]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
mountpoint_get(): Added support for AIX support with mntctl().
authorTimo Sirainen <tss@iki.fi>
Sun, 20 Jul 2008 15:57:50 +0000 (18:57 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 20 Jul 2008 15:57:50 +0000 (18:57 +0300)
--HG--
branch : HEAD

configure.in
src/lib/mountpoint.c

index 53cacc5c4e369eb6af6fca1a9866af54c0efad89..3eef27e82713fac25fcf60c87baf768db808228a 100644 (file)
@@ -19,7 +19,8 @@ AC_CHECK_HEADERS(strings.h stdint.h unistd.h dirent.h malloc.h inttypes.h \
   sys/uio.h sys/sysmacros.h sys/resource.h sys/select.h libgen.h \
   sys/quota.h sys/fs/ufs_quota.h ufs/ufs/quota.h jfs/quota.h sys/fs/quota_common.h \
   mntent.h sys/mnttab.h sys/event.h sys/time.h sys/mkdev.h linux/dqblk_xfs.h \
-  xfs/xqm.h sasl.h sasl/sasl.h execinfo.h ucontext.h malloc_np.h sys/utsname.h)
+  xfs/xqm.h sasl.h sasl/sasl.h execinfo.h ucontext.h malloc_np.h sys/utsname.h \
+  sys/vmount.h)
 
 AC_ARG_ENABLE(ipv6,
 [  --enable-ipv6           Enable IPv6 support (auto)],
@@ -1534,6 +1535,36 @@ AC_CHECK_FUNC(dlopen, [
   ])
 ])
 
+dnl **
+dnl ** AIX mntctl
+dnl **
+
+if test $ac_cv_header_sys_vmount_h = yes; then
+  AC_MSG_CHECKING([for reasonable mntctl buffer size])
+  AC_RUN_IFELSE([AC_LANG_SOURCE([[
+    #include <stdio.h>
+    #include <stdlib.h>
+    #include <sys/vmount.h>
+    int main() {
+      int size,count; char *m;
+      FILE *f=fopen("conftestval", "w");
+      if (!f) exit(1);
+      if ((count=mntctl(MCTL_QUERY,sizeof(size),&size))!=0 || !(m=malloc(size)) ||
+          (count=mntctl(MCTL_QUERY,size,m))<=0) exit(1);
+        fprintf(f, "%d\n",(size * (count + 5))/count & ~1); /* 5 mounts more */
+        exit(0);
+    }
+  ]])],[
+    size=`cat conftestval`
+    rm -f conftestval
+    AC_DEFINE_UNQUOTED(STATIC_MTAB_SIZE,$size, reasonable mntctl buffer size)
+    AC_MSG_RESULT($size)
+  ],[
+    AC_MSG_RESULT(default)
+  ])
+fi
+
+
 dnl **
 dnl ** SSL
 dnl **
index 08a573b92e8ca51b075f42d9a8aef530f73fce18..793c3f8832f6aad6c740a27a4dbe2b1eba8cdd98 100644 (file)
@@ -5,7 +5,10 @@
 
 #include <sys/stat.h>
 
-#ifdef HAVE_STATVFS_MNTFROMNAME
+#ifdef HAVE_SYS_VMOUNT_H
+#  include <stdio.h>
+#  include <sys/vmount.h> /* AIX */
+#elif defined(HAVE_STATVFS_MNTFROMNAME)
 #  include <sys/statvfs.h> /* NetBSD 3.0+, FreeBSD 5.0+ */
 #  define STATVFS_STR "statvfs"
 #elif defined(HAVE_STATFS_MNTFROMNAME)
 #ifndef MNTTYPE_IGNORE
 #  define MNTTYPE_IGNORE "ignore"
 #endif
+#ifndef MNTTYPE_JFS
+#  define MNTTYPE_JFS "jfs"
+#endif
+#ifndef MNTTYPE_NFS
+#  define MNTTYPE_NFS "nfs"
+#endif
 
 
 int mountpoint_get(const char *path, pool_t pool, struct mountpoint *point_r)
@@ -93,7 +102,62 @@ int mountpoint_get(const char *path, pool_t pool, struct mountpoint *point_r)
        }
        block_size = st.st_blksize;
 
-#ifdef HAVE_SYS_MNTTAB_H
+#ifdef HAVE_SYS_VMOUNT_H
+{
+       char static_mtab[STATIC_MTAB_SIZE], *mtab = static_mtab;
+       int i, count;
+       const struct vmount *vmt;
+
+       count = mntctl(MCTL_QUERY, sizeof(static_mtab), mtab);
+       while (count == 0) {
+               unsigned int size = *(unsigned int *)mtab;
+
+               mtab  = t_malloc(size);
+               count = mntctl(MCTL_QUERY, size, mtab);
+       }
+       if (count < 0) {
+               i_error("mntctl(MCTL_QUERY) failed: %m");
+               return -1;
+       }
+       vmt = (struct vmount *)mtab;
+       for (i = 0; i < count && device_path == NULL; i++) {
+               struct stat vst;
+               const char *vmt_base = (const char *)vmt;
+               const char *vmt_base, *vmt_object, *vmt_stub, *vmt_hostname;
+
+               vmt_hostname = vmt_base + vmt->vmt_data[VMT_HOSTNAME].vmt_off;
+               vmt_object   = vmt_base + vmt->vmt_data[VMT_OBJECT].vmt_off;
+               vmt_stub     = vmt_base + vmt->vmt_data[VMT_STUB].vmt_off;
+
+               switch (vmt->vmt_gfstype) {
+               case MNT_NFS:
+               case MNT_NFS3:
+               case MNT_NFS4:
+               case MNT_RFS4:
+                       if (stat(vmt_stub, &vst) == 0 &&
+                           st.st_dev == vst.st_dev) {
+                               device_path = t_strconcat(vmt_hostname, ":",
+                                                         vmt_object, NULL);
+                               mount_path  = vmt_stub;
+                               type        = MNTTYPE_NFS;
+                       }
+                       break;
+
+               case MNT_J2:
+               case MNT_JFS:
+                       if (stat(vmt_stub, &vst) == 0 &&
+                           st.st_dev == vst.st_dev) {
+                               device_path = vmt_object;
+                               mount_path  = vmt_stub;
+                               type        = MNTTYPE_JFS;
+                       }
+                       break;
+               }
+               vmt = CONST_PTR_OFFSET(vmt, vmt->vmt_length);
+       }
+}
+#elif defined(HAVE_SYS_MNTTAB_H)
+
        /* Solaris */
        f = fopen(MTAB_PATH, "r");
        if (f == NULL) {