From 8acd55bc32577c9e46c87d3f706fe3ed2fa7e157 Mon Sep 17 00:00:00 2001 From: niki Date: Thu, 1 Dec 2005 09:46:20 +0000 Subject: [PATCH] Many changes, but getting to somewhere. Plugin segfaults at the moment but i check it in anyway. --- configure.in | 1 + src/Makefile.am | 1 + src/config.h.in | 3 + src/quota_fs.c | 258 ++++++++++++++++++++++++++++----------------- src/quota_fs.h | 16 ++- src/quota_mnt.c | 30 +----- src/quota_plugin.c | 59 +++++++---- src/quota_plugin.h | 14 --- 8 files changed, 221 insertions(+), 161 deletions(-) diff --git a/configure.in b/configure.in index bfbb7213..2613926e 100644 --- a/configure.in +++ b/configure.in @@ -36,6 +36,7 @@ AC_CHECK_HEADERS(netinet/in.h) AC_CHECK_HEADERS(netdb.h) AC_CHECK_HEADERS(syslog.h) AC_CHECK_HEADERS(dlfcn.h) +AC_CHECK_HEADERS(grp.h) AC_CHECK_HEADERS(paths.h) AC_CHECK_HEADERS(mntent.h) AC_CHECK_HEADERS(sys/fs_types.h) diff --git a/src/Makefile.am b/src/Makefile.am index b0dee1cd..d2fd0b3d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,6 +37,7 @@ endif if BUILD_MODULE_QUOTA pkglib_LTLIBRARIES += quota.la quota_la_SOURCES = quota_plugin.c quota_plugin.h +quota_la_SOURCES += quota_common.c quota_common.h quota_la_SOURCES += quota_debug.c quota_debug.h quota_la_SOURCES += quota_mnt.c quota_mnt.h quota_mntopt.h quota_la_SOURCES += quota_fs.c quota_fs.h diff --git a/src/config.h.in b/src/config.h.in index 501cc882..5ec5c6fd 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -72,6 +72,9 @@ /* Define to 1 if you have the `getvfsent' function. */ #undef HAVE_GETVFSENT +/* Define to 1 if you have the header file. */ +#undef HAVE_GRP_H + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H diff --git a/src/quota_fs.c b/src/quota_fs.c index bf22b90d..d8ab22d4 100644 --- a/src/quota_fs.c +++ b/src/quota_fs.c @@ -23,18 +23,24 @@ #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 +#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 *** *** *** */ @@ -49,115 +55,138 @@ qft(const char *type) 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 *** *** *** */ @@ -178,7 +207,7 @@ quota_fs_issupported(const char *fsname) #endif return EXIT_FAILURE; } -} +} /* int quota_fs_issupported(const char *fsname) */ int quota_fs_isnfs(const char *fsname) @@ -188,13 +217,14 @@ 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; @@ -205,6 +235,7 @@ quota_fs_freequota(quota_t *quota) } free(q->type); free(q->name); + free(q->id); free(q->dir); free(q); prev = NULL; @@ -220,28 +251,57 @@ quota_t * 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) */ diff --git a/src/quota_fs.h b/src/quota_fs.h index 2bb05e97..9a8f9369 100644 --- a/src/quota_fs.h +++ b/src/quota_fs.h @@ -25,7 +25,6 @@ #define COLLECTD_QUOTA_FS_H 1 #include "common.h" -#include "quota_plugin.h" #include "quota_mnt.h" /* Quota Filesystem Type */ @@ -37,6 +36,21 @@ #define QFT_VXFS (5) #define QFT_ZFS (6) +typedef struct _quota_t quota_t; +struct _quota_t { + char *type; + char *name; + char *id; + char *dir; + unsigned long long blocks; + long long bquota, blimit; + unsigned long long bgrace, btimeleft; + unsigned long long inodes; + long long iquota, ilimit; + unsigned long long igrace, itimeleft; + quota_t *next; +}; + int quota_fs_issupported(const char *fsname); int quota_fs_isnfs(const char *fsname); diff --git a/src/quota_mnt.c b/src/quota_mnt.c index c2ab3035..435a69af 100644 --- a/src/quota_mnt.c +++ b/src/quota_mnt.c @@ -23,6 +23,7 @@ #include "common.h" #include "quota_debug.h" +#include "quota_common.h" #include "quota_fs.h" #include "quota_mnt.h" @@ -120,35 +121,6 @@ struct reiserfs_super_block { char s_volume_name[16]; }; -void -sstrncpy(char *d, const char *s, int len) -{ - strncpy(d, s, len); - d[len - 1] = 0; -} - -char * -sstrdup(const char *s) -{ - char *r = strdup(s); - if(r == NULL) { - DBG("Not enough memory."); - exit(3); - } - return r; -} - -void * -smalloc(size_t size) -{ - void *ret = malloc(size); - if(ret == NULL) { - DBG("Not enough memory."); - exit(3); - } - return ret; -} - /* for now, only ext2 and xfs are supported */ static int get_label_uuid(const char *device, char **label, char *uuid) diff --git a/src/quota_plugin.c b/src/quota_plugin.c index c00dabb6..900dd293 100644 --- a/src/quota_plugin.c +++ b/src/quota_plugin.c @@ -25,6 +25,7 @@ #include "plugin.h" #include "quota_debug.h" +#include "quota_common.h" #include "quota_mnt.h" #include "quota_fs.h" #include "quota_plugin.h" @@ -33,20 +34,20 @@ /* *** *** *** 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; @@ -59,6 +60,7 @@ quota_submit(quota_t *q) { char buf[BUFSIZE]; int r; + char *name, *n; r = snprintf(buf, BUFSIZE, "%u:%llu:%lld:%lld:%llu:%llu:%llu:%lld:%lld:%llu:%llu", @@ -69,7 +71,33 @@ quota_submit(quota_t *q) 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 @@ -86,16 +114,6 @@ quota_read(void) { 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:"); @@ -121,6 +139,7 @@ quota_read(void) 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, @@ -128,6 +147,7 @@ quota_read(void) 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-- "); @@ -135,8 +155,6 @@ quota_read(void) } DBG("\t== "); - quota_submit(&q_def); - quota_fs_freequota(quota); quota_mnt_freelist(list); } @@ -153,6 +171,11 @@ quota_write(char *host, char *inst, char *val) 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); } diff --git a/src/quota_plugin.h b/src/quota_plugin.h index 063cd09f..6dea2aab 100644 --- a/src/quota_plugin.h +++ b/src/quota_plugin.h @@ -26,20 +26,6 @@ #include "common.h" -typedef struct _quota_t quota_t; -struct _quota_t { - char *type; - char *name; - char *dir; - unsigned long long blocks; - long long bquota, blimit; - unsigned long long bgrace, btimeleft; - unsigned long long inodes; - long long iquota, ilimit; - unsigned long long igrace, itimeleft; - quota_t *next; -}; - void module_register(void); #endif /* !COLLECTD_QUOTA_PLUGIN_H */ -- 2.30.2