build: fix disk-free quota support on Solaris 10
authorUri Simchoni <uri@samba.org>
Wed, 3 Feb 2016 04:41:42 +0000 (06:41 +0200)
committerJeremy Allison <jra@samba.org>
Sun, 13 Mar 2016 00:37:58 +0000 (01:37 +0100)
Samba has no code to support quota on Solaris 10 (and possibly other
os's such as AIX) using the new quota interface. The new interface
serves both disk size/free space reporting (clamping the underlying
file system numbers with quota), and direct manipulation of the user's
quota.

However, there's legacy code that supports only disk size/free space on
Solaris 10. In the waf build, this code is not compiled because there is
no test for it.

This patch adds a test to see whether the legacy code can be used.

Issue reported and fix tested by Andrew Morgan <morgan@orst.edu>.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11788

Signed-off-by: Uri Simchoni <uri@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Sun Mar 13 01:37:58 CET 2016 on sn-devel-144

source3/wscript
source3/wscript_build
tests/oldquotas.c [new file with mode: 0644]

index c6504c6..c23f621 100644 (file)
@@ -1455,6 +1455,30 @@ main() {
             conf.DEFINE('HAVE_SYS_QUOTAS', '1')
             conf.DEFINE('WITH_QUOTAS', '1')
 
+        #
+        # check if Legacy quota code can be brought in
+        # if standard interfaces are not supported
+        #
+        legacy_quota_libs = ''
+        if not conf.CONFIG_SET('WITH_QUOTAS'):
+            if host_os.rfind('sunos5') > -1:
+                conf.DEFINE('SUNOS5', '1')
+                legacy_quota_libs = 'nsl'
+            conf.CHECK_CODE('''
+            #define WITH_QUOTAS 1
+            #define AUTOCONF_TEST 1
+            #include "../tests/oldquotas.c"
+            ''',
+                            cflags=conf.env['WERROR_CFLAGS'],
+                            define='WITH_QUOTAS',
+                            lib=legacy_quota_libs,
+                            msg='Checking whether legacy quota code can be used',
+                            execute=False,
+                            addmain=False)
+            if not conf.CONFIG_SET('WITH_QUOTAS'):
+                legacy_quota_libs = ''
+        conf.env['legacy_quota_libs'] = legacy_quota_libs
+
     #
     # cluster support (CTDB)
     #
index 9dc93bf..dce0238 100755 (executable)
@@ -634,6 +634,7 @@ bld.SAMBA3_LIBRARY('smbd_base',
                    notifyd
                    ''' +
                    bld.env['dmapi_lib'] +
+                   bld.env['legacy_quota_libs'] +
                    NOTIFY_DEPS,
                    private_library=True)
 
diff --git a/tests/oldquotas.c b/tests/oldquotas.c
new file mode 100644 (file)
index 0000000..bdb2beb
--- /dev/null
@@ -0,0 +1,174 @@
+/* this test should find out whether legacy quota code in disk_quotas.c
+ * compiles. It is a stripped-down version of disk_quotas.c, with samba
+ * stuff removed and only system calls, header files, and constants left.
+ */
+
+#ifndef HAVE_SYS_QUOTAS
+
+/* just a quick hack because sysquotas.h is included before linux/quota.h */
+#ifdef QUOTABLOCK_SIZE
+#undef QUOTABLOCK_SIZE
+#endif
+
+#ifdef WITH_QUOTAS
+
+#if defined(VXFS_QUOTA)
+
+bool disk_quotas_vxfs(const char *name, char *path, uint64_t *bsize,
+                     uint64_t *dfree, uint64_t *dsize);
+
+#endif /* VXFS_QUOTA */
+
+#if defined(SUNOS5) || defined(SUNOS4)
+
+#include <fcntl.h>
+#include <sys/param.h>
+#if defined(SUNOS5)
+#include <sys/fs/ufs_quota.h>
+#include <sys/mnttab.h>
+#include <sys/mntent.h>
+#else /* defined(SUNOS4) */
+#include <ufs/quota.h>
+#include <mntent.h>
+#endif
+
+#if defined(SUNOS5)
+
+/****************************************************************************
+ Allows querying of remote hosts for quotas on NFS mounted shares.
+ Supports normal NFS and AMD mounts.
+ Alan Romeril <a.romeril@ic.ac.uk> July 2K.
+****************************************************************************/
+
+#include <rpc/rpc.h>
+#include <rpc/types.h>
+#include <rpcsvc/rquota.h>
+#include <rpc/nettype.h>
+#include <rpc/xdr.h>
+
+static bool nfs_quotas(char *nfspath, uid_t euser_id, uint64_t *bsize,
+                      uint64_t *dfree, uint64_t *dsize)
+{
+       CLIENT *clnt;
+       clnt = clnt_create("host", RQUOTAPROG, RQUOTAVERS, "udp");
+       return true;
+}
+#endif
+
+/****************************************************************************
+try to get the disk space from disk quotas (SunOS & Solaris2 version)
+Quota code by Peter Urbanec (amiga@cse.unsw.edu.au).
+****************************************************************************/
+
+bool disk_quotas(const char *path, uint64_t *bsize, uint64_t *dfree,
+                uint64_t *dsize)
+{
+       int ret;
+#if defined(SUNOS5)
+       struct quotctl command;
+#else /* SunOS4 */
+       struct mntent *mnt;
+#endif
+#if defined(SUNOS5)
+       nfs_quotas("", 0, bsize, dfree, dsize);
+
+       command.op = Q_GETQUOTA;
+       command.uid = 0;
+       command.addr = NULL;
+       ret = ioctl(1, Q_QUOTACTL, &command);
+#else
+       ret = quotactl(Q_GETQUOTA, "", 0, NULL);
+#endif
+
+#if defined(SUNOS5) && defined(VXFS_QUOTA)
+       disk_quotas_vxfs("", path, bsize, dfree, dsize);
+#endif
+       return true;
+}
+
+#else
+
+#if AIX
+/* AIX quota patch from Ole Holm Nielsen <ohnielse@fysik.dtu.dk> */
+#include <jfs/quota.h>
+/* AIX 4.X: Rename members of the dqblk structure (ohnielse@fysik.dtu.dk) */
+#define dqb_curfiles dqb_curinodes
+#define dqb_fhardlimit dqb_ihardlimit
+#define dqb_fsoftlimit dqb_isoftlimit
+#ifdef _AIXVERSION_530
+#include <sys/statfs.h>
+#include <sys/vmount.h>
+#endif /* AIX 5.3 */
+#else  /* !AIX */
+#include <sys/quota.h>
+#include <devnm.h>
+#endif
+
+/****************************************************************************
+try to get the disk space from disk quotas - default version
+****************************************************************************/
+
+bool disk_quotas(const char *path, uint64_t *bsize, uint64_t *dfree,
+                uint64_t *dsize)
+{
+       struct dqblk D;
+#if defined(AIX)
+#ifdef _AIXVERSION_530
+       quota64_t user_quota;
+       quotactl(path, QCMD(Q_J2GETQUOTA, USRQUOTA), 0, (char *)&user_quota);
+#endif /* AIX 5.3 */
+       quotactl(path, QCMD(Q_GETQUOTA, USRQUOTA), 0, (char *)&D);
+#else  /* !AIX */
+       quotactl(Q_GETQUOTA, "", 0, &D);
+#endif /* !AIX */
+       return (true);
+}
+
+#endif
+
+#if defined(VXFS_QUOTA)
+
+#if defined(SUNOS5)
+
+#include <sys/fs/vx_solaris.h>
+#include <sys/fs/vx_machdep.h>
+#include <sys/fs/vx_layout.h>
+#include <sys/fs/vx_quota.h>
+#include <sys/fs/vx_aioctl.h>
+#include <sys/fs/vx_ioctl.h>
+
+bool disk_quotas_vxfs(const char *name, char *path, uint64_t *bsize,
+                     uint64_t *dfree, uint64_t *dsize)
+{
+       struct vx_dqblk D;
+       struct vx_quotctl quotabuf;
+       struct vx_genioctl genbuf;
+
+       genbuf.ioc_cmd = VX_QUOTACTL;
+       genbuf.ioc_up = (void *)&quotabuf;
+
+       quotabuf.cmd = VX_GETQUOTA;
+       quotabuf.uid = 0;
+       quotabuf.addr = (caddr_t)&D;
+       ret = ioctl(1, VX_ADMIN_IOCTL, &genbuf);
+
+       return true;
+}
+
+#endif /* SUNOS5 || ... */
+
+#endif /* VXFS_QUOTA */
+
+#else /* WITH_QUOTAS */
+
+#error "This test should be called with WITH_QUOTAS defined"
+
+#endif /* WITH_QUOTAS */
+
+#else /* HAVE_SYS_QUOTAS */
+
+#error "This test should not be called for systems with new quota interface"
+
+#endif /* HAVE_SYS_QUOTAS */
+
+int main() { return disk_quotas(NULL, NULL, NULL, NULL); }