fstests: Replace all __[u]intNN_t types with standard [u]intNN_t
[xfstests-dev.git] / src / feature.c
index 9e9ade6b133a096ccefabcde62209f1f8d483c14..0fb834a0273e63045f30659e2248215cf2ea5282 100644 (file)
@@ -1,33 +1,19 @@
 /*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * 
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 /*
  *   -t  test for working rlimit/ftruncate64 (via libc)
  *   -q  test for quota support (kernel compile option)
  *   -u  test for user quota enforcement support (mount option)
+ *   -p  test for project quota enforcement support (mount option)
  *   -g  test for group quota enforcement support (mount option)
  *   -U  test for user quota accounting support (mount option)
  *   -G  test for group quota accounting support (mount option)
+ *   -P  test for project quota accounting support (mount option)
  * Return code: 0 is true, anything else is error/not supported
+ *
+ * Test for machine features
+ *   -A  test whether AIO syscalls are available
+ *   -o  report a number of online cpus
+ *   -s  report pagesize
+ *   -w  report bits per long
  */
 
-#include <libxfs.h>
+#include "global.h"
+
 #include <sys/quota.h>
 #include <sys/resource.h>
 #include <signal.h>
-#include <xqm.h>
+#include <unistd.h>
+
+#ifdef HAVE_XFS_XQM_H
+#include <xfs/xqm.h>
+#endif
+
+#ifdef HAVE_LIBAIO_H
+#include <libaio.h>
+#endif
+
+#ifndef USRQUOTA
+#define USRQUOTA  0
+#endif
+
+#ifndef GRPQUOTA
+#define GRPQUOTA  1
+#endif
+
+#ifndef PRJQUOTA
+#define PRJQUOTA  2
+#endif
 
 int verbose = 0;
 
 void
 usage(void)
 {
-       fprintf(stderr, "Usage: feature [-v] -<q|u|g|U|G> <filesystem>\n");
+       fprintf(stderr, "Usage: feature [-v] -<q|u|g|p|U|G|P> <filesystem>\n");
        fprintf(stderr, "       feature [-v] -c <file>\n");
        fprintf(stderr, "       feature [-v] -t <file>\n");
+       fprintf(stderr, "       feature -A | -o | -s | -w\n");
        exit(1);
 }
 
@@ -71,11 +87,11 @@ int check_big_ID(char *filename)
        }
 
        /* 98789 is greater than 2^16 (65536) */
-       if ((__u32)sbuf.st_uid == 98789 || (__u32)sbuf.st_gid == 98789)
+       if ((uint32_t)sbuf.st_uid == 98789 || (uint32_t)sbuf.st_gid == 98789)
                return(0);
        if (verbose)
                fprintf(stderr, "lstat64 on %s gave uid=%d, gid=%d\n",
-                       filename, sbuf.st_uid, sbuf.st_gid);
+                       filename, (int)sbuf.st_uid, (int)sbuf.st_gid);
        return(1);
 }
 
@@ -100,7 +116,7 @@ int
 hastruncate64(char *filename)
 {
        struct rlimit64 rlimit64;
-       off64_t bigoff = 4294967307;    /* > 2^32 */
+       off64_t bigoff = 4294967307LL;  /* > 2^32 */
        struct stat64 bigst;
        int fd;
 
@@ -127,7 +143,7 @@ hastruncate64(char *filename)
 
        if (verbose)
                fprintf(stderr, "fstat64 on %s gave sz=%lld (truncsz=%lld)\n",
-                       filename, bigst.st_size, bigoff);
+                       filename, (long long)bigst.st_size, (long long)bigoff);
 
        if (bigst.st_size != bigoff)
                return(1);
@@ -140,11 +156,32 @@ hasxfsquota(int type, int q, char *device)
        fs_quota_stat_t qstat;
        int             qcmd;
 
-       if (q == 0)
-               return (access("/proc/fs/xfs/xqm", F_OK) < 0);
-
        memset(&qstat, 0, sizeof(fs_quota_stat_t));
+
+#ifdef QCMD
+       if (q == 0) {
+               if (access("/proc/fs/xfs/xqm", F_OK) < 0) {
+                       if (verbose) {
+                               fprintf(stderr, "can't access /proc/fs/xfs/xqm\n");
+                       }
+                       return 1;
+               }
+               return 0;
+       }
        qcmd = QCMD(Q_XGETQSTAT, type);
+#else
+       if (q == 0) {
+               if (quotactl(Q_SYNC, device, 0, (caddr_t)&qstat) == ENOPKG) {
+                       if (verbose) {
+                               fprintf(stderr, "Q_SYNC not supported\n");
+                       }
+                       return 1;
+               }
+               return 0;
+       }
+       qcmd = Q_GETQSTAT;
+#endif
+
        if (quotactl(qcmd, device, 0, (caddr_t)&qstat) < 0) {
                if (verbose)
                        perror("quotactl");
@@ -154,30 +191,67 @@ hasxfsquota(int type, int q, char *device)
                return (0);
        else if (q == XFS_QUOTA_GDQ_ENFD && qstat.qs_flags & XFS_QUOTA_GDQ_ENFD)
                return (0);
+       else if (q == XFS_QUOTA_PDQ_ENFD && qstat.qs_flags & XFS_QUOTA_PDQ_ENFD)
+               return (0);
        else if (q == XFS_QUOTA_UDQ_ACCT && qstat.qs_flags & XFS_QUOTA_UDQ_ACCT)
                return (0);
        else if (q == XFS_QUOTA_GDQ_ACCT && qstat.qs_flags & XFS_QUOTA_GDQ_ACCT)
                return (0);
+       else if (q == XFS_QUOTA_PDQ_ACCT && qstat.qs_flags & XFS_QUOTA_PDQ_ACCT)
+               return (0);
        if (verbose)
                fprintf(stderr, "quota type (%d) not available\n", q);
        return (1);
 }
 
+static int
+check_aio_support(void)
+{
+#ifdef HAVE_LIBAIO_H
+       struct io_context *ctx = NULL;
+       int err;
+
+       err = io_setup(1, &ctx);
+       if (err == 0)
+               return 0;
+
+       if (err == -ENOSYS) /* CONFIG_AIO=n */
+               return 1;
+
+       fprintf(stderr, "unexpected error from io_setup(): %s\n",
+               strerror(-err));
+       return 2;
+#else
+       /* libaio was unavailable at build time; assume AIO is unsupported */
+       return 1;
+#endif
+}
+
+
 int
 main(int argc, char **argv)
 {
        int     c;
+       int     Aflag = 0;
        int     cflag = 0;
        int     tflag = 0;
        int     gflag = 0;
        int     Gflag = 0;
+       int     pflag = 0;
+       int     Pflag = 0;
        int     qflag = 0;
+       int     sflag = 0;
        int     uflag = 0;
        int     Uflag = 0;
-       char    *fs;
+       int     wflag = 0;
+       int     oflag = 0;
+       char    *fs = NULL;
 
-       while ((c = getopt(argc, argv, "ctgGquUv")) != EOF) {
+       while ((c = getopt(argc, argv, "ActgGopPqsuUvw")) != EOF) {
                switch (c) {
+               case 'A':
+                       Aflag++;
+                       break;
                case 'c':
                        cflag++;
                        break;
@@ -190,15 +264,30 @@ main(int argc, char **argv)
                case 'G':
                        Gflag++;
                        break;
+               case 'o':
+                       oflag++;
+                       break;
+               case 'p':
+                       pflag++;
+                       break;
+               case 'P':
+                       Pflag++;
+                       break;
                case 'q':
                        qflag++;
                        break;
+               case 's':
+                       sflag++;
+                       break;
                case 'u':
                        uflag++;
                        break;
                case 'U':
                        Uflag++;
                        break;
+               case 'w':
+                       wflag++;
+                       break;
                case 'v':
                        verbose++;
                        break;
@@ -207,11 +296,16 @@ main(int argc, char **argv)
                }
        }
 
-       if (!cflag && !tflag && !uflag && !gflag && !qflag && !Uflag && !Gflag)
-               usage();
-       if (optind != argc-1)
+       /* filesystem features */
+       if (cflag|tflag|uflag|gflag|pflag|qflag|Uflag|Gflag|Pflag) {
+               if (optind != argc-1)   /* need a device */
+                       usage();
+               fs = argv[argc-1];
+       } else if (Aflag || wflag || sflag || oflag) {
+               if (optind != argc)
+                       usage();
+       } else 
                usage();
-       fs = argv[argc-1];
 
        if (cflag)
                return(haschown32(fs));
@@ -221,13 +315,55 @@ main(int argc, char **argv)
                return(hasxfsquota(0, 0, fs));
        if (gflag)
                return(hasxfsquota(GRPQUOTA, XFS_QUOTA_GDQ_ENFD, fs));
+       if (pflag)
+               return(hasxfsquota(PRJQUOTA, XFS_QUOTA_PDQ_ENFD, fs));
        if (uflag)
                return(hasxfsquota(USRQUOTA, XFS_QUOTA_UDQ_ENFD, fs));
        if (Gflag)
                return(hasxfsquota(GRPQUOTA, XFS_QUOTA_GDQ_ACCT, fs));
+       if (Pflag)
+               return(hasxfsquota(PRJQUOTA, XFS_QUOTA_PDQ_ACCT, fs));
        if (Uflag)
                return(hasxfsquota(USRQUOTA, XFS_QUOTA_UDQ_ACCT, fs));
 
-       fprintf(stderr, "feature: dunno what you're doing?\n");
+       if (Aflag)
+               return(check_aio_support());
+
+       if (sflag) {
+               printf("%d\n", getpagesize());
+               exit(0);
+       }
+       if (wflag) {
+#ifdef BITS_PER_LONG
+               printf("%d\n", BITS_PER_LONG);
+#else
+#ifdef NBBY
+               /* This can change under IRIX depending on whether we compile
+                * with -n32/-32 or -64
+                */
+               printf("%d\n", (int)(NBBY * sizeof(long)));
+#else
+bozo!
+#endif
+#endif
+               exit(0);
+       }
+       if (oflag) {
+               long ncpus = -1;
+
+#if defined(_SC_NPROCESSORS_ONLN)
+               ncpus = sysconf(_SC_NPROCESSORS_ONLN);
+#elif defined(_SC_NPROC_ONLN)
+               ncpus = sysconf(_SC_NPROC_ONLN);
+#endif
+               if (ncpus == -1)
+                       ncpus = 1;
+
+               printf("%ld\n", ncpus);
+
+               exit(0);
+       }
+
+       fprintf(stderr, "feature: dunno what you're after.\n");
        return(1);
 }