Bug 97208

Summary: quotactl() doesn't work
Product: [Fedora] Fedora Reporter: Michael Redinger <michael.redinger>
Component: glibc-kernheadersAssignee: David Woodhouse <dwmw2>
Status: CLOSED NOTABUG QA Contact: Brian Brock <bbrock>
Severity: high Docs Contact:
Priority: medium    
Version: rawhideCC: mitr
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-07-14 11:41:20 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Michael Redinger 2003-06-11 16:04:44 UTC
I'm seeing a strange quota problem here that I don't understand.
This is on a RHL 9 system, all updates (incl. kernel) applied.
As of Jun 11 2003:
$ rpm -q glibc kernel-smp quota
glibc-2.3.2-27.9
kernel-smp-2.4.20-18.9
quota-3.06-9

The quota programs work fine - no problem with quotacheck, quotaon, repquota
etc.

However, some of our code stopped working when upgrading from 7.2 to 9.
I had a look the source (and the man page, and the include files) and I really
don't see the problem. Therefore it must be a bug ... ;)

The actual problem is that quotactl does not work as expected.
The sample prints "getquota: Invalid argument" and exits with errno 22.

Below is some sample C code that reproduces the problem (just change the
uid and the mountpoint):


############################### begin ###############################

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <linux/quota.h>

#define connect(qid, qval, init_qid, init_qval) qid=init_qid, qval=init_qval
#define NO_QIDS 4

int main()
{
  int    uid=12345;                  /* uid of user */
  char   *sp="/dev/sda6";            /* device special file */
  struct mem_dqblk qv;               /* quota-values */
  char   *qids[NO_QIDS];             /* valid qids */
  u_int32_t *qvals[NO_QIDS];         /* for convenience */


  /*
  ** get current quota
  */
  if (quotactl(QCMD(Q_GETQUOTA,USRQUOTA), sp, uid, (caddr_t) &qv) != 0) {
    if (errno == ESRCH) { /* no quotas defined for uid */
      *qvals[0] = *qvals[1] = *qvals[2] = *qvals[3] = 0;
    }
    else {
      printf("%i\n", errno);
      perror("quotactl: getquota");
    }
  }
}

###############################  end  ###############################

Comment 1 Michael Redinger 2003-06-11 16:24:17 UTC
Well, right after filing this bug a co-worker actually found the problem.
The problem is that glibc-kernheaders-2.4-8.10 is very different from the kernel
includes (only checked the quota.h)!

The first three 3 examples I saw (there are probably many others):

/usr/include/linux/quota.h:
#define Q_GETQUOTA 0x0D00       /* get limits and usage */
#define Q_SETQUOTA 0x0E00       /* set limits and usage */
#define Q_SETQLIM  0x0700       /* set limits */

/usr/src/linux-2.4.20-18.9/include/linux/quota.h:
#define Q_GETQUOTA 0x800007     /* get user quota structure */
#define Q_SETQUOTA 0x800008     /* set user quota structure */
/* Q_SETQLIM is missing */


Comment 2 Alan Cox 2003-06-22 18:13:29 UTC
Glibc seems to have the old headers for ancient 16bit uid quota still. What I
don't understand given that is how our quota tools built 8)



Comment 3 Miloslav Trmač 2005-04-22 14:40:22 UTC
The glibc headers are completely incompatible with the kernel interface
and AFAICS glibc is not doing any conversion,
so the only way to use quotactl () is currently to ship a private
copy of original linux/quota.h.

The current (glibc-kernheaders-2.4-9.1.94) linux/quota.h that includes
sys/quota.h really doesn't help.

Comment 4 David Woodhouse 2005-07-14 11:41:20 UTC
You shouldn't be looking at linux/quota.h -- that's a private kernel header.

You should be using sys/quota.h, which I believe is fixed in current glibc packages.