Linux Quota Inconsistency Problems

In our system, we use linux quota to limit users file usage. However, quota database has inconsistencies with file usage of users. Sometimes user has no data, however quota database shows 4KB of usage.

On this problem, quotacheck is recommended. However, quotacheck fully checks the disk. If there are too many files and users, also user files frequently changing; online mode of quotacheck can’t fix inconsistencies.

quota1

We have a daily quota check script. It finds quota inconsistencies. The missing part: entry based online quota update software.

I straced to learn how quotacheck do this.

[root@node1 kota]# strace quotacheck -m /{filesystem} 2>&1 | tail -10
close(4) = 0
getdents(3, /* 0 entries */, 32768) = 0
close(3) = 0
stat("/dev/mapper/cluster_vg-cluster_lv", {st_mode=S_IFBLK|0660, st_rdev=makedev(253, 4), ...}) = 0
quotactl(Q_XGETQSTAT|USRQUOTA, "/dev/mapper/cluster_vg-cluster_lv", 0, {version=1, ...}) = 0
quotactl(Q_XSETQLIM|USRQUOTA, "/dev/mapper/cluster_vg-cluster_lv", 0, {version=0, flags=XFS_USER_QUOTA, fieldmask=0x1000, id=0, blk_hardlimit=0, blk_softlimit=0, ino_hardlimit=0, ino_softlimit=0, bcount=280, icount=18, ...}) = 0
quotactl(Q_XSETQLIM|USRQUOTA, "/dev/mapper/cluster_vg-cluster_lv", 107, {version=0, flags=XFS_USER_QUOTA, fieldmask=0x1000, id=107, blk_hardlimit=0, blk_softlimit=0, ino_hardlimit=0, ino_softlimit=0, bcount=1475448, icount=2, ...}) = 0
quotactl(Q_XSETQLIM|USRQUOTA, "/dev/mapper/cluster_vg-cluster_lv", 1000, {version=0, flags=XFS_USER_QUOTA, fieldmask=0x1000, id=1000, blk_hardlimit=0, blk_softlimit=0, ino_hardlimit=0, ino_softlimit=0, bcount=51096, icount=3, ...}) = 0
exit_group(0) = ?
+++ exited with 0 +++

I saw all the parameters with strace -f -v -e abbrev=none -s 1048576 quotacheck -m /{filesystem} 2>&1.

Then I wrote a C program uses quotactl system call with same parameters.

Our intention was making zero the quota value if user don’t have a file on the file system.

 

 

 
[code language=”c”]
#include
#include
#include
#include

int main(int argc, char *argv[] )
{
if(argc != 3){
printf(“Usage: ./clearQuotaUsage [DEVICE] [UID]”);
return 1;
}

// getUid value
int uid = atoi(argv[2]);

// define quota options
fs_disk_quota opts;
opts.d_version = 0;
opts.d_flags = XFS_USER_QUOTA;

// this mask is for updating the quota value
opts.d_fieldmask = 0x1000;

// which UID value will be changed.
opts.d_id = uid;

//nonsense
opts.d_blk_hardlimit = 0;
opts.d_blk_softlimit = 0;
opts.d_ino_hardlimit = 0;
opts.d_ino_softlimit = 0;

// new block count value
opts.d_bcount = 0;

opts.d_icount = 0;
opts.d_btimer = 0;
opts.d_itimer = 0;
opts.d_bwarns = 0;
opts.d_iwarns = 0;
opts.d_rtbcount = 0;
opts.d_rtbtimer = 0;
opts.d_rtbwarns = 0;

// update block quota usage
// 1.parameter: operation
// 2.parameter: device to be updated
// 3.parameter: uid to be updated
// 4.parameter: kota parameters
int out = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), argv[1], uid, (caddr_t)&opts);
printf(“return out: %d\n”, out);

return 0;
}
[/code]

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.