glusterfs-3.4.2/ 0000755 0000762 0000763 00000000000 12261516145 010547 5 0000000 0000000 glusterfs-3.4.2/Makefile.am 0000644 0000762 0000763 00000001663 12261516067 012534 0000000 0000000 EXTRA_DIST = autogen.sh \
COPYING-GPLV2 COPYING-LGPLV3 \
INSTALL README AUTHORS THANKS NEWS \
glusterfs.spec glusterfs-api.pc.in
SUBDIRS = argp-standalone libglusterfs rpc api xlators glusterfsd \
$(FUSERMOUNT_SUBDIR) doc extras cli
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = glusterfs-api.pc
CLEANFILES =
gitclean: distclean
find . -name Makefile.in -exec rm -f {} \;
find . -name Makefile -exec rm -f {} \;
find . -name mount.glusterfs -exec rm -f {} \;
rm -fr autom4te.cache
rm -f missing aclocal.m4 config.h.in config.guess config.sub ltmain.sh install-sh configure depcomp
rm -fr argp-standalone/autom4te.cache
rm -f argp-standalone/aclocal.m4 argp-standalone/config.h.in argp-standalone/configure argp-standalone/depcomp argp-standalone/install-sh argp-standalone/missing
dist-hook:
(cd $(srcdir) && git diff && echo ===== git log ==== && git log) > $(distdir)/ChangeLog
tar czf gluster-swift-ufo-$(VERSION).tar.gz ufo
glusterfs-3.4.2/COPYING-LGPLV3 0000644 0000762 0000763 00000016743 12261516067 012505 0000000 0000000 GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
glusterfs-3.4.2/README 0000644 0000762 0000763 00000000065 12261516067 011353 0000000 0000000 For more info, please visit http://www.gluster.org/.
glusterfs-3.4.2/NEWS 0000644 0000762 0000763 00000000031 12261516067 011163 0000000 0000000 Gluster moves to Gerrit.
glusterfs-3.4.2/configure.ac 0000644 0000762 0000763 00000055576 12261516070 012774 0000000 0000000 dnl Copyright (c) 2006-2012 Red Hat, Inc.
dnl This file is part of GlusterFS.
dnl
dnl This file is licensed to you under your choice of the GNU Lesser
dnl General Public License, version 3 or any later version (LGPLv3 or
dnl later), or the GNU General Public License, version 2 (GPLv2), in all
dnl cases as published by the Free Software Foundation.
AC_INIT([glusterfs],[3.4.2],[gluster-users@gluster.org])
AM_INIT_AUTOMAKE
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(yes)])
if make --help 2>&1 | grep -q no-print-directory; then
AM_MAKEFLAGS="$AM_MAKEFLAGS --no-print-directory";
fi
if make --help 2>&1 | grep -q quiet; then
AM_MAKEFLAGS="$AM_MAKEFLAGS --quiet"
fi
if libtool --help 2>&1 | grep -q quiet; then
AM_LIBTOOLFLAGS="--quiet";
fi
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile
libglusterfs/Makefile
libglusterfs/src/Makefile
glusterfsd/Makefile
glusterfsd/src/Makefile
rpc/Makefile
rpc/rpc-lib/Makefile
rpc/rpc-lib/src/Makefile
rpc/rpc-transport/Makefile
rpc/rpc-transport/socket/Makefile
rpc/rpc-transport/socket/src/Makefile
rpc/rpc-transport/rdma/Makefile
rpc/rpc-transport/rdma/src/Makefile
rpc/xdr/Makefile
rpc/xdr/src/Makefile
xlators/Makefile
xlators/mount/Makefile
xlators/mount/fuse/Makefile
xlators/mount/fuse/src/Makefile
xlators/mount/fuse/utils/mount.glusterfs
xlators/mount/fuse/utils/mount_glusterfs
xlators/mount/fuse/utils/Makefile
xlators/storage/Makefile
xlators/storage/posix/Makefile
xlators/storage/posix/src/Makefile
xlators/storage/bd_map/Makefile
xlators/storage/bd_map/src/Makefile
xlators/cluster/Makefile
xlators/cluster/afr/Makefile
xlators/cluster/afr/src/Makefile
xlators/cluster/stripe/Makefile
xlators/cluster/stripe/src/Makefile
xlators/cluster/dht/Makefile
xlators/cluster/dht/src/Makefile
xlators/performance/Makefile
xlators/performance/write-behind/Makefile
xlators/performance/write-behind/src/Makefile
xlators/performance/read-ahead/Makefile
xlators/performance/read-ahead/src/Makefile
xlators/performance/io-threads/Makefile
xlators/performance/io-threads/src/Makefile
xlators/performance/io-cache/Makefile
xlators/performance/io-cache/src/Makefile
xlators/performance/symlink-cache/Makefile
xlators/performance/symlink-cache/src/Makefile
xlators/performance/quick-read/Makefile
xlators/performance/quick-read/src/Makefile
xlators/performance/open-behind/Makefile
xlators/performance/open-behind/src/Makefile
xlators/performance/md-cache/Makefile
xlators/performance/md-cache/src/Makefile
xlators/debug/Makefile
xlators/debug/trace/Makefile
xlators/debug/trace/src/Makefile
xlators/debug/error-gen/Makefile
xlators/debug/error-gen/src/Makefile
xlators/debug/io-stats/Makefile
xlators/debug/io-stats/src/Makefile
xlators/protocol/Makefile
xlators/protocol/auth/Makefile
xlators/protocol/auth/addr/Makefile
xlators/protocol/auth/addr/src/Makefile
xlators/protocol/auth/login/Makefile
xlators/protocol/auth/login/src/Makefile
xlators/protocol/client/Makefile
xlators/protocol/client/src/Makefile
xlators/protocol/server/Makefile
xlators/protocol/server/src/Makefile
xlators/features/Makefile
xlators/features/locks/Makefile
xlators/features/locks/src/Makefile
xlators/features/quota/Makefile
xlators/features/quota/src/Makefile
xlators/features/marker/Makefile
xlators/features/marker/src/Makefile
xlators/features/marker/utils/Makefile
xlators/features/marker/utils/src/Makefile
xlators/features/marker/utils/syncdaemon/Makefile
xlators/features/read-only/Makefile
xlators/features/read-only/src/Makefile
xlators/features/mac-compat/Makefile
xlators/features/mac-compat/src/Makefile
xlators/features/quiesce/Makefile
xlators/features/quiesce/src/Makefile
xlators/features/index/Makefile
xlators/features/index/src/Makefile
xlators/encryption/Makefile
xlators/encryption/rot-13/Makefile
xlators/encryption/rot-13/src/Makefile
xlators/system/Makefile
xlators/system/posix-acl/Makefile
xlators/system/posix-acl/src/Makefile
cli/Makefile
cli/src/Makefile
doc/Makefile
extras/Makefile
extras/init.d/Makefile
extras/init.d/glusterd.plist
extras/init.d/glusterd-Debian
extras/init.d/glusterd-Redhat
extras/init.d/glusterd-SuSE
extras/systemd/Makefile
extras/systemd/glusterd.service
extras/benchmarking/Makefile
extras/hook-scripts/Makefile
extras/ocf/Makefile
extras/ocf/glusterd
extras/ocf/volume
extras/LinuxRPM/Makefile
contrib/fuse-util/Makefile
contrib/uuid/uuid_types.h
xlators/nfs/Makefile
xlators/nfs/server/Makefile
xlators/nfs/server/src/Makefile
xlators/mgmt/Makefile
xlators/mgmt/glusterd/Makefile
xlators/mgmt/glusterd/src/Makefile
glusterfs-api.pc
api/Makefile
api/src/Makefile
api/examples/Makefile
api/examples/setup.py
glusterfs.spec])
AC_CANONICAL_HOST
AC_PROG_CC
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
AC_ARG_WITH(pkgconfigdir,
[ --with-pkgconfigdir=DIR pkgconfig file in DIR @<:@LIBDIR/pkgconfig@:>@],
[pkgconfigdir=$withval],
[pkgconfigdir='${libdir}/pkgconfig'])
AC_SUBST(pkgconfigdir)
AC_ARG_WITH(mountutildir,
[ --with-mountutildir=DIR mount helper utility in DIR @<:@/sbin@:>@],
[mountutildir=$withval],
[mountutildir='/sbin'])
AC_SUBST(mountutildir)
AC_ARG_WITH(systemddir,
[ --with-systemddir=DIR systemd service files in DIR @<:@/usr/lib/systemd/system@:>@],
[systemddir=$withval],
[systemddir='/usr/lib/systemd/system'])
AC_SUBST(systemddir)
AC_ARG_WITH(initdir,
[ --with-initdir=DIR init.d scripts in DIR @<:@/etc/init.d@:>@],
[initdir=$withval],
[initdir='/etc/init.d'])
AC_SUBST(initdir)
AC_ARG_WITH(launchddir,
[ --with-launchddir=DIR launchd services in DIR @<:@/Library/LaunchDaemons@:>@],
[launchddir=$withval],
[launchddir='/Library/LaunchDaemons'])
AC_SUBST(launchddir)
AC_ARG_WITH([ocf],
[AS_HELP_STRING([--without-ocf], [build OCF-compliant cluster resource agents])],
,
[OCF_SUBDIR='ocf'],
)
AC_SUBST(OCF_SUBDIR)
# LEX needs a check
AC_PROG_LEX
if test "x${LEX}" != "xflex" -a "x${FLEX}" != "xlex"; then
AC_MSG_ERROR([Flex or lex required to build glusterfs.])
fi
dnl
dnl Word sizes...
dnl
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
SIZEOF_SHORT=$ac_cv_sizeof_short
SIZEOF_INT=$ac_cv_sizeof_int
SIZEOF_LONG=$ac_cv_sizeof_long
SIZEOF_LONG_LONG=$ac_cv_sizeof_long_long
AC_SUBST(SIZEOF_SHORT)
AC_SUBST(SIZEOF_INT)
AC_SUBST(SIZEOF_LONG)
AC_SUBST(SIZEOF_LONG_LONG)
# YACC needs a check
AC_PROG_YACC
if test "x${YACC}" = "xbyacc" -o "x${YACC}" = "xyacc" -o "x${YACC}" = "x"; then
AC_MSG_ERROR([GNU Bison required to build glusterfs.])
fi
AC_CHECK_TOOL([LD],[ld])
AC_CHECK_LIB([crypto], [MD5], , AC_MSG_ERROR([OpenSSL crypto library is required to build glusterfs]))
AC_CHECK_LIB([pthread], [pthread_mutex_init], , AC_MSG_ERROR([Posix threads library is required to build glusterfs]))
AC_CHECK_FUNC([dlopen], [has_dlopen=yes], AC_CHECK_LIB([dl], [dlopen], , AC_MSG_ERROR([Dynamic linking library required to build glusterfs])))
AC_CHECK_HEADERS([sys/xattr.h])
AC_CHECK_HEADERS([sys/extattr.h])
AC_CHECK_HEADERS([openssl/md5.h])
case $host_os in
darwin*)
if ! test "`/usr/bin/sw_vers | grep ProductVersion: | cut -f 2 | cut -d. -f2`" -ge 5; then
AC_MSG_ERROR([You need at least OS X 10.5 (Leopard) to build Glusterfs])
fi
;;
esac
dnl Mac OS X does not have spinlocks
AC_CHECK_FUNC([pthread_spin_init], [have_spinlock=yes])
if test "x${have_spinlock}" = "xyes"; then
AC_DEFINE(HAVE_SPINLOCK, 1, [define if found spinlock])
fi
AC_SUBST(HAVE_SPINLOCK)
dnl some os may not have GNU defined strnlen function
AC_CHECK_FUNC([strnlen], [have_strnlen=yes])
if test "x${have_strnlen}" = "xyes"; then
AC_DEFINE(HAVE_STRNLEN, 1, [define if found strnlen])
fi
AC_SUBST(HAVE_STRNLEN)
AC_CHECK_FUNC([setfsuid], [have_setfsuid=yes])
AC_CHECK_FUNC([setfsgid], [have_setfsgid=yes])
if test "x${have_setfsuid}" = "xyes" -a "x${have_setfsgid}" = "xyes"; then
AC_DEFINE(HAVE_SET_FSID, 1, [define if found setfsuid setfsgid])
fi
# FUSE section
AC_ARG_ENABLE([fuse-client],
AC_HELP_STRING([--disable-fuse-client],
[Do not build the fuse client. NOTE: you cannot mount glusterfs without the client]))
BUILD_FUSE_CLIENT=no
if test "x$enable_fuse_client" != "xno"; then
FUSE_CLIENT_SUBDIR=fuse
BUILD_FUSE_CLIENT="yes"
fi
AC_ARG_ENABLE([bd-xlator],
AC_HELP_STRING([--enable-bd-xlator],
[Build BD xlator]))
if test "x$enable_bd_xlator" != "xno"; then
AC_CHECK_LIB([lvm2app],
[lvm_init,lvm_lv_from_name],
[HAVE_BD_LIB="yes"],
[HAVE_BD_LIB="no"])
if test "x$HAVE_BD_LIB" = "xyes"; then
# lvm_lv_from_name() has been made public with lvm2-2.02.79
AC_CHECK_DECLS(
[lvm_lv_from_name],
[NEED_LVM_LV_FROM_NAME_DECL="no"],
[NEED_LVM_LV_FROM_NAME_DECL="yes"],
[[#include ]])
fi
fi
if test "x$enable_bd_xlator" = "xyes" -a "x$HAVE_BD_LIB" = "xno"; then
echo "BD xlator requested but required lvm2 development library not found."
exit 1
fi
BUILD_BD_XLATOR=no
if test "x${enable_bd_xlator}" != "xno" -a "x${HAVE_BD_LIB}" = "xyes"; then
BUILD_BD_XLATOR=yes
AC_DEFINE(HAVE_BD_XLATOR, 1, [define if lvm2app library found and bd
xlator enabled])
if test "x$NEED_LVM_LV_FROM_NAME_DECL" = "xyes"; then
AC_DEFINE(NEED_LVM_LV_FROM_NAME_DECL, 1, [defined if lvm_lv_from_name()
was not found in the lvm2app.h header, but can be linked])
fi
fi
AM_CONDITIONAL([ENABLE_BD_XLATOR], [test x$BUILD_BD_XLATOR = xyes])
AC_SUBST(FUSE_CLIENT_SUBDIR)
# end FUSE section
# FUSERMOUNT section
AC_ARG_ENABLE([fusermount],
AC_HELP_STRING([--disable-fusermount],
[Use system's fusermount]))
BUILD_FUSERMOUNT="yes"
if test "x$enable_fusermount" = "xno"; then
BUILD_FUSERMOUNT="no"
else
AC_DEFINE(GF_FUSERMOUNT, 1, [Use our own fusermount])
FUSERMOUNT_SUBDIR="contrib/fuse-util"
fi
AC_SUBST(FUSERMOUNT_SUBDIR)
#end FUSERMOUNT section
# EPOLL section
AC_ARG_ENABLE([epoll],
AC_HELP_STRING([--disable-epoll],
[Use poll instead of epoll.]))
BUILD_EPOLL=no
if test "x$enable_epoll" != "xno"; then
AC_CHECK_HEADERS([sys/epoll.h],
[BUILD_EPOLL=yes],
[BUILD_EPOLL=no])
fi
# end EPOLL section
# IBVERBS section
AC_ARG_ENABLE([ibverbs],
AC_HELP_STRING([--disable-ibverbs],
[Do not build the ibverbs transport]))
if test "x$enable_ibverbs" != "xno"; then
AC_CHECK_LIB([ibverbs],
[ibv_get_device_list],
[HAVE_LIBIBVERBS="yes"],
[HAVE_LIBIBVERBS="no"])
AC_CHECK_LIB([rdmacm], [rdma_create_id], [HAVE_RDMACM="yes"], [HAVE_RDMACM="no"])
fi
if test "x$enable_ibverbs" = "xyes"; then
if test "x$HAVE_LIBIBVERBS" = "xno"; then
echo "ibverbs-transport requested, but libibverbs is not present."
exit 1
fi
if test "x$HAVE_RDMACM" = "xno"; then
echo "ibverbs-transport requested, but librdmacm is not present."
exit 1
fi
fi
BUILD_RDMA=no
BUILD_IBVERBS=no
if test "x$enable_ibverbs" != "xno" -a "x$HAVE_LIBIBVERBS" = "xyes" -a "x$HAVE_RDMACM" = "xyes"; then
IBVERBS_SUBDIR=ib-verbs
BUILD_IBVERBS=yes
RDMA_SUBDIR=rdma
BUILD_RDMA=yes
fi
AC_SUBST(IBVERBS_SUBDIR)
AC_SUBST(RDMA_SUBDIR)
# end IBVERBS section
# SYNCDAEMON section
AC_ARG_ENABLE([georeplication],
AC_HELP_STRING([--disable-georeplication],
[Do not install georeplication components]))
BUILD_SYNCDAEMON=no
case $host_os in
linux*)
#do nothing
;;
netbsd*)
#do nothing
;;
*)
#disabling geo replication for non-linux platforms
enable_georeplication=no
;;
esac
SYNCDAEMON_COMPILE=0
if test "x$enable_georeplication" != "xno"; then
SYNCDAEMON_SUBDIR=utils
SYNCDAEMON_COMPILE=1
BUILD_SYNCDAEMON="yes"
AM_PATH_PYTHON([2.4])
echo -n "checking if python is python 2.x... "
if echo $PYTHON_VERSION | grep ^2; then
:
else
echo no
AC_MSG_ERROR([only python 2.x is supported])
fi
echo -n "checking if python has ctypes support... "
if "$PYTHON" -c 'import ctypes' 2>/dev/null; then
echo yes
else
echo no
AC_MSG_ERROR([python does not have ctypes support])
fi
fi
AC_SUBST(SYNCDAEMON_COMPILE)
AC_SUBST(SYNCDAEMON_SUBDIR)
# end SYNCDAEMON section
# check for systemtap/dtrace
BUILD_SYSTEMTAP=no
AC_MSG_CHECKING([whether to include systemtap tracing support])
AC_ARG_ENABLE([systemtap],
[AS_HELP_STRING([--enable-systemtap],
[Enable inclusion of systemtap trace support])],
[ENABLE_SYSTEMTAP="${enableval}"], [ENABLE_SYSTEMTAP="def"])
AM_CONDITIONAL([ENABLE_SYSTEMTAP], [test "x${ENABLE_SYSTEMTAP}" = "xyes"])
AC_MSG_RESULT(${ENABLE_SYSTEMTAP})
if test "x${ENABLE_SYSTEMTAP}" != "xno"; then
AC_CHECK_PROG(DTRACE, dtrace, "yes", "no")
AC_CHECK_HEADER([sys/sdt.h], [SDT_H_FOUND="yes"],
[SDT_H_FOUND="no"])
fi
if test "x${ENABLE_SYSTEMTAP}" = "xyes"; then
if test "x${DTRACE}" = "xno"; then
AC_MSG_ERROR([dtrace not found])
elif test "$x{SDT_H_FOUND}" = "xno"; then
AC_MSG_ERROR([systemtap support needs sys/sdt.h header])
fi
fi
if test "x${DTRACE}" = "xyes" -a "x${SDT_H_FOUND}" = "xyes"; then
AC_MSG_CHECKING([x"${DTRACE}"xy"${SDT_H_FOUND}"y])
AC_DEFINE([HAVE_SYSTEMTAP], [1], [Define to 1 if using probes.])
BUILD_SYSTEMTAP=yes
fi
# end of systemtap/dtrace
#check if libxml is present if so enable HAVE_LIB_XML
echo -n "checking if libxml2 is present... "
PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.6.19],
[echo "yes (features requiring libxml2 enabled)" AC_DEFINE(HAVE_LIB_XML, 1, [define if libxml2 is present])],
[echo "no"] )
AC_SUBST(LIBXML2_CFLAGS)
AC_SUBST(LIBXML2_LIBS)
dnl FreeBSD > 5 has execinfo as a Ported library for giving a workaround
dnl solution to GCC backtrace functionality
AC_CHECK_HEADERS([execinfo.h], [have_backtrace=yes],
AC_CHECK_LIB([execinfo], [backtrace], [have_backtrace=yes]))
dnl AC_MSG_ERROR([libexecinfo not found libexecinfo required.])))
if test "x${have_backtrace}" = "xyes"; then
AC_DEFINE(HAVE_BACKTRACE, 1, [define if found backtrace])
fi
AC_SUBST(HAVE_BACKTRACE)
dnl glusterfs prints memory usage to stderr by sending it SIGUSR1
AC_CHECK_FUNC([malloc_stats], [have_malloc_stats=yes])
if test "x${have_malloc_stats}" = "xyes"; then
AC_DEFINE(HAVE_MALLOC_STATS, 1, [define if found malloc_stats])
fi
AC_SUBST(HAVE_MALLOC_STATS)
dnl Linux, Solaris, Cygwin
AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec])
dnl FreeBSD, NetBSD
AC_CHECK_MEMBERS([struct stat.st_atimespec.tv_nsec])
case $host_os in
*netbsd*)
CFLAGS=-D_INCOMPLETE_XOPEN_C063
;;
esac
AC_CHECK_FUNC([linkat], [have_linkat=yes])
if test "x${have_linkat}" = "xyes"; then
AC_DEFINE(HAVE_LINKAT, 1, [define if found linkat])
fi
AC_SUBST(HAVE_LINKAT)
dnl Check for argp
AC_CHECK_HEADER([argp.h], AC_DEFINE(HAVE_ARGP, 1, [have argp]))
AC_CONFIG_SUBDIRS(argp-standalone)
BUILD_ARGP_STANDALONE=no
if test "x${ac_cv_header_argp_h}" = "xno"; then
BUILD_ARGP_STANDALONE=yes
ARGP_STANDALONE_CPPFLAGS='-I${top_srcdir}/argp-standalone'
ARGP_STANDALONE_LDADD='${top_builddir}/argp-standalone/libargp.a'
fi
AC_SUBST(ARGP_STANDALONE_CPPFLAGS)
AC_SUBST(ARGP_STANDALONE_LDADD)
AC_CHECK_HEADER([malloc.h], AC_DEFINE(HAVE_MALLOC_H, 1, [have malloc.h]))
AC_CHECK_FUNC([llistxattr], [have_llistxattr=yes])
if test "x${have_llistxattr}" = "xyes"; then
AC_DEFINE(HAVE_LLISTXATTR, 1, [define if llistxattr exists])
fi
AC_CHECK_FUNC([fdatasync], [have_fdatasync=yes])
if test "x${have_fdatasync}" = "xyes"; then
AC_DEFINE(HAVE_FDATASYNC, 1, [define if fdatasync exists])
fi
# Check the distribution where you are compiling glusterfs on
GF_DISTRIBUTION=
AC_CHECK_FILE([/etc/debian_version])
AC_CHECK_FILE([/etc/SuSE-release])
AC_CHECK_FILE([/etc/redhat-release])
if test "x$ac_cv_file__etc_debian_version" = "xyes"; then
GF_DISTRIBUTION=Debian
fi
if test "x$ac_cv_file__etc_SuSE_release" = "xyes"; then
GF_DISTRIBUTION=SuSE
fi
if test "x$ac_cv_file__etc_redhat_release" = "xyes"; then
GF_DISTRIBUTION=Redhat
fi
AC_SUBST(GF_DISTRIBUTION)
GF_HOST_OS=""
GF_LDFLAGS="-rdynamic"
# check for gcc -Werror=format-security
saved_CFLAGS=$CFLAGS
CFLAGS="-Wformat -Werror=format-security"
AC_MSG_CHECKING([whether $CC accepts -Werror=format-security])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [cc_werror_format_security=yes], [cc_werror_format_security=no])
echo $cc_werror_format_security
if test "x$cc_werror_format_security" = "xno"; then
CFLAGS="$saved_CFLAGS"
else
CFLAGS="$saved_CFLAGS $CFLAGS"
fi
case $host_os in
linux*)
dnl GF_LINUX_HOST_OS=1
GF_HOST_OS="GF_LINUX_HOST_OS"
GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -O0"
GF_GLUSTERFS_CFLAGS="${GF_CFLAGS}"
GF_LDADD="${ARGP_STANDALONE_LDADD}"
GF_FUSE_CFLAGS="-DFUSERMOUNT_DIR=\\\"\$(bindir)\\\""
;;
solaris*)
GF_HOST_OS="GF_SOLARIS_HOST_OS"
GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -O0 -m64"
GF_LDFLAGS=""
GF_GLUSTERFS_CFLAGS="${GF_CFLAGS}"
GF_LDADD="${ARGP_STANDALONE_LDADD}"
GF_GLUSTERFS_LIBS="-lnsl -lresolv -lsocket"
BUILD_FUSE_CLIENT=no
FUSE_CLIENT_SUBDIR=""
;;
*netbsd*)
GF_HOST_OS="GF_BSD_HOST_OS"
GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -D_INCOMPLETE_XOPEN_C063"
GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_BASENAME"
GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_DIRNAME"
GF_GLUSTERFS_CFLAGS="${GF_CFLAGS}"
GF_LDADD="${ARGP_STANDALONE_LDADD}"
if test "x$ac_cv_header_execinfo_h" = "xyes"; then
GF_GLUSTERFS_LIBS="-lexecinfo"
fi
GF_FUSE_LDADD="-lperfuse"
BUILD_FUSE_CLIENT=yes
LEXLIB=""
;;
*bsd*)
GF_HOST_OS="GF_BSD_HOST_OS"
GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -O0"
GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_BASENAME"
GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_DIRNAME"
GF_GLUSTERFS_CFLAGS="${GF_CFLAGS}"
GF_LDADD="${ARGP_STANDALONE_LDADD}"
if test "x$ac_cv_header_execinfo_h" = "xyes"; then
GF_GLUSTERFS_LIBS="-lexecinfo"
fi
BUILD_FUSE_CLIENT=no
;;
darwin*)
GF_HOST_OS="GF_DARWIN_HOST_OS"
LIBTOOL=glibtool
GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -D__DARWIN_64_BIT_INO_T -bundle -undefined suppress -flat_namespace -D_XOPEN_SOURCE -O0"
GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_BASENAME"
GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_DIRNAME"
GF_GLUSTERFS_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -D__DARWIN_64_BIT_INO_T -undefined suppress -flat_namespace -O0"
GF_LDADD="${ARGP_STANDALONE_LDADD}"
GF_FUSE_CFLAGS="-I\$(CONTRIBDIR)/macfuse"
;;
esac
# enable debug section
AC_ARG_ENABLE([debug],
AC_HELP_STRING([--enable-debug],
[Enable debug build options.]))
BUILD_DEBUG=no
if test "x$enable_debug" = "xyes"; then
BUILD_DEBUG=yes
CFLAGS=`echo $CFLAGS | sed -e s/O2/O0/`
else
BUILD_DEBUG=no
fi
AC_SUBST(CFLAGS)
# end enable debug section
BUILD_READLINE=no
AC_CHECK_LIB([readline -lcurses],[readline],[RLLIBS="-lreadline -lcurses"])
AC_CHECK_LIB([readline -ltermcap],[readline],[RLLIBS="-lreadline -ltermcap"])
AC_CHECK_LIB([readline -lncurses],[readline],[RLLIBS="-lreadline -lncurses"])
if test "x$RLLIBS" != "x"; then
AC_DEFINE(HAVE_READLINE, 1, [readline enabled CLI])
BUILD_READLINE=yes
fi
BUILD_LIBAIO=no
AC_CHECK_LIB([aio],[io_setup],[LIBAIO="-laio"])
if test "x$LIBAIO" != "x"; then
AC_DEFINE(HAVE_LIBAIO, 1, [libaio based POSIX enabled])
BUILD_LIBAIO=yes
fi
AC_SUBST(GF_HOST_OS)
AC_SUBST([GF_GLUSTERFS_LIBS])
AC_SUBST(GF_GLUSTERFS_CFLAGS)
AC_SUBST(GF_CFLAGS)
AC_SUBST(GF_LDFLAGS)
AC_SUBST(GF_LDADD)
AC_SUBST(GF_FUSE_LDADD)
AC_SUBST(GF_FUSE_CFLAGS)
AC_SUBST(RLLIBS)
AC_SUBST(LIBAIO)
AC_SUBST(AM_MAKEFLAGS)
AC_SUBST(AM_LIBTOOLFLAGS)
CONTRIBDIR='$(top_srcdir)/contrib'
AC_SUBST(CONTRIBDIR)
GF_CPPDEFINES='-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS)'
GF_CPPINCLUDES='-I$(top_srcdir)/libglusterfs/src -I$(CONTRIBDIR)/uuid'
GF_CPPFLAGS="$GF_CPPDEFINES $GF_CPPINCLUDES"
AC_SUBST([GF_CPPFLAGS])
AM_CONDITIONAL([GF_DARWIN_HOST_OS], test "${GF_HOST_OS}" = "GF_DARWIN_HOST_OS")
AM_CONDITIONAL([GF_INSTALL_VAR_LIB_GLUSTERD], test ! -d ${localstatedir}/lib/glusterd && test -d ${sysconfdir}/glusterd )
AC_OUTPUT
echo
echo "GlusterFS configure summary"
echo "==========================="
echo "FUSE client : $BUILD_FUSE_CLIENT"
echo "Infiniband verbs : $BUILD_IBVERBS"
echo "epoll IO multiplex : $BUILD_EPOLL"
echo "argp-standalone : $BUILD_ARGP_STANDALONE"
echo "fusermount : $BUILD_FUSERMOUNT"
echo "readline : $BUILD_READLINE"
echo "georeplication : $BUILD_SYNCDAEMON"
echo "Linux-AIO : $BUILD_LIBAIO"
echo "Enable Debug : $BUILD_DEBUG"
echo "systemtap : $BUILD_SYSTEMTAP"
echo "Block Device backend : $BUILD_BD_XLATOR"
echo
glusterfs-3.4.2/autogen.sh 0000755 0000762 0000763 00000000324 12261516067 012472 0000000 0000000 #!/bin/sh
aclocal -I ./contrib/aclocal
autoheader
(libtoolize --automake --copy --force || glibtoolize --automake --copy --force)
autoconf
automake --add-missing --copy --foreign
cd argp-standalone;./autogen.sh
glusterfs-3.4.2/contrib/ 0000755 0000762 0000763 00000000000 12261516155 012210 5 0000000 0000000 glusterfs-3.4.2/contrib/ipaddr-py/ 0000755 0000762 0000763 00000000000 12261516154 014100 5 0000000 0000000 glusterfs-3.4.2/contrib/ipaddr-py/ipaddr.py 0000644 0000762 0000763 00000167302 12261516067 015651 0000000 0000000 #!/usr/bin/python
#
# Copyright 2007 Google Inc.
# Licensed to PSF under a Contributor Agreement.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing
# permissions and limitations under the License.
"""A fast, lightweight IPv4/IPv6 manipulation library in Python.
This library is used to create/poke/manipulate IPv4 and IPv6 addresses
and networks.
"""
__version__ = 'trunk'
import struct
IPV4LENGTH = 32
IPV6LENGTH = 128
class AddressValueError(ValueError):
"""A Value Error related to the address."""
class NetmaskValueError(ValueError):
"""A Value Error related to the netmask."""
def IPAddress(address, version=None):
"""Take an IP string/int and return an object of the correct type.
Args:
address: A string or integer, the IP address. Either IPv4 or
IPv6 addresses may be supplied; integers less than 2**32 will
be considered to be IPv4 by default.
version: An Integer, 4 or 6. If set, don't try to automatically
determine what the IP address type is. important for things
like IPAddress(1), which could be IPv4, '0.0.0.1', or IPv6,
'::1'.
Returns:
An IPv4Address or IPv6Address object.
Raises:
ValueError: if the string passed isn't either a v4 or a v6
address.
"""
if version:
if version == 4:
return IPv4Address(address)
elif version == 6:
return IPv6Address(address)
try:
return IPv4Address(address)
except (AddressValueError, NetmaskValueError):
pass
try:
return IPv6Address(address)
except (AddressValueError, NetmaskValueError):
pass
raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
address)
def IPNetwork(address, version=None, strict=False):
"""Take an IP string/int and return an object of the correct type.
Args:
address: A string or integer, the IP address. Either IPv4 or
IPv6 addresses may be supplied; integers less than 2**32 will
be considered to be IPv4 by default.
version: An Integer, if set, don't try to automatically
determine what the IP address type is. important for things
like IPNetwork(1), which could be IPv4, '0.0.0.1/32', or IPv6,
'::1/128'.
Returns:
An IPv4Network or IPv6Network object.
Raises:
ValueError: if the string passed isn't either a v4 or a v6
address. Or if a strict network was requested and a strict
network wasn't given.
"""
if version:
if version == 4:
return IPv4Network(address, strict)
elif version == 6:
return IPv6Network(address, strict)
try:
return IPv4Network(address, strict)
except (AddressValueError, NetmaskValueError):
pass
try:
return IPv6Network(address, strict)
except (AddressValueError, NetmaskValueError):
pass
raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
address)
def v4_int_to_packed(address):
"""The binary representation of this address.
Args:
address: An integer representation of an IPv4 IP address.
Returns:
The binary representation of this address.
Raises:
ValueError: If the integer is too large to be an IPv4 IP
address.
"""
if address > _BaseV4._ALL_ONES:
raise ValueError('Address too large for IPv4')
return struct.pack('!I', address)
def v6_int_to_packed(address):
"""The binary representation of this address.
Args:
address: An integer representation of an IPv4 IP address.
Returns:
The binary representation of this address.
"""
return struct.pack('!QQ', address >> 64, address & (2**64 - 1))
def _find_address_range(addresses):
"""Find a sequence of addresses.
Args:
addresses: a list of IPv4 or IPv6 addresses.
Returns:
A tuple containing the first and last IP addresses in the sequence.
"""
first = last = addresses[0]
for ip in addresses[1:]:
if ip._ip == last._ip + 1:
last = ip
else:
break
return (first, last)
def _get_prefix_length(number1, number2, bits):
"""Get the number of leading bits that are same for two numbers.
Args:
number1: an integer.
number2: another integer.
bits: the maximum number of bits to compare.
Returns:
The number of leading bits that are the same for two numbers.
"""
for i in range(bits):
if number1 >> i == number2 >> i:
return bits - i
return 0
def _count_righthand_zero_bits(number, bits):
"""Count the number of zero bits on the right hand side.
Args:
number: an integer.
bits: maximum number of bits to count.
Returns:
The number of zero bits on the right hand side of the number.
"""
if number == 0:
return bits
for i in range(bits):
if (number >> i) % 2:
return i
def summarize_address_range(first, last):
"""Summarize a network range given the first and last IP addresses.
Example:
>>> summarize_address_range(IPv4Address('1.1.1.0'),
IPv4Address('1.1.1.130'))
[IPv4Network('1.1.1.0/25'), IPv4Network('1.1.1.128/31'),
IPv4Network('1.1.1.130/32')]
Args:
first: the first IPv4Address or IPv6Address in the range.
last: the last IPv4Address or IPv6Address in the range.
Returns:
The address range collapsed to a list of IPv4Network's or
IPv6Network's.
Raise:
TypeError:
If the first and last objects are not IP addresses.
If the first and last objects are not the same version.
ValueError:
If the last object is not greater than the first.
If the version is not 4 or 6.
"""
if not (isinstance(first, _BaseIP) and isinstance(last, _BaseIP)):
raise TypeError('first and last must be IP addresses, not networks')
if first.version != last.version:
raise TypeError("%s and %s are not of the same version" % (
str(first), str(last)))
if first > last:
raise ValueError('last IP address must be greater than first')
networks = []
if first.version == 4:
ip = IPv4Network
elif first.version == 6:
ip = IPv6Network
else:
raise ValueError('unknown IP version')
ip_bits = first._max_prefixlen
first_int = first._ip
last_int = last._ip
while first_int <= last_int:
nbits = _count_righthand_zero_bits(first_int, ip_bits)
current = None
while nbits >= 0:
addend = 2**nbits - 1
current = first_int + addend
nbits -= 1
if current <= last_int:
break
prefix = _get_prefix_length(first_int, current, ip_bits)
net = ip('%s/%d' % (str(first), prefix))
networks.append(net)
if current == ip._ALL_ONES:
break
first_int = current + 1
first = IPAddress(first_int, version=first._version)
return networks
def _collapse_address_list_recursive(addresses):
"""Loops through the addresses, collapsing concurrent netblocks.
Example:
ip1 = IPv4Network('1.1.0.0/24')
ip2 = IPv4Network('1.1.1.0/24')
ip3 = IPv4Network('1.1.2.0/24')
ip4 = IPv4Network('1.1.3.0/24')
ip5 = IPv4Network('1.1.4.0/24')
ip6 = IPv4Network('1.1.0.1/22')
_collapse_address_list_recursive([ip1, ip2, ip3, ip4, ip5, ip6]) ->
[IPv4Network('1.1.0.0/22'), IPv4Network('1.1.4.0/24')]
This shouldn't be called directly; it is called via
collapse_address_list([]).
Args:
addresses: A list of IPv4Network's or IPv6Network's
Returns:
A list of IPv4Network's or IPv6Network's depending on what we were
passed.
"""
ret_array = []
optimized = False
for cur_addr in addresses:
if not ret_array:
ret_array.append(cur_addr)
continue
if cur_addr in ret_array[-1]:
optimized = True
elif cur_addr == ret_array[-1].supernet().subnet()[1]:
ret_array.append(ret_array.pop().supernet())
optimized = True
else:
ret_array.append(cur_addr)
if optimized:
return _collapse_address_list_recursive(ret_array)
return ret_array
def collapse_address_list(addresses):
"""Collapse a list of IP objects.
Example:
collapse_address_list([IPv4('1.1.0.0/24'), IPv4('1.1.1.0/24')]) ->
[IPv4('1.1.0.0/23')]
Args:
addresses: A list of IPv4Network or IPv6Network objects.
Returns:
A list of IPv4Network or IPv6Network objects depending on what we
were passed.
Raises:
TypeError: If passed a list of mixed version objects.
"""
i = 0
addrs = []
ips = []
nets = []
# split IP addresses and networks
for ip in addresses:
if isinstance(ip, _BaseIP):
if ips and ips[-1]._version != ip._version:
raise TypeError("%s and %s are not of the same version" % (
str(ip), str(ips[-1])))
ips.append(ip)
elif ip._prefixlen == ip._max_prefixlen:
if ips and ips[-1]._version != ip._version:
raise TypeError("%s and %s are not of the same version" % (
str(ip), str(ips[-1])))
ips.append(ip.ip)
else:
if nets and nets[-1]._version != ip._version:
raise TypeError("%s and %s are not of the same version" % (
str(ip), str(ips[-1])))
nets.append(ip)
# sort and dedup
ips = sorted(set(ips))
nets = sorted(set(nets))
while i < len(ips):
(first, last) = _find_address_range(ips[i:])
i = ips.index(last) + 1
addrs.extend(summarize_address_range(first, last))
return _collapse_address_list_recursive(sorted(
addrs + nets, key=_BaseNet._get_networks_key))
# backwards compatibility
CollapseAddrList = collapse_address_list
# Test whether this Python implementation supports byte objects that
# are not identical to str ones.
# We need to exclude platforms where bytes == str so that we can
# distinguish between packed representations and strings, for example
# b'12::' (the IPv4 address 49.50.58.58) and '12::' (an IPv6 address).
try:
_compat_has_real_bytes = bytes is not str
except NameError: # other._ip
return False
# Shorthand for Integer addition and subtraction. This is not
# meant to ever support addition/subtraction of addresses.
def __add__(self, other):
if not isinstance(other, int):
return NotImplemented
return IPAddress(int(self) + other, version=self._version)
def __sub__(self, other):
if not isinstance(other, int):
return NotImplemented
return IPAddress(int(self) - other, version=self._version)
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, str(self))
def __str__(self):
return '%s' % self._string_from_ip_int(self._ip)
def __hash__(self):
return hash(hex(long(self._ip)))
def _get_address_key(self):
return (self._version, self)
@property
def version(self):
raise NotImplementedError('BaseIP has no version')
class _BaseNet(_IPAddrBase):
"""A generic IP object.
This IP class contains the version independent methods which are
used by networks.
"""
def __init__(self, address):
self._cache = {}
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, str(self))
def iterhosts(self):
"""Generate Iterator over usable hosts in a network.
This is like __iter__ except it doesn't return the network
or broadcast addresses.
"""
cur = int(self.network) + 1
bcast = int(self.broadcast) - 1
while cur <= bcast:
cur += 1
yield IPAddress(cur - 1, version=self._version)
def __iter__(self):
cur = int(self.network)
bcast = int(self.broadcast)
while cur <= bcast:
cur += 1
yield IPAddress(cur - 1, version=self._version)
def __getitem__(self, n):
network = int(self.network)
broadcast = int(self.broadcast)
if n >= 0:
if network + n > broadcast:
raise IndexError
return IPAddress(network + n, version=self._version)
else:
n += 1
if broadcast + n < network:
raise IndexError
return IPAddress(broadcast + n, version=self._version)
def __lt__(self, other):
if self._version != other._version:
raise TypeError('%s and %s are not of the same version' % (
str(self), str(other)))
if not isinstance(other, _BaseNet):
raise TypeError('%s and %s are not of the same type' % (
str(self), str(other)))
if self.network != other.network:
return self.network < other.network
if self.netmask != other.netmask:
return self.netmask < other.netmask
return False
def __gt__(self, other):
if self._version != other._version:
raise TypeError('%s and %s are not of the same version' % (
str(self), str(other)))
if not isinstance(other, _BaseNet):
raise TypeError('%s and %s are not of the same type' % (
str(self), str(other)))
if self.network != other.network:
return self.network > other.network
if self.netmask != other.netmask:
return self.netmask > other.netmask
return False
def __le__(self, other):
gt = self.__gt__(other)
if gt is NotImplemented:
return NotImplemented
return not gt
def __ge__(self, other):
lt = self.__lt__(other)
if lt is NotImplemented:
return NotImplemented
return not lt
def __eq__(self, other):
try:
return (self._version == other._version
and self.network == other.network
and int(self.netmask) == int(other.netmask))
except AttributeError:
if isinstance(other, _BaseIP):
return (self._version == other._version
and self._ip == other._ip)
def __ne__(self, other):
eq = self.__eq__(other)
if eq is NotImplemented:
return NotImplemented
return not eq
def __str__(self):
return '%s/%s' % (str(self.ip),
str(self._prefixlen))
def __hash__(self):
return hash(int(self.network) ^ int(self.netmask))
def __contains__(self, other):
# always false if one is v4 and the other is v6.
if self._version != other._version:
return False
# dealing with another network.
if isinstance(other, _BaseNet):
return (self.network <= other.network and
self.broadcast >= other.broadcast)
# dealing with another address
else:
return (int(self.network) <= int(other._ip) <=
int(self.broadcast))
def overlaps(self, other):
"""Tell if self is partly contained in other."""
return self.network in other or self.broadcast in other or (
other.network in self or other.broadcast in self)
@property
def network(self):
x = self._cache.get('network')
if x is None:
x = IPAddress(self._ip & int(self.netmask), version=self._version)
self._cache['network'] = x
return x
@property
def broadcast(self):
x = self._cache.get('broadcast')
if x is None:
x = IPAddress(self._ip | int(self.hostmask), version=self._version)
self._cache['broadcast'] = x
return x
@property
def hostmask(self):
x = self._cache.get('hostmask')
if x is None:
x = IPAddress(int(self.netmask) ^ self._ALL_ONES,
version=self._version)
self._cache['hostmask'] = x
return x
@property
def with_prefixlen(self):
return '%s/%d' % (str(self.ip), self._prefixlen)
@property
def with_netmask(self):
return '%s/%s' % (str(self.ip), str(self.netmask))
@property
def with_hostmask(self):
return '%s/%s' % (str(self.ip), str(self.hostmask))
@property
def numhosts(self):
"""Number of hosts in the current subnet."""
return int(self.broadcast) - int(self.network) + 1
@property
def version(self):
raise NotImplementedError('BaseNet has no version')
@property
def prefixlen(self):
return self._prefixlen
def address_exclude(self, other):
"""Remove an address from a larger block.
For example:
addr1 = IPNetwork('10.1.1.0/24')
addr2 = IPNetwork('10.1.1.0/26')
addr1.address_exclude(addr2) =
[IPNetwork('10.1.1.64/26'), IPNetwork('10.1.1.128/25')]
or IPv6:
addr1 = IPNetwork('::1/32')
addr2 = IPNetwork('::1/128')
addr1.address_exclude(addr2) = [IPNetwork('::0/128'),
IPNetwork('::2/127'),
IPNetwork('::4/126'),
IPNetwork('::8/125'),
...
IPNetwork('0:0:8000::/33')]
Args:
other: An IPvXNetwork object of the same type.
Returns:
A sorted list of IPvXNetwork objects addresses which is self
minus other.
Raises:
TypeError: If self and other are of difffering address
versions, or if other is not a network object.
ValueError: If other is not completely contained by self.
"""
if not self._version == other._version:
raise TypeError("%s and %s are not of the same version" % (
str(self), str(other)))
if not isinstance(other, _BaseNet):
raise TypeError("%s is not a network object" % str(other))
if other not in self:
raise ValueError('%s not contained in %s' % (str(other),
str(self)))
if other == self:
return []
ret_addrs = []
# Make sure we're comparing the network of other.
other = IPNetwork('%s/%s' % (str(other.network), str(other.prefixlen)),
version=other._version)
s1, s2 = self.subnet()
while s1 != other and s2 != other:
if other in s1:
ret_addrs.append(s2)
s1, s2 = s1.subnet()
elif other in s2:
ret_addrs.append(s1)
s1, s2 = s2.subnet()
else:
# If we got here, there's a bug somewhere.
assert True == False, ('Error performing exclusion: '
's1: %s s2: %s other: %s' %
(str(s1), str(s2), str(other)))
if s1 == other:
ret_addrs.append(s2)
elif s2 == other:
ret_addrs.append(s1)
else:
# If we got here, there's a bug somewhere.
assert True == False, ('Error performing exclusion: '
's1: %s s2: %s other: %s' %
(str(s1), str(s2), str(other)))
return sorted(ret_addrs, key=_BaseNet._get_networks_key)
def compare_networks(self, other):
"""Compare two IP objects.
This is only concerned about the comparison of the integer
representation of the network addresses. This means that the
host bits aren't considered at all in this method. If you want
to compare host bits, you can easily enough do a
'HostA._ip < HostB._ip'
Args:
other: An IP object.
Returns:
If the IP versions of self and other are the same, returns:
-1 if self < other:
eg: IPv4('1.1.1.0/24') < IPv4('1.1.2.0/24')
IPv6('1080::200C:417A') < IPv6('1080::200B:417B')
0 if self == other
eg: IPv4('1.1.1.1/24') == IPv4('1.1.1.2/24')
IPv6('1080::200C:417A/96') == IPv6('1080::200C:417B/96')
1 if self > other
eg: IPv4('1.1.1.0/24') > IPv4('1.1.0.0/24')
IPv6('1080::1:200C:417A/112') >
IPv6('1080::0:200C:417A/112')
If the IP versions of self and other are different, returns:
-1 if self._version < other._version
eg: IPv4('10.0.0.1/24') < IPv6('::1/128')
1 if self._version > other._version
eg: IPv6('::1/128') > IPv4('255.255.255.0/24')
"""
if self._version < other._version:
return -1
if self._version > other._version:
return 1
# self._version == other._version below here:
if self.network < other.network:
return -1
if self.network > other.network:
return 1
# self.network == other.network below here:
if self.netmask < other.netmask:
return -1
if self.netmask > other.netmask:
return 1
# self.network == other.network and self.netmask == other.netmask
return 0
def _get_networks_key(self):
"""Network-only key function.
Returns an object that identifies this address' network and
netmask. This function is a suitable "key" argument for sorted()
and list.sort().
"""
return (self._version, self.network, self.netmask)
def _ip_int_from_prefix(self, prefixlen=None):
"""Turn the prefix length netmask into a int for comparison.
Args:
prefixlen: An integer, the prefix length.
Returns:
An integer.
"""
if not prefixlen and prefixlen != 0:
prefixlen = self._prefixlen
return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen)
def _prefix_from_ip_int(self, ip_int, mask=32):
"""Return prefix length from the decimal netmask.
Args:
ip_int: An integer, the IP address.
mask: The netmask. Defaults to 32.
Returns:
An integer, the prefix length.
"""
while mask:
if ip_int & 1 == 1:
break
ip_int >>= 1
mask -= 1
return mask
def _ip_string_from_prefix(self, prefixlen=None):
"""Turn a prefix length into a dotted decimal string.
Args:
prefixlen: An integer, the netmask prefix length.
Returns:
A string, the dotted decimal netmask string.
"""
if not prefixlen:
prefixlen = self._prefixlen
return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen))
def iter_subnets(self, prefixlen_diff=1, new_prefix=None):
"""The subnets which join to make the current subnet.
In the case that self contains only one IP
(self._prefixlen == 32 for IPv4 or self._prefixlen == 128
for IPv6), return a list with just ourself.
Args:
prefixlen_diff: An integer, the amount the prefix length
should be increased by. This should not be set if
new_prefix is also set.
new_prefix: The desired new prefix length. This must be a
larger number (smaller prefix) than the existing prefix.
This should not be set if prefixlen_diff is also set.
Returns:
An iterator of IPv(4|6) objects.
Raises:
ValueError: The prefixlen_diff is too small or too large.
OR
prefixlen_diff and new_prefix are both set or new_prefix
is a smaller number than the current prefix (smaller
number means a larger network)
"""
if self._prefixlen == self._max_prefixlen:
yield self
return
if new_prefix is not None:
if new_prefix < self._prefixlen:
raise ValueError('new prefix must be longer')
if prefixlen_diff != 1:
raise ValueError('cannot set prefixlen_diff and new_prefix')
prefixlen_diff = new_prefix - self._prefixlen
if prefixlen_diff < 0:
raise ValueError('prefix length diff must be > 0')
new_prefixlen = self._prefixlen + prefixlen_diff
if not self._is_valid_netmask(str(new_prefixlen)):
raise ValueError(
'prefix length diff %d is invalid for netblock %s' % (
new_prefixlen, str(self)))
first = IPNetwork('%s/%s' % (str(self.network),
str(self._prefixlen + prefixlen_diff)),
version=self._version)
yield first
current = first
while True:
broadcast = current.broadcast
if broadcast == self.broadcast:
return
new_addr = IPAddress(int(broadcast) + 1, version=self._version)
current = IPNetwork('%s/%s' % (str(new_addr), str(new_prefixlen)),
version=self._version)
yield current
def masked(self):
"""Return the network object with the host bits masked out."""
return IPNetwork('%s/%d' % (self.network, self._prefixlen),
version=self._version)
def subnet(self, prefixlen_diff=1, new_prefix=None):
"""Return a list of subnets, rather than an iterator."""
return list(self.iter_subnets(prefixlen_diff, new_prefix))
def supernet(self, prefixlen_diff=1, new_prefix=None):
"""The supernet containing the current network.
Args:
prefixlen_diff: An integer, the amount the prefix length of
the network should be decreased by. For example, given a
/24 network and a prefixlen_diff of 3, a supernet with a
/21 netmask is returned.
Returns:
An IPv4 network object.
Raises:
ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have a
negative prefix length.
OR
If prefixlen_diff and new_prefix are both set or new_prefix is a
larger number than the current prefix (larger number means a
smaller network)
"""
if self._prefixlen == 0:
return self
if new_prefix is not None:
if new_prefix > self._prefixlen:
raise ValueError('new prefix must be shorter')
if prefixlen_diff != 1:
raise ValueError('cannot set prefixlen_diff and new_prefix')
prefixlen_diff = self._prefixlen - new_prefix
if self.prefixlen - prefixlen_diff < 0:
raise ValueError(
'current prefixlen is %d, cannot have a prefixlen_diff of %d' %
(self.prefixlen, prefixlen_diff))
return IPNetwork('%s/%s' % (str(self.network),
str(self.prefixlen - prefixlen_diff)),
version=self._version)
# backwards compatibility
Subnet = subnet
Supernet = supernet
AddressExclude = address_exclude
CompareNetworks = compare_networks
Contains = __contains__
class _BaseV4(object):
"""Base IPv4 object.
The following methods are used by IPv4 objects in both single IP
addresses and networks.
"""
# Equivalent to 255.255.255.255 or 32 bits of 1's.
_ALL_ONES = (2**IPV4LENGTH) - 1
_DECIMAL_DIGITS = frozenset('0123456789')
def __init__(self, address):
self._version = 4
self._max_prefixlen = IPV4LENGTH
def _explode_shorthand_ip_string(self, ip_str=None):
if not ip_str:
ip_str = str(self)
return ip_str
def _ip_int_from_string(self, ip_str):
"""Turn the given IP string into an integer for comparison.
Args:
ip_str: A string, the IP ip_str.
Returns:
The IP ip_str as an integer.
Raises:
AddressValueError: if ip_str isn't a valid IPv4 Address.
"""
octets = ip_str.split('.')
if len(octets) != 4:
raise AddressValueError(ip_str)
packed_ip = 0
for oc in octets:
try:
packed_ip = (packed_ip << 8) | self._parse_octet(oc)
except ValueError:
raise AddressValueError(ip_str)
return packed_ip
def _parse_octet(self, octet_str):
"""Convert a decimal octet into an integer.
Args:
octet_str: A string, the number to parse.
Returns:
The octet as an integer.
Raises:
ValueError: if the octet isn't strictly a decimal from [0..255].
"""
# Whitelist the characters, since int() allows a lot of bizarre stuff.
if not self._DECIMAL_DIGITS.issuperset(octet_str):
raise ValueError
octet_int = int(octet_str, 10)
# Disallow leading zeroes, because no clear standard exists on
# whether these should be interpreted as decimal or octal.
if octet_int > 255 or (octet_str[0] == '0' and len(octet_str) > 1):
raise ValueError
return octet_int
def _string_from_ip_int(self, ip_int):
"""Turns a 32-bit integer into dotted decimal notation.
Args:
ip_int: An integer, the IP address.
Returns:
The IP address as a string in dotted decimal notation.
"""
octets = []
for _ in xrange(4):
octets.insert(0, str(ip_int & 0xFF))
ip_int >>= 8
return '.'.join(octets)
@property
def max_prefixlen(self):
return self._max_prefixlen
@property
def packed(self):
"""The binary representation of this address."""
return v4_int_to_packed(self._ip)
@property
def version(self):
return self._version
@property
def is_reserved(self):
"""Test if the address is otherwise IETF reserved.
Returns:
A boolean, True if the address is within the
reserved IPv4 Network range.
"""
return self in IPv4Network('240.0.0.0/4')
@property
def is_private(self):
"""Test if this address is allocated for private networks.
Returns:
A boolean, True if the address is reserved per RFC 1918.
"""
return (self in IPv4Network('10.0.0.0/8') or
self in IPv4Network('172.16.0.0/12') or
self in IPv4Network('192.168.0.0/16'))
@property
def is_multicast(self):
"""Test if the address is reserved for multicast use.
Returns:
A boolean, True if the address is multicast.
See RFC 3171 for details.
"""
return self in IPv4Network('224.0.0.0/4')
@property
def is_unspecified(self):
"""Test if the address is unspecified.
Returns:
A boolean, True if this is the unspecified address as defined in
RFC 5735 3.
"""
return self in IPv4Network('0.0.0.0')
@property
def is_loopback(self):
"""Test if the address is a loopback address.
Returns:
A boolean, True if the address is a loopback per RFC 3330.
"""
return self in IPv4Network('127.0.0.0/8')
@property
def is_link_local(self):
"""Test if the address is reserved for link-local.
Returns:
A boolean, True if the address is link-local per RFC 3927.
"""
return self in IPv4Network('169.254.0.0/16')
class IPv4Address(_BaseV4, _BaseIP):
"""Represent and manipulate single IPv4 Addresses."""
def __init__(self, address):
"""
Args:
address: A string or integer representing the IP
'192.168.1.1'
Additionally, an integer can be passed, so
IPv4Address('192.168.1.1') == IPv4Address(3232235777).
or, more generally
IPv4Address(int(IPv4Address('192.168.1.1'))) ==
IPv4Address('192.168.1.1')
Raises:
AddressValueError: If ipaddr isn't a valid IPv4 address.
"""
_BaseIP.__init__(self, address)
_BaseV4.__init__(self, address)
# Efficient constructor from integer.
if isinstance(address, (int, long)):
self._ip = address
if address < 0 or address > self._ALL_ONES:
raise AddressValueError(address)
return
# Constructing from a packed address
if _compat_has_real_bytes:
if isinstance(address, bytes) and len(address) == 4:
self._ip = struct.unpack('!I', address)[0]
return
# Assume input argument to be string or any object representation
# which converts into a formatted IP string.
addr_str = str(address)
self._ip = self._ip_int_from_string(addr_str)
class IPv4Network(_BaseV4, _BaseNet):
"""This class represents and manipulates 32-bit IPv4 networks.
Attributes: [examples for IPv4Network('1.2.3.4/27')]
._ip: 16909060
.ip: IPv4Address('1.2.3.4')
.network: IPv4Address('1.2.3.0')
.hostmask: IPv4Address('0.0.0.31')
.broadcast: IPv4Address('1.2.3.31')
.netmask: IPv4Address('255.255.255.224')
.prefixlen: 27
"""
# the valid octets for host and netmasks. only useful for IPv4.
_valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
def __init__(self, address, strict=False):
"""Instantiate a new IPv4 network object.
Args:
address: A string or integer representing the IP [& network].
'192.168.1.1/24'
'192.168.1.1/255.255.255.0'
'192.168.1.1/0.0.0.255'
are all functionally the same in IPv4. Similarly,
'192.168.1.1'
'192.168.1.1/255.255.255.255'
'192.168.1.1/32'
are also functionaly equivalent. That is to say, failing to
provide a subnetmask will create an object with a mask of /32.
If the mask (portion after the / in the argument) is given in
dotted quad form, it is treated as a netmask if it starts with a
non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it
starts with a zero field (e.g. 0.255.255.255 == /8), with the
single exception of an all-zero mask which is treated as a
netmask == /0. If no mask is given, a default of /32 is used.
Additionally, an integer can be passed, so
IPv4Network('192.168.1.1') == IPv4Network(3232235777).
or, more generally
IPv4Network(int(IPv4Network('192.168.1.1'))) ==
IPv4Network('192.168.1.1')
strict: A boolean. If true, ensure that we have been passed
A true network address, eg, 192.168.1.0/24 and not an
IP address on a network, eg, 192.168.1.1/24.
Raises:
AddressValueError: If ipaddr isn't a valid IPv4 address.
NetmaskValueError: If the netmask isn't valid for
an IPv4 address.
ValueError: If strict was True and a network address was not
supplied.
"""
_BaseNet.__init__(self, address)
_BaseV4.__init__(self, address)
# Efficient constructor from integer.
if isinstance(address, (int, long)):
self._ip = address
self.ip = IPv4Address(self._ip)
self._prefixlen = self._max_prefixlen
self.netmask = IPv4Address(self._ALL_ONES)
if address < 0 or address > self._ALL_ONES:
raise AddressValueError(address)
return
# Constructing from a packed address
if _compat_has_real_bytes:
if isinstance(address, bytes) and len(address) == 4:
self._ip = struct.unpack('!I', address)[0]
self.ip = IPv4Address(self._ip)
self._prefixlen = self._max_prefixlen
self.netmask = IPv4Address(self._ALL_ONES)
return
# Assume input argument to be string or any object representation
# which converts into a formatted IP prefix string.
addr = str(address).split('/')
if len(addr) > 2:
raise AddressValueError(address)
self._ip = self._ip_int_from_string(addr[0])
self.ip = IPv4Address(self._ip)
if len(addr) == 2:
mask = addr[1].split('.')
if len(mask) == 4:
# We have dotted decimal netmask.
if self._is_valid_netmask(addr[1]):
self.netmask = IPv4Address(self._ip_int_from_string(
addr[1]))
elif self._is_hostmask(addr[1]):
self.netmask = IPv4Address(
self._ip_int_from_string(addr[1]) ^ self._ALL_ONES)
else:
raise NetmaskValueError('%s is not a valid netmask'
% addr[1])
self._prefixlen = self._prefix_from_ip_int(int(self.netmask))
else:
# We have a netmask in prefix length form.
if not self._is_valid_netmask(addr[1]):
raise NetmaskValueError(addr[1])
self._prefixlen = int(addr[1])
self.netmask = IPv4Address(self._ip_int_from_prefix(
self._prefixlen))
else:
self._prefixlen = self._max_prefixlen
self.netmask = IPv4Address(self._ip_int_from_prefix(
self._prefixlen))
if strict:
if self.ip != self.network:
raise ValueError('%s has host bits set' %
self.ip)
def _is_hostmask(self, ip_str):
"""Test if the IP string is a hostmask (rather than a netmask).
Args:
ip_str: A string, the potential hostmask.
Returns:
A boolean, True if the IP string is a hostmask.
"""
bits = ip_str.split('.')
try:
parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
except ValueError:
return False
if len(parts) != len(bits):
return False
if parts[0] < parts[-1]:
return True
return False
def _is_valid_netmask(self, netmask):
"""Verify that the netmask is valid.
Args:
netmask: A string, either a prefix or dotted decimal
netmask.
Returns:
A boolean, True if the prefix represents a valid IPv4
netmask.
"""
mask = netmask.split('.')
if len(mask) == 4:
if [x for x in mask if int(x) not in self._valid_mask_octets]:
return False
if [y for idx, y in enumerate(mask) if idx > 0 and
y > mask[idx - 1]]:
return False
return True
try:
netmask = int(netmask)
except ValueError:
return False
return 0 <= netmask <= self._max_prefixlen
# backwards compatibility
IsRFC1918 = lambda self: self.is_private
IsMulticast = lambda self: self.is_multicast
IsLoopback = lambda self: self.is_loopback
IsLinkLocal = lambda self: self.is_link_local
class _BaseV6(object):
"""Base IPv6 object.
The following methods are used by IPv6 objects in both single IP
addresses and networks.
"""
_ALL_ONES = (2**IPV6LENGTH) - 1
_HEXTET_COUNT = 8
_HEX_DIGITS = frozenset('0123456789ABCDEFabcdef')
def __init__(self, address):
self._version = 6
self._max_prefixlen = IPV6LENGTH
def _ip_int_from_string(self, ip_str):
"""Turn an IPv6 ip_str into an integer.
Args:
ip_str: A string, the IPv6 ip_str.
Returns:
A long, the IPv6 ip_str.
Raises:
AddressValueError: if ip_str isn't a valid IPv6 Address.
"""
parts = ip_str.split(':')
# An IPv6 address needs at least 2 colons (3 parts).
if len(parts) < 3:
raise AddressValueError(ip_str)
# If the address has an IPv4-style suffix, convert it to hexadecimal.
if '.' in parts[-1]:
ipv4_int = IPv4Address(parts.pop())._ip
parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF))
parts.append('%x' % (ipv4_int & 0xFFFF))
# An IPv6 address can't have more than 8 colons (9 parts).
if len(parts) > self._HEXTET_COUNT + 1:
raise AddressValueError(ip_str)
# Disregarding the endpoints, find '::' with nothing in between.
# This indicates that a run of zeroes has been skipped.
try:
skip_index, = (
[i for i in xrange(1, len(parts) - 1) if not parts[i]] or
[None])
except ValueError:
# Can't have more than one '::'
raise AddressValueError(ip_str)
# parts_hi is the number of parts to copy from above/before the '::'
# parts_lo is the number of parts to copy from below/after the '::'
if skip_index is not None:
# If we found a '::', then check if it also covers the endpoints.
parts_hi = skip_index
parts_lo = len(parts) - skip_index - 1
if not parts[0]:
parts_hi -= 1
if parts_hi:
raise AddressValueError(ip_str) # ^: requires ^::
if not parts[-1]:
parts_lo -= 1
if parts_lo:
raise AddressValueError(ip_str) # :$ requires ::$
parts_skipped = self._HEXTET_COUNT - (parts_hi + parts_lo)
if parts_skipped < 1:
raise AddressValueError(ip_str)
else:
# Otherwise, allocate the entire address to parts_hi. The endpoints
# could still be empty, but _parse_hextet() will check for that.
if len(parts) != self._HEXTET_COUNT:
raise AddressValueError(ip_str)
parts_hi = len(parts)
parts_lo = 0
parts_skipped = 0
try:
# Now, parse the hextets into a 128-bit integer.
ip_int = 0L
for i in xrange(parts_hi):
ip_int <<= 16
ip_int |= self._parse_hextet(parts[i])
ip_int <<= 16 * parts_skipped
for i in xrange(-parts_lo, 0):
ip_int <<= 16
ip_int |= self._parse_hextet(parts[i])
return ip_int
except ValueError:
raise AddressValueError(ip_str)
def _parse_hextet(self, hextet_str):
"""Convert an IPv6 hextet string into an integer.
Args:
hextet_str: A string, the number to parse.
Returns:
The hextet as an integer.
Raises:
ValueError: if the input isn't strictly a hex number from [0..FFFF].
"""
# Whitelist the characters, since int() allows a lot of bizarre stuff.
if not self._HEX_DIGITS.issuperset(hextet_str):
raise ValueError
hextet_int = int(hextet_str, 16)
if hextet_int > 0xFFFF:
raise ValueError
return hextet_int
def _compress_hextets(self, hextets):
"""Compresses a list of hextets.
Compresses a list of strings, replacing the longest continuous
sequence of "0" in the list with "" and adding empty strings at
the beginning or at the end of the string such that subsequently
calling ":".join(hextets) will produce the compressed version of
the IPv6 address.
Args:
hextets: A list of strings, the hextets to compress.
Returns:
A list of strings.
"""
best_doublecolon_start = -1
best_doublecolon_len = 0
doublecolon_start = -1
doublecolon_len = 0
for index in range(len(hextets)):
if hextets[index] == '0':
doublecolon_len += 1
if doublecolon_start == -1:
# Start of a sequence of zeros.
doublecolon_start = index
if doublecolon_len > best_doublecolon_len:
# This is the longest sequence of zeros so far.
best_doublecolon_len = doublecolon_len
best_doublecolon_start = doublecolon_start
else:
doublecolon_len = 0
doublecolon_start = -1
if best_doublecolon_len > 1:
best_doublecolon_end = (best_doublecolon_start +
best_doublecolon_len)
# For zeros at the end of the address.
if best_doublecolon_end == len(hextets):
hextets += ['']
hextets[best_doublecolon_start:best_doublecolon_end] = ['']
# For zeros at the beginning of the address.
if best_doublecolon_start == 0:
hextets = [''] + hextets
return hextets
def _string_from_ip_int(self, ip_int=None):
"""Turns a 128-bit integer into hexadecimal notation.
Args:
ip_int: An integer, the IP address.
Returns:
A string, the hexadecimal representation of the address.
Raises:
ValueError: The address is bigger than 128 bits of all ones.
"""
if not ip_int and ip_int != 0:
ip_int = int(self._ip)
if ip_int > self._ALL_ONES:
raise ValueError('IPv6 address is too large')
hex_str = '%032x' % ip_int
hextets = []
for x in range(0, 32, 4):
hextets.append('%x' % int(hex_str[x:x+4], 16))
hextets = self._compress_hextets(hextets)
return ':'.join(hextets)
def _explode_shorthand_ip_string(self, ip_str=None):
"""Expand a shortened IPv6 address.
Args:
ip_str: A string, the IPv6 address.
Returns:
A string, the expanded IPv6 address.
"""
if not ip_str:
ip_str = str(self)
if isinstance(self, _BaseNet):
ip_str = str(self.ip)
ip_int = self._ip_int_from_string(ip_str)
parts = []
for i in xrange(self._HEXTET_COUNT):
parts.append('%04x' % (ip_int & 0xFFFF))
ip_int >>= 16
parts.reverse()
return ':'.join(parts)
@property
def max_prefixlen(self):
return self._max_prefixlen
@property
def packed(self):
"""The binary representation of this address."""
return v6_int_to_packed(self._ip)
@property
def version(self):
return self._version
@property
def is_multicast(self):
"""Test if the address is reserved for multicast use.
Returns:
A boolean, True if the address is a multicast address.
See RFC 2373 2.7 for details.
"""
return self in IPv6Network('ff00::/8')
@property
def is_reserved(self):
"""Test if the address is otherwise IETF reserved.
Returns:
A boolean, True if the address is within one of the
reserved IPv6 Network ranges.
"""
return (self in IPv6Network('::/8') or
self in IPv6Network('100::/8') or
self in IPv6Network('200::/7') or
self in IPv6Network('400::/6') or
self in IPv6Network('800::/5') or
self in IPv6Network('1000::/4') or
self in IPv6Network('4000::/3') or
self in IPv6Network('6000::/3') or
self in IPv6Network('8000::/3') or
self in IPv6Network('A000::/3') or
self in IPv6Network('C000::/3') or
self in IPv6Network('E000::/4') or
self in IPv6Network('F000::/5') or
self in IPv6Network('F800::/6') or
self in IPv6Network('FE00::/9'))
@property
def is_unspecified(self):
"""Test if the address is unspecified.
Returns:
A boolean, True if this is the unspecified address as defined in
RFC 2373 2.5.2.
"""
return self._ip == 0 and getattr(self, '_prefixlen', 128) == 128
@property
def is_loopback(self):
"""Test if the address is a loopback address.
Returns:
A boolean, True if the address is a loopback address as defined in
RFC 2373 2.5.3.
"""
return self._ip == 1 and getattr(self, '_prefixlen', 128) == 128
@property
def is_link_local(self):
"""Test if the address is reserved for link-local.
Returns:
A boolean, True if the address is reserved per RFC 4291.
"""
return self in IPv6Network('fe80::/10')
@property
def is_site_local(self):
"""Test if the address is reserved for site-local.
Note that the site-local address space has been deprecated by RFC 3879.
Use is_private to test if this address is in the space of unique local
addresses as defined by RFC 4193.
Returns:
A boolean, True if the address is reserved per RFC 3513 2.5.6.
"""
return self in IPv6Network('fec0::/10')
@property
def is_private(self):
"""Test if this address is allocated for private networks.
Returns:
A boolean, True if the address is reserved per RFC 4193.
"""
return self in IPv6Network('fc00::/7')
@property
def ipv4_mapped(self):
"""Return the IPv4 mapped address.
Returns:
If the IPv6 address is a v4 mapped address, return the
IPv4 mapped address. Return None otherwise.
"""
if (self._ip >> 32) != 0xFFFF:
return None
return IPv4Address(self._ip & 0xFFFFFFFF)
@property
def teredo(self):
"""Tuple of embedded teredo IPs.
Returns:
Tuple of the (server, client) IPs or None if the address
doesn't appear to be a teredo address (doesn't start with
2001::/32)
"""
if (self._ip >> 96) != 0x20010000:
return None
return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF),
IPv4Address(~self._ip & 0xFFFFFFFF))
@property
def sixtofour(self):
"""Return the IPv4 6to4 embedded address.
Returns:
The IPv4 6to4-embedded address if present or None if the
address doesn't appear to contain a 6to4 embedded address.
"""
if (self._ip >> 112) != 0x2002:
return None
return IPv4Address((self._ip >> 80) & 0xFFFFFFFF)
class IPv6Address(_BaseV6, _BaseIP):
"""Represent and manipulate single IPv6 Addresses.
"""
def __init__(self, address):
"""Instantiate a new IPv6 address object.
Args:
address: A string or integer representing the IP
Additionally, an integer can be passed, so
IPv6Address('2001:4860::') ==
IPv6Address(42541956101370907050197289607612071936L).
or, more generally
IPv6Address(IPv6Address('2001:4860::')._ip) ==
IPv6Address('2001:4860::')
Raises:
AddressValueError: If address isn't a valid IPv6 address.
"""
_BaseIP.__init__(self, address)
_BaseV6.__init__(self, address)
# Efficient constructor from integer.
if isinstance(address, (int, long)):
self._ip = address
if address < 0 or address > self._ALL_ONES:
raise AddressValueError(address)
return
# Constructing from a packed address
if _compat_has_real_bytes:
if isinstance(address, bytes) and len(address) == 16:
tmp = struct.unpack('!QQ', address)
self._ip = (tmp[0] << 64) | tmp[1]
return
# Assume input argument to be string or any object representation
# which converts into a formatted IP string.
addr_str = str(address)
if not addr_str:
raise AddressValueError('')
self._ip = self._ip_int_from_string(addr_str)
class IPv6Network(_BaseV6, _BaseNet):
"""This class represents and manipulates 128-bit IPv6 networks.
Attributes: [examples for IPv6('2001:658:22A:CAFE:200::1/64')]
.ip: IPv6Address('2001:658:22a:cafe:200::1')
.network: IPv6Address('2001:658:22a:cafe::')
.hostmask: IPv6Address('::ffff:ffff:ffff:ffff')
.broadcast: IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff')
.netmask: IPv6Address('ffff:ffff:ffff:ffff::')
.prefixlen: 64
"""
def __init__(self, address, strict=False):
"""Instantiate a new IPv6 Network object.
Args:
address: A string or integer representing the IPv6 network or the IP
and prefix/netmask.
'2001:4860::/128'
'2001:4860:0000:0000:0000:0000:0000:0000/128'
'2001:4860::'
are all functionally the same in IPv6. That is to say,
failing to provide a subnetmask will create an object with
a mask of /128.
Additionally, an integer can be passed, so
IPv6Network('2001:4860::') ==
IPv6Network(42541956101370907050197289607612071936L).
or, more generally
IPv6Network(IPv6Network('2001:4860::')._ip) ==
IPv6Network('2001:4860::')
strict: A boolean. If true, ensure that we have been passed
A true network address, eg, 192.168.1.0/24 and not an
IP address on a network, eg, 192.168.1.1/24.
Raises:
AddressValueError: If address isn't a valid IPv6 address.
NetmaskValueError: If the netmask isn't valid for
an IPv6 address.
ValueError: If strict was True and a network address was not
supplied.
"""
_BaseNet.__init__(self, address)
_BaseV6.__init__(self, address)
# Efficient constructor from integer.
if isinstance(address, (int, long)):
self._ip = address
self.ip = IPv6Address(self._ip)
self._prefixlen = self._max_prefixlen
self.netmask = IPv6Address(self._ALL_ONES)
if address < 0 or address > self._ALL_ONES:
raise AddressValueError(address)
return
# Constructing from a packed address
if _compat_has_real_bytes:
if isinstance(address, bytes) and len(address) == 16:
tmp = struct.unpack('!QQ', address)
self._ip = (tmp[0] << 64) | tmp[1]
self.ip = IPv6Address(self._ip)
self._prefixlen = self._max_prefixlen
self.netmask = IPv6Address(self._ALL_ONES)
return
# Assume input argument to be string or any object representation
# which converts into a formatted IP prefix string.
addr = str(address).split('/')
if len(addr) > 2:
raise AddressValueError(address)
self._ip = self._ip_int_from_string(addr[0])
self.ip = IPv6Address(self._ip)
if len(addr) == 2:
if self._is_valid_netmask(addr[1]):
self._prefixlen = int(addr[1])
else:
raise NetmaskValueError(addr[1])
else:
self._prefixlen = self._max_prefixlen
self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen))
if strict:
if self.ip != self.network:
raise ValueError('%s has host bits set' %
self.ip)
def _is_valid_netmask(self, prefixlen):
"""Verify that the netmask/prefixlen is valid.
Args:
prefixlen: A string, the netmask in prefix length format.
Returns:
A boolean, True if the prefix represents a valid IPv6
netmask.
"""
try:
prefixlen = int(prefixlen)
except ValueError:
return False
return 0 <= prefixlen <= self._max_prefixlen
@property
def with_netmask(self):
return self.with_prefixlen
glusterfs-3.4.2/contrib/rbtree/ 0000755 0000762 0000763 00000000000 12261516146 013473 5 0000000 0000000 glusterfs-3.4.2/contrib/rbtree/rb.c 0000644 0000762 0000763 00000061203 12261516067 014166 0000000 0000000 /* Produced by texiweb from libavl.w. */
/* libavl - library for manipulation of binary trees.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
This code is also covered by the following earlier license notice:
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; either version 2 of the
License, or (at your option) any later version.
*/
#include
#include
#include
#include
#include "rb.h"
/* Creates and returns a new table
with comparison function |compare| using parameter |param|
and memory allocator |allocator|.
Returns |NULL| if memory allocation failed. */
struct rb_table *
rb_create (rb_comparison_func *compare, void *param,
struct libavl_allocator *allocator)
{
struct rb_table *tree;
assert (compare != NULL);
if (allocator == NULL)
allocator = &rb_allocator_default;
tree = allocator->libavl_malloc (allocator, sizeof *tree);
if (tree == NULL)
return NULL;
tree->rb_root = NULL;
tree->rb_compare = compare;
tree->rb_param = param;
tree->rb_alloc = allocator;
tree->rb_count = 0;
tree->rb_generation = 0;
return tree;
}
/* Search |tree| for an item matching |item|, and return it if found.
Otherwise return |NULL|. */
void *
rb_find (const struct rb_table *tree, const void *item)
{
const struct rb_node *p;
assert (tree != NULL && item != NULL);
for (p = tree->rb_root; p != NULL; )
{
int cmp = tree->rb_compare (item, p->rb_data, tree->rb_param);
if (cmp < 0)
p = p->rb_link[0];
else if (cmp > 0)
p = p->rb_link[1];
else /* |cmp == 0| */
return p->rb_data;
}
return NULL;
}
/* Inserts |item| into |tree| and returns a pointer to |item|'s address.
If a duplicate item is found in the tree,
returns a pointer to the duplicate without inserting |item|.
Returns |NULL| in case of memory allocation failure. */
void **
rb_probe (struct rb_table *tree, void *item)
{
struct rb_node *pa[RB_MAX_HEIGHT]; /* Nodes on stack. */
unsigned char da[RB_MAX_HEIGHT]; /* Directions moved from stack nodes. */
int k; /* Stack height. */
struct rb_node *p; /* Traverses tree looking for insertion point. */
struct rb_node *n; /* Newly inserted node. */
assert (tree != NULL && item != NULL);
pa[0] = (struct rb_node *) &tree->rb_root;
da[0] = 0;
k = 1;
for (p = tree->rb_root; p != NULL; p = p->rb_link[da[k - 1]])
{
int cmp = tree->rb_compare (item, p->rb_data, tree->rb_param);
if (cmp == 0)
return &p->rb_data;
pa[k] = p;
da[k++] = cmp > 0;
}
n = pa[k - 1]->rb_link[da[k - 1]] =
tree->rb_alloc->libavl_malloc (tree->rb_alloc, sizeof *n);
if (n == NULL)
return NULL;
n->rb_data = item;
n->rb_link[0] = n->rb_link[1] = NULL;
n->rb_color = RB_RED;
tree->rb_count++;
tree->rb_generation++;
while (k >= 3 && pa[k - 1]->rb_color == RB_RED)
{
if (da[k - 2] == 0)
{
struct rb_node *y = pa[k - 2]->rb_link[1];
if (y != NULL && y->rb_color == RB_RED)
{
pa[k - 1]->rb_color = y->rb_color = RB_BLACK;
pa[k - 2]->rb_color = RB_RED;
k -= 2;
}
else
{
struct rb_node *x;
if (da[k - 1] == 0)
y = pa[k - 1];
else
{
x = pa[k - 1];
y = x->rb_link[1];
x->rb_link[1] = y->rb_link[0];
y->rb_link[0] = x;
pa[k - 2]->rb_link[0] = y;
}
x = pa[k - 2];
x->rb_color = RB_RED;
y->rb_color = RB_BLACK;
x->rb_link[0] = y->rb_link[1];
y->rb_link[1] = x;
pa[k - 3]->rb_link[da[k - 3]] = y;
break;
}
}
else
{
struct rb_node *y = pa[k - 2]->rb_link[0];
if (y != NULL && y->rb_color == RB_RED)
{
pa[k - 1]->rb_color = y->rb_color = RB_BLACK;
pa[k - 2]->rb_color = RB_RED;
k -= 2;
}
else
{
struct rb_node *x;
if (da[k - 1] == 1)
y = pa[k - 1];
else
{
x = pa[k - 1];
y = x->rb_link[0];
x->rb_link[0] = y->rb_link[1];
y->rb_link[1] = x;
pa[k - 2]->rb_link[1] = y;
}
x = pa[k - 2];
x->rb_color = RB_RED;
y->rb_color = RB_BLACK;
x->rb_link[1] = y->rb_link[0];
y->rb_link[0] = x;
pa[k - 3]->rb_link[da[k - 3]] = y;
break;
}
}
}
tree->rb_root->rb_color = RB_BLACK;
return &n->rb_data;
}
/* Inserts |item| into |table|.
Returns |NULL| if |item| was successfully inserted
or if a memory allocation error occurred.
Otherwise, returns the duplicate item. */
void *
rb_insert (struct rb_table *table, void *item)
{
void **p = rb_probe (table, item);
return p == NULL || *p == item ? NULL : *p;
}
/* Inserts |item| into |table|, replacing any duplicate item.
Returns |NULL| if |item| was inserted without replacing a duplicate,
or if a memory allocation error occurred.
Otherwise, returns the item that was replaced. */
void *
rb_replace (struct rb_table *table, void *item)
{
void **p = rb_probe (table, item);
if (p == NULL || *p == item)
return NULL;
else
{
void *r = *p;
*p = item;
return r;
}
}
/* Deletes from |tree| and returns an item matching |item|.
Returns a null pointer if no matching item found. */
void *
rb_delete (struct rb_table *tree, const void *item)
{
struct rb_node *pa[RB_MAX_HEIGHT]; /* Nodes on stack. */
unsigned char da[RB_MAX_HEIGHT]; /* Directions moved from stack nodes. */
int k; /* Stack height. */
struct rb_node *p; /* The node to delete, or a node part way to it. */
int cmp; /* Result of comparison between |item| and |p|. */
assert (tree != NULL && item != NULL);
k = 0;
p = (struct rb_node *) &tree->rb_root;
for (cmp = -1; cmp != 0;
cmp = tree->rb_compare (item, p->rb_data, tree->rb_param))
{
int dir = cmp > 0;
pa[k] = p;
da[k++] = dir;
p = p->rb_link[dir];
if (p == NULL)
return NULL;
}
item = p->rb_data;
if (p->rb_link[1] == NULL)
pa[k - 1]->rb_link[da[k - 1]] = p->rb_link[0];
else
{
enum rb_color t;
struct rb_node *r = p->rb_link[1];
if (r->rb_link[0] == NULL)
{
r->rb_link[0] = p->rb_link[0];
t = r->rb_color;
r->rb_color = p->rb_color;
p->rb_color = t;
pa[k - 1]->rb_link[da[k - 1]] = r;
da[k] = 1;
pa[k++] = r;
}
else
{
struct rb_node *s;
int j = k++;
for (;;)
{
da[k] = 0;
pa[k++] = r;
s = r->rb_link[0];
if (s->rb_link[0] == NULL)
break;
r = s;
}
da[j] = 1;
pa[j] = s;
pa[j - 1]->rb_link[da[j - 1]] = s;
s->rb_link[0] = p->rb_link[0];
r->rb_link[0] = s->rb_link[1];
s->rb_link[1] = p->rb_link[1];
t = s->rb_color;
s->rb_color = p->rb_color;
p->rb_color = t;
}
}
if (p->rb_color == RB_BLACK)
{
for (;;)
{
struct rb_node *x = pa[k - 1]->rb_link[da[k - 1]];
if (x != NULL && x->rb_color == RB_RED)
{
x->rb_color = RB_BLACK;
break;
}
if (k < 2)
break;
if (da[k - 1] == 0)
{
struct rb_node *w = pa[k - 1]->rb_link[1];
if (w->rb_color == RB_RED)
{
w->rb_color = RB_BLACK;
pa[k - 1]->rb_color = RB_RED;
pa[k - 1]->rb_link[1] = w->rb_link[0];
w->rb_link[0] = pa[k - 1];
pa[k - 2]->rb_link[da[k - 2]] = w;
pa[k] = pa[k - 1];
da[k] = 0;
pa[k - 1] = w;
k++;
w = pa[k - 1]->rb_link[1];
}
if ((w->rb_link[0] == NULL
|| w->rb_link[0]->rb_color == RB_BLACK)
&& (w->rb_link[1] == NULL
|| w->rb_link[1]->rb_color == RB_BLACK))
w->rb_color = RB_RED;
else
{
if (w->rb_link[1] == NULL
|| w->rb_link[1]->rb_color == RB_BLACK)
{
struct rb_node *y = w->rb_link[0];
y->rb_color = RB_BLACK;
w->rb_color = RB_RED;
w->rb_link[0] = y->rb_link[1];
y->rb_link[1] = w;
w = pa[k - 1]->rb_link[1] = y;
}
w->rb_color = pa[k - 1]->rb_color;
pa[k - 1]->rb_color = RB_BLACK;
w->rb_link[1]->rb_color = RB_BLACK;
pa[k - 1]->rb_link[1] = w->rb_link[0];
w->rb_link[0] = pa[k - 1];
pa[k - 2]->rb_link[da[k - 2]] = w;
break;
}
}
else
{
struct rb_node *w = pa[k - 1]->rb_link[0];
if (w->rb_color == RB_RED)
{
w->rb_color = RB_BLACK;
pa[k - 1]->rb_color = RB_RED;
pa[k - 1]->rb_link[0] = w->rb_link[1];
w->rb_link[1] = pa[k - 1];
pa[k - 2]->rb_link[da[k - 2]] = w;
pa[k] = pa[k - 1];
da[k] = 1;
pa[k - 1] = w;
k++;
w = pa[k - 1]->rb_link[0];
}
if ((w->rb_link[0] == NULL
|| w->rb_link[0]->rb_color == RB_BLACK)
&& (w->rb_link[1] == NULL
|| w->rb_link[1]->rb_color == RB_BLACK))
w->rb_color = RB_RED;
else
{
if (w->rb_link[0] == NULL
|| w->rb_link[0]->rb_color == RB_BLACK)
{
struct rb_node *y = w->rb_link[1];
y->rb_color = RB_BLACK;
w->rb_color = RB_RED;
w->rb_link[1] = y->rb_link[0];
y->rb_link[0] = w;
w = pa[k - 1]->rb_link[0] = y;
}
w->rb_color = pa[k - 1]->rb_color;
pa[k - 1]->rb_color = RB_BLACK;
w->rb_link[0]->rb_color = RB_BLACK;
pa[k - 1]->rb_link[0] = w->rb_link[1];
w->rb_link[1] = pa[k - 1];
pa[k - 2]->rb_link[da[k - 2]] = w;
break;
}
}
k--;
}
}
tree->rb_alloc->libavl_free (tree->rb_alloc, p);
tree->rb_count--;
tree->rb_generation++;
return (void *) item;
}
/* Refreshes the stack of parent pointers in |trav|
and updates its generation number. */
static void
trav_refresh (struct rb_traverser *trav)
{
assert (trav != NULL);
trav->rb_generation = trav->rb_table->rb_generation;
if (trav->rb_node != NULL)
{
rb_comparison_func *cmp = trav->rb_table->rb_compare;
void *param = trav->rb_table->rb_param;
struct rb_node *node = trav->rb_node;
struct rb_node *i;
trav->rb_height = 0;
for (i = trav->rb_table->rb_root; i != node; )
{
assert (trav->rb_height < RB_MAX_HEIGHT);
assert (i != NULL);
trav->rb_stack[trav->rb_height++] = i;
i = i->rb_link[cmp (node->rb_data, i->rb_data, param) > 0];
}
}
}
/* Initializes |trav| for use with |tree|
and selects the null node. */
void
rb_t_init (struct rb_traverser *trav, struct rb_table *tree)
{
trav->rb_table = tree;
trav->rb_node = NULL;
trav->rb_height = 0;
trav->rb_generation = tree->rb_generation;
}
/* Initializes |trav| for |tree|
and selects and returns a pointer to its least-valued item.
Returns |NULL| if |tree| contains no nodes. */
void *
rb_t_first (struct rb_traverser *trav, struct rb_table *tree)
{
struct rb_node *x;
assert (tree != NULL && trav != NULL);
trav->rb_table = tree;
trav->rb_height = 0;
trav->rb_generation = tree->rb_generation;
x = tree->rb_root;
if (x != NULL)
while (x->rb_link[0] != NULL)
{
assert (trav->rb_height < RB_MAX_HEIGHT);
trav->rb_stack[trav->rb_height++] = x;
x = x->rb_link[0];
}
trav->rb_node = x;
return x != NULL ? x->rb_data : NULL;
}
/* Initializes |trav| for |tree|
and selects and returns a pointer to its greatest-valued item.
Returns |NULL| if |tree| contains no nodes. */
void *
rb_t_last (struct rb_traverser *trav, struct rb_table *tree)
{
struct rb_node *x;
assert (tree != NULL && trav != NULL);
trav->rb_table = tree;
trav->rb_height = 0;
trav->rb_generation = tree->rb_generation;
x = tree->rb_root;
if (x != NULL)
while (x->rb_link[1] != NULL)
{
assert (trav->rb_height < RB_MAX_HEIGHT);
trav->rb_stack[trav->rb_height++] = x;
x = x->rb_link[1];
}
trav->rb_node = x;
return x != NULL ? x->rb_data : NULL;
}
/* Searches for |item| in |tree|.
If found, initializes |trav| to the item found and returns the item
as well.
If there is no matching item, initializes |trav| to the null item
and returns |NULL|. */
void *
rb_t_find (struct rb_traverser *trav, struct rb_table *tree, void *item)
{
struct rb_node *p, *q;
assert (trav != NULL && tree != NULL && item != NULL);
trav->rb_table = tree;
trav->rb_height = 0;
trav->rb_generation = tree->rb_generation;
for (p = tree->rb_root; p != NULL; p = q)
{
int cmp = tree->rb_compare (item, p->rb_data, tree->rb_param);
if (cmp < 0)
q = p->rb_link[0];
else if (cmp > 0)
q = p->rb_link[1];
else /* |cmp == 0| */
{
trav->rb_node = p;
return p->rb_data;
}
assert (trav->rb_height < RB_MAX_HEIGHT);
trav->rb_stack[trav->rb_height++] = p;
}
trav->rb_height = 0;
trav->rb_node = NULL;
return NULL;
}
/* Attempts to insert |item| into |tree|.
If |item| is inserted successfully, it is returned and |trav| is
initialized to its location.
If a duplicate is found, it is returned and |trav| is initialized to
its location. No replacement of the item occurs.
If a memory allocation failure occurs, |NULL| is returned and |trav|
is initialized to the null item. */
void *
rb_t_insert (struct rb_traverser *trav, struct rb_table *tree, void *item)
{
void **p;
assert (trav != NULL && tree != NULL && item != NULL);
p = rb_probe (tree, item);
if (p != NULL)
{
trav->rb_table = tree;
trav->rb_node =
((struct rb_node *)
((char *) p - offsetof (struct rb_node, rb_data)));
trav->rb_generation = tree->rb_generation - 1;
return *p;
}
else
{
rb_t_init (trav, tree);
return NULL;
}
}
/* Initializes |trav| to have the same current node as |src|. */
void *
rb_t_copy (struct rb_traverser *trav, const struct rb_traverser *src)
{
assert (trav != NULL && src != NULL);
if (trav != src)
{
trav->rb_table = src->rb_table;
trav->rb_node = src->rb_node;
trav->rb_generation = src->rb_generation;
if (trav->rb_generation == trav->rb_table->rb_generation)
{
trav->rb_height = src->rb_height;
memcpy (trav->rb_stack, (const void *) src->rb_stack,
sizeof *trav->rb_stack * trav->rb_height);
}
}
return trav->rb_node != NULL ? trav->rb_node->rb_data : NULL;
}
/* Returns the next data item in inorder
within the tree being traversed with |trav|,
or if there are no more data items returns |NULL|. */
void *
rb_t_next (struct rb_traverser *trav)
{
struct rb_node *x;
assert (trav != NULL);
if (trav->rb_generation != trav->rb_table->rb_generation)
trav_refresh (trav);
x = trav->rb_node;
if (x == NULL)
{
return rb_t_first (trav, trav->rb_table);
}
else if (x->rb_link[1] != NULL)
{
assert (trav->rb_height < RB_MAX_HEIGHT);
trav->rb_stack[trav->rb_height++] = x;
x = x->rb_link[1];
while (x->rb_link[0] != NULL)
{
assert (trav->rb_height < RB_MAX_HEIGHT);
trav->rb_stack[trav->rb_height++] = x;
x = x->rb_link[0];
}
}
else
{
struct rb_node *y;
do
{
if (trav->rb_height == 0)
{
trav->rb_node = NULL;
return NULL;
}
y = x;
x = trav->rb_stack[--trav->rb_height];
}
while (y == x->rb_link[1]);
}
trav->rb_node = x;
return x->rb_data;
}
/* Returns the previous data item in inorder
within the tree being traversed with |trav|,
or if there are no more data items returns |NULL|. */
void *
rb_t_prev (struct rb_traverser *trav)
{
struct rb_node *x;
assert (trav != NULL);
if (trav->rb_generation != trav->rb_table->rb_generation)
trav_refresh (trav);
x = trav->rb_node;
if (x == NULL)
{
return rb_t_last (trav, trav->rb_table);
}
else if (x->rb_link[0] != NULL)
{
assert (trav->rb_height < RB_MAX_HEIGHT);
trav->rb_stack[trav->rb_height++] = x;
x = x->rb_link[0];
while (x->rb_link[1] != NULL)
{
assert (trav->rb_height < RB_MAX_HEIGHT);
trav->rb_stack[trav->rb_height++] = x;
x = x->rb_link[1];
}
}
else
{
struct rb_node *y;
do
{
if (trav->rb_height == 0)
{
trav->rb_node = NULL;
return NULL;
}
y = x;
x = trav->rb_stack[--trav->rb_height];
}
while (y == x->rb_link[0]);
}
trav->rb_node = x;
return x->rb_data;
}
/* Returns |trav|'s current item. */
void *
rb_t_cur (struct rb_traverser *trav)
{
assert (trav != NULL);
return trav->rb_node != NULL ? trav->rb_node->rb_data : NULL;
}
/* Replaces the current item in |trav| by |new| and returns the item replaced.
|trav| must not have the null item selected.
The new item must not upset the ordering of the tree. */
void *
rb_t_replace (struct rb_traverser *trav, void *new)
{
void *old;
assert (trav != NULL && trav->rb_node != NULL && new != NULL);
old = trav->rb_node->rb_data;
trav->rb_node->rb_data = new;
return old;
}
/* Destroys |new| with |rb_destroy (new, destroy)|,
first setting right links of nodes in |stack| within |new|
to null pointers to avoid touching uninitialized data. */
static void
copy_error_recovery (struct rb_node **stack, int height,
struct rb_table *new, rb_item_func *destroy)
{
assert (stack != NULL && height >= 0 && new != NULL);
for (; height > 2; height -= 2)
stack[height - 1]->rb_link[1] = NULL;
rb_destroy (new, destroy);
}
/* Copies |org| to a newly created tree, which is returned.
If |copy != NULL|, each data item in |org| is first passed to |copy|,
and the return values are inserted into the tree,
with |NULL| return values taken as indications of failure.
On failure, destroys the partially created new tree,
applying |destroy|, if non-null, to each item in the new tree so far,
and returns |NULL|.
If |allocator != NULL|, it is used for allocation in the new tree.
Otherwise, the same allocator used for |org| is used. */
struct rb_table *
rb_copy (const struct rb_table *org, rb_copy_func *copy,
rb_item_func *destroy, struct libavl_allocator *allocator)
{
struct rb_node *stack[2 * (RB_MAX_HEIGHT + 1)];
int height = 0;
struct rb_table *new;
const struct rb_node *x;
struct rb_node *y;
assert (org != NULL);
new = rb_create (org->rb_compare, org->rb_param,
allocator != NULL ? allocator : org->rb_alloc);
if (new == NULL)
return NULL;
new->rb_count = org->rb_count;
if (new->rb_count == 0)
return new;
x = (const struct rb_node *) &org->rb_root;
y = (struct rb_node *) &new->rb_root;
for (;;)
{
while (x->rb_link[0] != NULL)
{
assert (height < 2 * (RB_MAX_HEIGHT + 1));
y->rb_link[0] =
new->rb_alloc->libavl_malloc (new->rb_alloc,
sizeof *y->rb_link[0]);
if (y->rb_link[0] == NULL)
{
if (y != (struct rb_node *) &new->rb_root)
{
y->rb_data = NULL;
y->rb_link[1] = NULL;
}
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
stack[height++] = (struct rb_node *) x;
stack[height++] = y;
x = x->rb_link[0];
y = y->rb_link[0];
}
y->rb_link[0] = NULL;
for (;;)
{
y->rb_color = x->rb_color;
if (copy == NULL)
y->rb_data = x->rb_data;
else
{
y->rb_data = copy (x->rb_data, org->rb_param);
if (y->rb_data == NULL)
{
y->rb_link[1] = NULL;
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
}
if (x->rb_link[1] != NULL)
{
y->rb_link[1] =
new->rb_alloc->libavl_malloc (new->rb_alloc,
sizeof *y->rb_link[1]);
if (y->rb_link[1] == NULL)
{
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
x = x->rb_link[1];
y = y->rb_link[1];
break;
}
else
y->rb_link[1] = NULL;
if (height <= 2)
return new;
y = stack[--height];
x = stack[--height];
}
}
}
/* Frees storage allocated for |tree|.
If |destroy != NULL|, applies it to each data item in inorder. */
void
rb_destroy (struct rb_table *tree, rb_item_func *destroy)
{
struct rb_node *p, *q;
assert (tree != NULL);
for (p = tree->rb_root; p != NULL; p = q)
if (p->rb_link[0] == NULL)
{
q = p->rb_link[1];
if (destroy != NULL && p->rb_data != NULL)
destroy (p->rb_data, tree->rb_param);
tree->rb_alloc->libavl_free (tree->rb_alloc, p);
}
else
{
q = p->rb_link[0];
p->rb_link[0] = q->rb_link[1];
q->rb_link[1] = p;
}
tree->rb_alloc->libavl_free (tree->rb_alloc, tree);
}
/* Allocates |size| bytes of space using |malloc()|.
Returns a null pointer if allocation fails. */
void *
rb_malloc (struct libavl_allocator *allocator, size_t size)
{
assert (allocator != NULL && size > 0);
return malloc (size);
}
/* Frees |block|. */
void
rb_free (struct libavl_allocator *allocator, void *block)
{
assert (allocator != NULL && block != NULL);
free (block);
}
/* Default memory allocator that uses |malloc()| and |free()|. */
struct libavl_allocator rb_allocator_default =
{
rb_malloc,
rb_free
};
#undef NDEBUG
#include
/* Asserts that |rb_insert()| succeeds at inserting |item| into |table|. */
void
(rb_assert_insert) (struct rb_table *table, void *item)
{
void **p = rb_probe (table, item);
assert (p != NULL && *p == item);
}
/* Asserts that |rb_delete()| really removes |item| from |table|,
and returns the removed item. */
void *
(rb_assert_delete) (struct rb_table *table, void *item)
{
void *p = rb_delete (table, item);
assert (p != NULL);
return p;
}
glusterfs-3.4.2/contrib/rbtree/rb.h 0000644 0000762 0000763 00000011066 12261516067 014175 0000000 0000000 /* Produced by texiweb from libavl.w. */
/* libavl - library for manipulation of binary trees.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
This code is also covered by the following earlier license notice:
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; either version 2 of the
License, or (at your option) any later version.
*/
#ifndef RB_H
#define RB_H 1
#include
/* Function types. */
typedef int rb_comparison_func (const void *rb_a, const void *rb_b,
void *rb_param);
typedef void rb_item_func (void *rb_item, void *rb_param);
typedef void *rb_copy_func (void *rb_item, void *rb_param);
#ifndef LIBAVL_ALLOCATOR
#define LIBAVL_ALLOCATOR
/* Memory allocator. */
struct libavl_allocator
{
void *(*libavl_malloc) (struct libavl_allocator *, size_t libavl_size);
void (*libavl_free) (struct libavl_allocator *, void *libavl_block);
};
#endif
/* Default memory allocator. */
extern struct libavl_allocator rb_allocator_default;
void *rb_malloc (struct libavl_allocator *, size_t);
void rb_free (struct libavl_allocator *, void *);
/* Maximum RB height. */
#ifndef RB_MAX_HEIGHT
#define RB_MAX_HEIGHT 128
#endif
/* Tree data structure. */
struct rb_table
{
struct rb_node *rb_root; /* Tree's root. */
rb_comparison_func *rb_compare; /* Comparison function. */
void *rb_param; /* Extra argument to |rb_compare|. */
struct libavl_allocator *rb_alloc; /* Memory allocator. */
size_t rb_count; /* Number of items in tree. */
unsigned long rb_generation; /* Generation number. */
};
/* Color of a red-black node. */
enum rb_color
{
RB_BLACK, /* Black. */
RB_RED /* Red. */
};
/* A red-black tree node. */
struct rb_node
{
struct rb_node *rb_link[2]; /* Subtrees. */
void *rb_data; /* Pointer to data. */
unsigned char rb_color; /* Color. */
};
/* RB traverser structure. */
struct rb_traverser
{
struct rb_table *rb_table; /* Tree being traversed. */
struct rb_node *rb_node; /* Current node in tree. */
struct rb_node *rb_stack[RB_MAX_HEIGHT];
/* All the nodes above |rb_node|. */
size_t rb_height; /* Number of nodes in |rb_parent|. */
unsigned long rb_generation; /* Generation number. */
};
/* Table functions. */
struct rb_table *rb_create (rb_comparison_func *, void *,
struct libavl_allocator *);
struct rb_table *rb_copy (const struct rb_table *, rb_copy_func *,
rb_item_func *, struct libavl_allocator *);
void rb_destroy (struct rb_table *, rb_item_func *);
void **rb_probe (struct rb_table *, void *);
void *rb_insert (struct rb_table *, void *);
void *rb_replace (struct rb_table *, void *);
void *rb_delete (struct rb_table *, const void *);
void *rb_find (const struct rb_table *, const void *);
void rb_assert_insert (struct rb_table *, void *);
void *rb_assert_delete (struct rb_table *, void *);
#define rb_count(table) ((size_t) (table)->rb_count)
/* Table traverser functions. */
void rb_t_init (struct rb_traverser *, struct rb_table *);
void *rb_t_first (struct rb_traverser *, struct rb_table *);
void *rb_t_last (struct rb_traverser *, struct rb_table *);
void *rb_t_find (struct rb_traverser *, struct rb_table *, void *);
void *rb_t_insert (struct rb_traverser *, struct rb_table *, void *);
void *rb_t_copy (struct rb_traverser *, const struct rb_traverser *);
void *rb_t_next (struct rb_traverser *);
void *rb_t_prev (struct rb_traverser *);
void *rb_t_cur (struct rb_traverser *);
void *rb_t_replace (struct rb_traverser *, void *);
#endif /* rb.h */
glusterfs-3.4.2/contrib/stdlib/ 0000755 0000762 0000763 00000000000 12261516146 013471 5 0000000 0000000 glusterfs-3.4.2/contrib/stdlib/gf_mkostemp.c 0000644 0000762 0000763 00000007255 12261516067 016103 0000000 0000000 /* Borrowed from glibc-2.16/sysdeps/posix/tempname.c */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* Copyright (C) 1991-2001, 2006, 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
. */
static const char letters[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/* Generate a temporary file name based on TMPL. TMPL must match the
rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
*/
int
gf_mkostemp (char *tmpl, int suffixlen, int flags)
{
int len;
char *XXXXXX;
static uint64_t value;
uint64_t random_time_bits;
unsigned int count;
int fd = -1;
/* A lower bound on the number of temporary files to attempt to
generate. The maximum total number of temporary file names that
can exist for a given template is 62**6. It should never be
necessary to try all these combinations. Instead if a reasonable
number of names is tried (we define reasonable as 62**3) fail to
give the system administrator the chance to remove the problems. */
#define ATTEMPTS_MIN (62 * 62 * 62)
/* The number of times to attempt to generate a temporary file. To
conform to POSIX, this must be no smaller than TMP_MAX. */
#if ATTEMPTS_MIN < TMP_MAX
unsigned int attempts = TMP_MAX;
#else
unsigned int attempts = ATTEMPTS_MIN;
#endif
len = strlen (tmpl);
if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen],
"XXXXXX", 6))
return -1;
/* This is where the Xs start. */
XXXXXX = &tmpl[len - 6 - suffixlen];
/* Get some more or less random data. */
# if HAVE_GETTIMEOFDAY
struct timeval tv;
gettimeofday (&tv, NULL);
random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
# else
random_time_bits = time (NULL);
# endif
value += random_time_bits ^ getpid ();
for (count = 0; count < attempts; value += 7777, ++count) {
uint64_t v = value;
/* Fill in the random bits. */
XXXXXX[0] = letters[v % 62];
v /= 62;
XXXXXX[1] = letters[v % 62];
v /= 62;
XXXXXX[2] = letters[v % 62];
v /= 62;
XXXXXX[3] = letters[v % 62];
v /= 62;
XXXXXX[4] = letters[v % 62];
v /= 62;
XXXXXX[5] = letters[v % 62];
fd = open (tmpl, (flags & ~O_ACCMODE)
| O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if (fd >= 0)
return fd;
else if (errno != EEXIST)
return -1;
}
/* We got out of the loop because we ran out of combinations to try. */
return -1;
}
glusterfs-3.4.2/contrib/fuse-include/ 0000755 0000762 0000763 00000000000 12261516155 014573 5 0000000 0000000 glusterfs-3.4.2/contrib/fuse-include/fuse-misc.h 0000644 0000762 0000763 00000000706 12261516067 016564 0000000 0000000 /*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB
*/
#define OFFSET_MAX 0x7fffffffffffffffLL
unsigned long calc_timeout_sec (double t);
unsigned int calc_timeout_nsec (double t);
void convert_fuse_file_lock (struct fuse_file_lock *fl, struct gf_flock *flock,
uint64_t lk_owner);
glusterfs-3.4.2/contrib/fuse-include/fuse-mount.h 0000644 0000762 0000763 00000000745 12261516067 016776 0000000 0000000 /*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi
Copyright (c) 2010 Gluster, Inc.
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB.
*/
void gf_fuse_unmount (const char *mountpoint, int fd);
int gf_fuse_mount (const char *mountpoint, char *fsname,
unsigned long mountflags, char *mnt_param,
pid_t *mtab_pid, int status_fd);
glusterfs-3.4.2/contrib/fuse-include/mount_util.h 0000644 0000762 0000763 00000001221 12261516067 017061 0000000 0000000 /*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB.
*/
#include
int fuse_mnt_add_mount(const char *progname, const char *fsname,
const char *mnt, const char *type, const char *opts);
int fuse_mnt_umount(const char *progname, const char *abs_mnt,
const char *rel_mnt, int lazy);
char *fuse_mnt_resolve_path(const char *progname, const char *orig);
int fuse_mnt_check_empty(const char *progname, const char *mnt,
mode_t rootmode, off_t rootsize);
int fuse_mnt_check_fuseblk(void);
glusterfs-3.4.2/contrib/fuse-include/fuse_kernel.h 0000644 0000762 0000763 00000026665 12261516067 017207 0000000 0000000 /*
This file defines the kernel interface of FUSE
Copyright (C) 2001-2008 Miklos Szeredi
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
This -- and only this -- header file may also be distributed under
the terms of the BSD Licence as follows:
Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/*
* This file defines the kernel interface of FUSE
*
* Protocol changelog:
*
* 7.9:
* - new fuse_getattr_in input argument of GETATTR
* - add lk_flags in fuse_lk_in
* - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
* - add blksize field to fuse_attr
* - add file flags field to fuse_read_in and fuse_write_in
*
* 7.10
* - add nonseekable open flag
*
* 7.11
* - add IOCTL message
* - add unsolicited notification support
* - add POLL message and NOTIFY_POLL notification
*
* 7.12
* - add umask flag to input argument of open, mknod and mkdir
* - add notification messages for invalidation of inodes and
* directory entries
*
* 7.13
* - make max number of background requests and congestion threshold
* tunables
*/
#ifndef _LINUX_FUSE_H
#define _LINUX_FUSE_H
#include
#define __u64 uint64_t
#define __s64 int64_t
#define __u32 uint32_t
#define __s32 int32_t
#define __u16 uint16_t
/** Version number of this interface */
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 13
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
/* Make sure all structures are padded to 64bit boundary, so 32bit
userspace works under 64bit kernels */
struct fuse_attr {
__u64 ino;
__u64 size;
__u64 blocks;
__u64 atime;
__u64 mtime;
__u64 ctime;
__u32 atimensec;
__u32 mtimensec;
__u32 ctimensec;
__u32 mode;
__u32 nlink;
__u32 uid;
__u32 gid;
__u32 rdev;
__u32 blksize;
__u32 padding;
};
struct fuse_kstatfs {
__u64 blocks;
__u64 bfree;
__u64 bavail;
__u64 files;
__u64 ffree;
__u32 bsize;
__u32 namelen;
__u32 frsize;
__u32 padding;
__u32 spare[6];
};
struct fuse_file_lock {
__u64 start;
__u64 end;
__u32 type;
__u32 pid; /* tgid */
};
/**
* Bitmasks for fuse_setattr_in.valid
*/
#define FATTR_MODE (1 << 0)
#define FATTR_UID (1 << 1)
#define FATTR_GID (1 << 2)
#define FATTR_SIZE (1 << 3)
#define FATTR_ATIME (1 << 4)
#define FATTR_MTIME (1 << 5)
#define FATTR_FH (1 << 6)
#define FATTR_ATIME_NOW (1 << 7)
#define FATTR_MTIME_NOW (1 << 8)
#define FATTR_LOCKOWNER (1 << 9)
/**
* Flags returned by the OPEN request
*
* FOPEN_DIRECT_IO: bypass page cache for this open file
* FOPEN_KEEP_CACHE: don't invalidate the data cache on open
* FOPEN_NONSEEKABLE: the file is not seekable
*/
#define FOPEN_DIRECT_IO (1 << 0)
#define FOPEN_KEEP_CACHE (1 << 1)
#define FOPEN_NONSEEKABLE (1 << 2)
/**
* INIT request/reply flags
*
* FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
* FUSE_DONT_MASK: don't apply umask to file mode on create operations
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
#define FUSE_FILE_OPS (1 << 2)
#define FUSE_ATOMIC_O_TRUNC (1 << 3)
#define FUSE_EXPORT_SUPPORT (1 << 4)
#define FUSE_BIG_WRITES (1 << 5)
#define FUSE_DONT_MASK (1 << 6)
#define FUSE_DO_READDIRPLUS (1 << 13)
/**
* CUSE INIT request/reply flags
*
* CUSE_UNRESTRICTED_IOCTL: use unrestricted ioctl
*/
#define CUSE_UNRESTRICTED_IOCTL (1 << 0)
/**
* Release flags
*/
#define FUSE_RELEASE_FLUSH (1 << 0)
/**
* Getattr flags
*/
#define FUSE_GETATTR_FH (1 << 0)
/**
* Lock flags
*/
#define FUSE_LK_FLOCK (1 << 0)
/**
* WRITE flags
*
* FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
* FUSE_WRITE_LOCKOWNER: lock_owner field is valid
*/
#define FUSE_WRITE_CACHE (1 << 0)
#define FUSE_WRITE_LOCKOWNER (1 << 1)
/**
* Read flags
*/
#define FUSE_READ_LOCKOWNER (1 << 1)
/**
* Ioctl flags
*
* FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
* FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
* FUSE_IOCTL_RETRY: retry with new iovecs
*
* FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
*/
#define FUSE_IOCTL_COMPAT (1 << 0)
#define FUSE_IOCTL_UNRESTRICTED (1 << 1)
#define FUSE_IOCTL_RETRY (1 << 2)
#define FUSE_IOCTL_MAX_IOV 256
/**
* Poll flags
*
* FUSE_POLL_SCHEDULE_NOTIFY: request poll notify
*/
#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0)
enum fuse_opcode {
FUSE_LOOKUP = 1,
FUSE_FORGET = 2, /* no reply */
FUSE_GETATTR = 3,
FUSE_SETATTR = 4,
FUSE_READLINK = 5,
FUSE_SYMLINK = 6,
FUSE_MKNOD = 8,
FUSE_MKDIR = 9,
FUSE_UNLINK = 10,
FUSE_RMDIR = 11,
FUSE_RENAME = 12,
FUSE_LINK = 13,
FUSE_OPEN = 14,
FUSE_READ = 15,
FUSE_WRITE = 16,
FUSE_STATFS = 17,
FUSE_RELEASE = 18,
FUSE_FSYNC = 20,
FUSE_SETXATTR = 21,
FUSE_GETXATTR = 22,
FUSE_LISTXATTR = 23,
FUSE_REMOVEXATTR = 24,
FUSE_FLUSH = 25,
FUSE_INIT = 26,
FUSE_OPENDIR = 27,
FUSE_READDIR = 28,
FUSE_RELEASEDIR = 29,
FUSE_FSYNCDIR = 30,
FUSE_GETLK = 31,
FUSE_SETLK = 32,
FUSE_SETLKW = 33,
FUSE_ACCESS = 34,
FUSE_CREATE = 35,
FUSE_INTERRUPT = 36,
FUSE_BMAP = 37,
FUSE_DESTROY = 38,
FUSE_IOCTL = 39,
FUSE_POLL = 40,
FUSE_READDIRPLUS = 44,
/* CUSE specific operations */
CUSE_INIT = 4096,
};
enum fuse_notify_code {
FUSE_NOTIFY_POLL = 1,
FUSE_NOTIFY_INVAL_INODE = 2,
FUSE_NOTIFY_INVAL_ENTRY = 3,
FUSE_NOTIFY_CODE_MAX,
};
/* The read buffer is required to be at least 8k, but may be much larger */
#define FUSE_MIN_READ_BUFFER 8192
#define FUSE_COMPAT_ENTRY_OUT_SIZE 120
struct fuse_entry_out {
__u64 nodeid; /* Inode ID */
__u64 generation; /* Inode generation: nodeid:gen must
be unique for the fs's lifetime */
__u64 entry_valid; /* Cache timeout for the name */
__u64 attr_valid; /* Cache timeout for the attributes */
__u32 entry_valid_nsec;
__u32 attr_valid_nsec;
struct fuse_attr attr;
};
struct fuse_forget_in {
__u64 nlookup;
};
struct fuse_getattr_in {
__u32 getattr_flags;
__u32 dummy;
__u64 fh;
};
#define FUSE_COMPAT_ATTR_OUT_SIZE 96
struct fuse_attr_out {
__u64 attr_valid; /* Cache timeout for the attributes */
__u32 attr_valid_nsec;
__u32 dummy;
struct fuse_attr attr;
};
#define FUSE_COMPAT_MKNOD_IN_SIZE 8
struct fuse_mknod_in {
__u32 mode;
__u32 rdev;
__u32 umask;
__u32 padding;
};
struct fuse_mkdir_in {
__u32 mode;
__u32 umask;
};
struct fuse_rename_in {
__u64 newdir;
};
struct fuse_link_in {
__u64 oldnodeid;
};
struct fuse_setattr_in {
__u32 valid;
__u32 padding;
__u64 fh;
__u64 size;
__u64 lock_owner;
__u64 atime;
__u64 mtime;
__u64 unused2;
__u32 atimensec;
__u32 mtimensec;
__u32 unused3;
__u32 mode;
__u32 unused4;
__u32 uid;
__u32 gid;
__u32 unused5;
};
struct fuse_open_in {
__u32 flags;
__u32 unused;
};
struct fuse_create_in {
__u32 flags;
__u32 mode;
__u32 umask;
__u32 padding;
};
struct fuse_open_out {
__u64 fh;
__u32 open_flags;
__u32 padding;
};
struct fuse_release_in {
__u64 fh;
__u32 flags;
__u32 release_flags;
__u64 lock_owner;
};
struct fuse_flush_in {
__u64 fh;
__u32 unused;
__u32 padding;
__u64 lock_owner;
};
struct fuse_read_in {
__u64 fh;
__u64 offset;
__u32 size;
__u32 read_flags;
__u64 lock_owner;
__u32 flags;
__u32 padding;
};
#define FUSE_COMPAT_WRITE_IN_SIZE 24
struct fuse_write_in {
__u64 fh;
__u64 offset;
__u32 size;
__u32 write_flags;
__u64 lock_owner;
__u32 flags;
__u32 padding;
};
struct fuse_write_out {
__u32 size;
__u32 padding;
};
#define FUSE_COMPAT_STATFS_SIZE 48
struct fuse_statfs_out {
struct fuse_kstatfs st;
};
struct fuse_fsync_in {
__u64 fh;
__u32 fsync_flags;
__u32 padding;
};
struct fuse_setxattr_in {
__u32 size;
__u32 flags;
};
struct fuse_getxattr_in {
__u32 size;
__u32 padding;
};
struct fuse_getxattr_out {
__u32 size;
__u32 padding;
};
struct fuse_lk_in {
__u64 fh;
__u64 owner;
struct fuse_file_lock lk;
__u32 lk_flags;
__u32 padding;
};
struct fuse_lk_out {
struct fuse_file_lock lk;
};
struct fuse_access_in {
__u32 mask;
__u32 padding;
};
struct fuse_init_in {
__u32 major;
__u32 minor;
__u32 max_readahead;
__u32 flags;
};
struct fuse_init_out {
__u32 major;
__u32 minor;
__u32 max_readahead;
__u32 flags;
__u16 max_background;
__u16 congestion_threshold;
__u32 max_write;
};
#define CUSE_INIT_INFO_MAX 4096
struct cuse_init_in {
__u32 major;
__u32 minor;
__u32 unused;
__u32 flags;
};
struct cuse_init_out {
__u32 major;
__u32 minor;
__u32 unused;
__u32 flags;
__u32 max_read;
__u32 max_write;
__u32 dev_major; /* chardev major */
__u32 dev_minor; /* chardev minor */
__u32 spare[10];
};
struct fuse_interrupt_in {
__u64 unique;
};
struct fuse_bmap_in {
__u64 block;
__u32 blocksize;
__u32 padding;
};
struct fuse_bmap_out {
__u64 block;
};
struct fuse_ioctl_in {
__u64 fh;
__u32 flags;
__u32 cmd;
__u64 arg;
__u32 in_size;
__u32 out_size;
};
struct fuse_ioctl_out {
__s32 result;
__u32 flags;
__u32 in_iovs;
__u32 out_iovs;
};
struct fuse_poll_in {
__u64 fh;
__u64 kh;
__u32 flags;
__u32 padding;
};
struct fuse_poll_out {
__u32 revents;
__u32 padding;
};
struct fuse_notify_poll_wakeup_out {
__u64 kh;
};
struct fuse_in_header {
__u32 len;
__u32 opcode;
__u64 unique;
__u64 nodeid;
__u32 uid;
__u32 gid;
__u32 pid;
__u32 padding;
};
struct fuse_out_header {
__u32 len;
__s32 error;
__u64 unique;
};
struct fuse_dirent {
__u64 ino;
__u64 off;
__u32 namelen;
__u32 type;
char name[];
};
#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
#define FUSE_DIRENT_SIZE(d) \
FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
struct fuse_direntplus {
struct fuse_entry_out entry_out;
struct fuse_dirent dirent;
};
#define FUSE_NAME_OFFSET_DIRENTPLUS \
offsetof(struct fuse_direntplus, dirent.name)
#define FUSE_DIRENTPLUS_SIZE(d) \
FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + (d)->dirent.namelen)
struct fuse_notify_inval_inode_out {
__u64 ino;
__s64 off;
__s64 len;
};
struct fuse_notify_inval_entry_out {
__u64 parent;
__u32 namelen;
__u32 padding;
};
#endif /* _LINUX_FUSE_H */
glusterfs-3.4.2/contrib/fuse-include/fuse_kernel_macfuse.h 0000644 0000762 0000763 00000021356 12261516067 020702 0000000 0000000 /*
This file defines the kernel interface of FUSE
Copyright (C) 2001-2007 Miklos Szeredi
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
This -- and only this -- header file may also be distributed under
the terms of the BSD Licence as follows:
Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#ifndef linux
#include
#define __u64 uint64_t
#define __u32 uint32_t
#define __s32 int32_t
#else
#include
#include
#endif
/** Version number of this interface */
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 8
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
/** The major number of the fuse character device */
#define FUSE_MAJOR MISC_MAJOR
/** The minor number of the fuse character device */
#define FUSE_MINOR 229
/* Make sure all structures are padded to 64bit boundary, so 32bit
userspace works under 64bit kernels */
struct fuse_attr {
__u64 ino;
__u64 size;
__u64 blocks;
__u64 atime;
__u64 mtime;
__u64 ctime;
#if (__FreeBSD__ >= 10)
__u64 crtime;
#endif /* __FreeBSD__ >= 10 */
__u32 atimensec;
__u32 mtimensec;
__u32 ctimensec;
#if (__FreeBSD__ >= 10)
__u32 crtimensec;
#endif /* __FreeBSD__ >= 10 */
__u32 mode;
__u32 nlink;
__u32 uid;
__u32 gid;
__u32 rdev;
#if (__FreeBSD__ >= 10)
__u32 flags; /* file flags; see chflags(2) */
#endif /* __FreeBSD__ >= 10 */
};
struct fuse_kstatfs {
__u64 blocks;
__u64 bfree;
__u64 bavail;
__u64 files;
__u64 ffree;
__u32 bsize;
__u32 namelen;
__u32 frsize;
__u32 padding;
__u32 spare[6];
};
struct fuse_file_lock {
__u64 start;
__u64 end;
__u32 type;
__u32 pid; /* tgid */
};
/**
* Bitmasks for fuse_setattr_in.valid
*/
#define FATTR_MODE (1 << 0)
#define FATTR_UID (1 << 1)
#define FATTR_GID (1 << 2)
#define FATTR_SIZE (1 << 3)
#define FATTR_ATIME (1 << 4)
#define FATTR_MTIME (1 << 5)
#define FATTR_FH (1 << 6)
#if (__FreeBSD__ >= 10)
#define FATTR_CRTIME (1 << 28)
#define FATTR_CHGTIME (1 << 29)
#define FATTR_BKUPTIME (1 << 30)
#define FATTR_FLAGS (1 << 31)
#endif /* __FreeBSD__ >= 10 */
/**
* Flags returned by the OPEN request
*
* FOPEN_DIRECT_IO: bypass page cache for this open file
* FOPEN_KEEP_CACHE: don't invalidate the data cache on open
*/
#define FOPEN_DIRECT_IO (1 << 0)
#define FOPEN_KEEP_CACHE (1 << 1)
#if (__FreeBSD__ >= 10)
#define FOPEN_PURGE_ATTR (1 << 30)
#define FOPEN_PURGE_UBC (1 << 31)
#endif
/**
* INIT request/reply flags
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
#if (__FreeBSD__ >= 10)
#define FUSE_CASE_INSENSITIVE (1 << 29)
#define FUSE_VOL_RENAME (1 << 30)
#define FUSE_XTIMES (1 << 31)
#endif /* __FreeBSD__ >= 10 */
/**
* Release flags
*/
#define FUSE_RELEASE_FLUSH (1 << 0)
enum fuse_opcode {
FUSE_LOOKUP = 1,
FUSE_FORGET = 2, /* no reply */
FUSE_GETATTR = 3,
FUSE_SETATTR = 4,
FUSE_READLINK = 5,
FUSE_SYMLINK = 6,
FUSE_MKNOD = 8,
FUSE_MKDIR = 9,
FUSE_UNLINK = 10,
FUSE_RMDIR = 11,
FUSE_RENAME = 12,
FUSE_LINK = 13,
FUSE_OPEN = 14,
FUSE_READ = 15,
FUSE_WRITE = 16,
FUSE_STATFS = 17,
FUSE_RELEASE = 18,
FUSE_FSYNC = 20,
FUSE_SETXATTR = 21,
FUSE_GETXATTR = 22,
FUSE_LISTXATTR = 23,
FUSE_REMOVEXATTR = 24,
FUSE_FLUSH = 25,
FUSE_INIT = 26,
FUSE_OPENDIR = 27,
FUSE_READDIR = 28,
FUSE_RELEASEDIR = 29,
FUSE_FSYNCDIR = 30,
FUSE_GETLK = 31,
FUSE_SETLK = 32,
FUSE_SETLKW = 33,
FUSE_ACCESS = 34,
FUSE_CREATE = 35,
FUSE_INTERRUPT = 36,
FUSE_BMAP = 37,
FUSE_DESTROY = 38,
#if (__FreeBSD__ >= 10)
FUSE_SETVOLNAME = 61,
FUSE_GETXTIMES = 62,
FUSE_EXCHANGE = 63,
#endif /* __FreeBSD__ >= 10 */
};
/* The read buffer is required to be at least 8k, but may be much larger */
#define FUSE_MIN_READ_BUFFER 8192
struct fuse_entry_out {
__u64 nodeid; /* Inode ID */
__u64 generation; /* Inode generation: nodeid:gen must
be unique for the fs's lifetime */
__u64 entry_valid; /* Cache timeout for the name */
__u64 attr_valid; /* Cache timeout for the attributes */
__u32 entry_valid_nsec;
__u32 attr_valid_nsec;
struct fuse_attr attr;
};
struct fuse_forget_in {
__u64 nlookup;
};
struct fuse_attr_out {
__u64 attr_valid; /* Cache timeout for the attributes */
__u32 attr_valid_nsec;
__u32 dummy;
struct fuse_attr attr;
};
#if (__FreeBSD__ >= 10)
struct fuse_getxtimes_out {
__u64 bkuptime;
__u64 crtime;
__u32 bkuptimensec;
__u32 crtimensec;
};
#endif /* __FreeBSD__ >= 10 */
struct fuse_mknod_in {
__u32 mode;
__u32 rdev;
};
struct fuse_mkdir_in {
__u32 mode;
__u32 padding;
};
struct fuse_rename_in {
__u64 newdir;
};
#if (__FreeBSD__ >= 10)
struct fuse_exchange_in {
__u64 olddir;
__u64 newdir;
__u64 options;
};
#endif /* __FreeBSD__ >= 10 */
struct fuse_link_in {
__u64 oldnodeid;
};
struct fuse_setattr_in {
__u32 valid;
__u32 padding;
__u64 fh;
__u64 size;
__u64 unused1;
__u64 atime;
__u64 mtime;
__u64 unused2;
__u32 atimensec;
__u32 mtimensec;
__u32 unused3;
__u32 mode;
__u32 unused4;
__u32 uid;
__u32 gid;
__u32 unused5;
#if (__FreeBSD__ >= 10)
__u64 bkuptime;
__u64 chgtime;
__u64 crtime;
__u32 bkuptimensec;
__u32 chgtimensec;
__u32 crtimensec;
__u32 flags; /* file flags; see chflags(2) */
#endif /* __FreeBSD__ >= 10 */
};
struct fuse_open_in {
__u32 flags;
__u32 mode;
};
struct fuse_open_out {
__u64 fh;
__u32 open_flags;
__u32 padding;
};
struct fuse_release_in {
__u64 fh;
__u32 flags;
__u32 release_flags;
__u64 lock_owner;
};
struct fuse_flush_in {
__u64 fh;
__u32 unused;
__u32 padding;
__u64 lock_owner;
};
struct fuse_read_in {
__u64 fh;
__u64 offset;
__u32 size;
__u32 padding;
};
struct fuse_write_in {
__u64 fh;
__u64 offset;
__u32 size;
__u32 write_flags;
};
struct fuse_write_out {
__u32 size;
__u32 padding;
};
#define FUSE_COMPAT_STATFS_SIZE 48
struct fuse_statfs_out {
struct fuse_kstatfs st;
};
struct fuse_fsync_in {
__u64 fh;
__u32 fsync_flags;
__u32 padding;
};
struct fuse_setxattr_in {
__u32 size;
__u32 flags;
#if (__FreeBSD__ >= 10)
__u32 position;
__u32 padding;
#endif /* __FreeBSD__ >= 10 */
};
struct fuse_getxattr_in {
__u32 size;
__u32 padding;
#if (__FreeBSD__ >= 10)
__u32 position;
__u32 padding2;
#endif /* __FreeBSD__ >= 10 */
};
struct fuse_getxattr_out {
__u32 size;
__u32 padding;
};
struct fuse_lk_in {
__u64 fh;
__u64 owner;
struct fuse_file_lock lk;
};
struct fuse_lk_out {
struct fuse_file_lock lk;
};
struct fuse_access_in {
__u32 mask;
__u32 padding;
};
struct fuse_init_in {
__u32 major;
__u32 minor;
__u32 max_readahead;
__u32 flags;
};
struct fuse_init_out {
__u32 major;
__u32 minor;
__u32 max_readahead;
__u32 flags;
__u32 unused;
__u32 max_write;
};
struct fuse_interrupt_in {
__u64 unique;
};
struct fuse_bmap_in {
__u64 block;
__u32 blocksize;
__u32 padding;
};
struct fuse_bmap_out {
__u64 block;
};
struct fuse_in_header {
__u32 len;
__u32 opcode;
__u64 unique;
__u64 nodeid;
__u32 uid;
__u32 gid;
__u32 pid;
__u32 padding;
};
struct fuse_out_header {
__u32 len;
__s32 error;
__u64 unique;
};
struct fuse_dirent {
__u64 ino;
__u64 off;
__u32 namelen;
__u32 type;
char name[0];
};
#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
#define FUSE_DIRENT_SIZE(d) \
FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
glusterfs-3.4.2/contrib/fuse-util/ 0000755 0000762 0000763 00000000000 12261516156 014126 5 0000000 0000000 glusterfs-3.4.2/contrib/fuse-util/Makefile.am 0000644 0000762 0000763 00000000660 12261516067 016105 0000000 0000000 bin_PROGRAMS = fusermount-glusterfs
fusermount_glusterfs_SOURCES = fusermount.c mount_util.c $(CONTRIBDIR)/fuse-lib/mount-common.c
noinst_HEADERS = $(CONTRIBDIR)/fuse-include/mount_util.h
AM_CPPFLAGS = $(GF_CPPFLAGS) -DFUSE_UTIL -I$(CONTRIBDIR)/fuse-include
AM_CFLAGS = -Wall $(GF_CFLAGS)
install-exec-hook:
-chown root $(DESTDIR)$(bindir)/fusermount-glusterfs
chmod u+s $(DESTDIR)$(bindir)/fusermount-glusterfs
CLEANFILES =
glusterfs-3.4.2/contrib/fuse-util/mount_util.c 0000644 0000762 0000763 00000002460 12261516067 016414 0000000 0000000 /*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB.
*/
#include
#include
#include
#include
#include
#include
int fuse_mnt_check_empty(const char *progname, const char *mnt,
mode_t rootmode, off_t rootsize)
{
int isempty = 1;
if (S_ISDIR(rootmode)) {
struct dirent *ent;
DIR *dp = opendir(mnt);
if (dp == NULL) {
fprintf(stderr,
"%s: failed to open mountpoint for reading: %s\n",
progname, strerror(errno));
return -1;
}
while ((ent = readdir(dp)) != NULL) {
if (strcmp(ent->d_name, ".") != 0 &&
strcmp(ent->d_name, "..") != 0) {
isempty = 0;
break;
}
}
closedir(dp);
} else if (rootsize)
isempty = 0;
if (!isempty) {
fprintf(stderr, "%s: mountpoint is not empty\n", progname);
fprintf(stderr, "%s: if you are sure this is safe, use the 'nonempty' mount option\n", progname);
return -1;
}
return 0;
}
int fuse_mnt_check_fuseblk(void)
{
char buf[256];
FILE *f = fopen("/proc/filesystems", "r");
if (!f)
return 1;
while (fgets(buf, sizeof(buf), f))
if (strstr(buf, "fuseblk\n")) {
fclose(f);
return 1;
}
fclose(f);
return 0;
}
glusterfs-3.4.2/contrib/fuse-util/fusermount.c 0000644 0000762 0000763 00000066570 12261516067 016440 0000000 0000000 /*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
*/
/* This program does the mounting and unmounting of FUSE filesystems */
#include
#include "mount_util.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define FUSE_DEVFD_ENV "_FUSE_DEVFD"
#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
#define FUSE_DEV_OLD "/proc/fs/fuse/dev"
#define FUSE_DEV_NEW "/dev/fuse"
#define FUSE_VERSION_FILE_OLD "/proc/fs/fuse/version"
#define FUSE_CONF "/etc/fuse.conf"
#ifndef MS_DIRSYNC
#define MS_DIRSYNC 128
#endif
#ifndef MS_REC
#define MS_REC 16384
#endif
#ifndef MS_PRIVATE
#define MS_PRIVATE (1<<18)
#endif
static const char *progname;
static int user_allow_other = 0;
static int mount_max = 1000;
static const char *get_user_name(void)
{
struct passwd *pw = getpwuid(getuid());
if (pw != NULL && pw->pw_name != NULL)
return pw->pw_name;
else {
fprintf(stderr, "%s: could not determine username\n", progname);
return NULL;
}
}
static uid_t oldfsuid;
static gid_t oldfsgid;
static void drop_privs(void)
{
if (getuid() != 0) {
oldfsuid = setfsuid(getuid());
oldfsgid = setfsgid(getgid());
}
}
static void restore_privs(void)
{
if (getuid() != 0) {
setfsuid(oldfsuid);
setfsgid(oldfsgid);
}
}
#ifndef IGNORE_MTAB
/*
* Make sure that /etc/mtab is checked and updated atomically
*/
static int lock_umount(void)
{
const char *mtab_lock = _PATH_MOUNTED ".fuselock";
int mtablock;
int res;
struct stat mtab_stat;
/* /etc/mtab could be a symlink to /proc/mounts */
if (lstat(_PATH_MOUNTED, &mtab_stat) == 0 && S_ISLNK(mtab_stat.st_mode))
return -1;
mtablock = open(mtab_lock, O_RDWR | O_CREAT, 0600);
if (mtablock == -1) {
fprintf(stderr, "%s: unable to open fuse lock file: %s\n",
progname, strerror(errno));
return -1;
}
res = lockf(mtablock, F_LOCK, 0);
if (res < 0) {
fprintf(stderr, "%s: error getting lock: %s\n", progname,
strerror(errno));
close(mtablock);
return -1;
}
return mtablock;
}
static void unlock_umount(int mtablock)
{
if (mtablock >= 0) {
int res;
res = lockf(mtablock, F_ULOCK, 0);
if (res < 0) {
fprintf(stderr, "%s: error releasing lock: %s\n",
progname, strerror(errno));
}
close(mtablock);
}
}
static int add_mount(const char *source, const char *mnt, const char *type,
const char *opts)
{
return fuse_mnt_add_mount(progname, source, mnt, type, opts);
}
static int may_unmount(const char *mnt, int quiet)
{
struct mntent *entp;
FILE *fp;
const char *user = NULL;
char uidstr[32];
unsigned uidlen = 0;
int found;
const char *mtab = _PATH_MOUNTED;
user = get_user_name();
if (user == NULL)
return -1;
fp = setmntent(mtab, "r");
if (fp == NULL) {
fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
strerror(errno));
return -1;
}
uidlen = sprintf(uidstr, "%u", getuid());
found = 0;
while ((entp = getmntent(fp)) != NULL) {
if (!found && strcmp(entp->mnt_dir, mnt) == 0 &&
(strcmp(entp->mnt_type, "fuse") == 0 ||
strcmp(entp->mnt_type, "fuseblk") == 0 ||
strncmp(entp->mnt_type, "fuse.", 5) == 0 ||
strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) {
char *p = strstr(entp->mnt_opts, "user=");
if (p &&
(p == entp->mnt_opts || *(p-1) == ',') &&
strcmp(p + 5, user) == 0) {
found = 1;
break;
}
/* /etc/mtab is a link pointing to
/proc/mounts: */
else if ((p =
strstr(entp->mnt_opts, "user_id=")) &&
(p == entp->mnt_opts ||
*(p-1) == ',') &&
strncmp(p + 8, uidstr, uidlen) == 0 &&
(*(p+8+uidlen) == ',' ||
*(p+8+uidlen) == '\0')) {
found = 1;
break;
}
}
}
endmntent(fp);
if (!found) {
if (!quiet)
fprintf(stderr,
"%s: entry for %s not found in %s\n",
progname, mnt, mtab);
return -1;
}
return 0;
}
/*
* Check whether the file specified in "fusermount -u" is really a
* mountpoint and not a symlink. This is necessary otherwise the user
* could move the mountpoint away and replace it with a symlink
* pointing to an arbitrary mount, thereby tricking fusermount into
* unmounting that (umount(2) will follow symlinks).
*
* This is the child process running in a separate mount namespace, so
* we don't mess with the global namespace and if the process is
* killed for any reason, mounts are automatically cleaned up.
*
* First make sure nothing is propagated back into the parent
* namespace by marking all mounts "private".
*
* Then bind mount parent onto a stable base where the user can't move
* it around.
*
* Finally check /proc/mounts for an entry matching the requested
* mountpoint. If it's found then we are OK, and the user can't move
* it around within the parent directory as rename() will return
* EBUSY. Be careful to ignore any mounts that existed before the
* bind.
*/
static int check_is_mount_child(void *p)
{
const char **a = p;
const char *last = a[0];
const char *mnt = a[1];
int res;
const char *procmounts = "/proc/mounts";
int found;
FILE *fp;
struct mntent *entp;
int count;
res = mount("", "/", "", MS_PRIVATE | MS_REC, NULL);
if (res == -1) {
fprintf(stderr, "%s: failed to mark mounts private: %s\n",
progname, strerror(errno));
return 1;
}
fp = setmntent(procmounts, "r");
if (fp == NULL) {
fprintf(stderr, "%s: failed to open %s: %s\n", progname,
procmounts, strerror(errno));
return 1;
}
count = 0;
while (getmntent(fp) != NULL)
count++;
endmntent(fp);
fp = setmntent(procmounts, "r");
if (fp == NULL) {
fprintf(stderr, "%s: failed to open %s: %s\n", progname,
procmounts, strerror(errno));
return 1;
}
res = mount(".", "/", "", MS_BIND | MS_REC, NULL);
if (res == -1) {
fprintf(stderr, "%s: failed to bind parent to /: %s\n",
progname, strerror(errno));
return 1;
}
found = 0;
while ((entp = getmntent(fp)) != NULL) {
if (count > 0) {
count--;
continue;
}
if (entp->mnt_dir[0] == '/' &&
strcmp(entp->mnt_dir + 1, last) == 0) {
found = 1;
break;
}
}
endmntent(fp);
if (!found) {
fprintf(stderr, "%s: %s not mounted\n", progname, mnt);
return 1;
}
return 0;
}
static pid_t clone_newns(void *a)
{
char buf[131072];
char *stack = buf + (sizeof(buf) / 2 - ((size_t) buf & 15));
#ifdef __ia64__
extern int __clone2(int (*fn)(void *),
void *child_stack_base, size_t stack_size,
int flags, void *arg, pid_t *ptid,
void *tls, pid_t *ctid);
return __clone2(check_is_mount_child, stack, sizeof(buf) / 2,
CLONE_NEWNS, a, NULL, NULL, NULL);
#else
return clone(check_is_mount_child, stack, CLONE_NEWNS, a);
#endif
}
static int check_is_mount(const char *last, const char *mnt)
{
pid_t pid, p;
int status;
const char *a[2] = { last, mnt };
pid = clone_newns((void *) a);
if (pid == (pid_t) -1) {
fprintf(stderr, "%s: failed to clone namespace: %s\n",
progname, strerror(errno));
return -1;
}
p = waitpid(pid, &status, __WCLONE);
if (p == (pid_t) -1) {
fprintf(stderr, "%s: waitpid failed: %s\n",
progname, strerror(errno));
return -1;
}
if (!WIFEXITED(status)) {
fprintf(stderr, "%s: child terminated abnormally (status %i)\n",
progname, status);
return -1;
}
if (WEXITSTATUS(status) != 0)
return -1;
return 0;
}
static int chdir_to_parent(char *copy, const char **lastp)
{
char *tmp;
const char *parent;
char buf[65536];
int res;
tmp = strrchr(copy, '/');
if (tmp == NULL || tmp[1] == '\0') {
fprintf(stderr, "%s: internal error: invalid abs path: <%s>\n",
progname, copy);
return -1;
}
if (tmp != copy) {
*tmp = '\0';
parent = copy;
*lastp = tmp + 1;
} else if (tmp[1] != '\0') {
*lastp = tmp + 1;
parent = "/";
} else {
*lastp = ".";
parent = "/";
}
res = chdir(parent);
if (res == -1) {
fprintf(stderr, "%s: failed to chdir to %s: %s\n",
progname, parent, strerror(errno));
return -1;
}
if (getcwd(buf, sizeof(buf)) == NULL) {
fprintf(stderr, "%s: failed to obtain current directory: %s\n",
progname, strerror(errno));
return -1;
}
if (strcmp(buf, parent) != 0) {
fprintf(stderr, "%s: mountpoint moved (%s -> %s)\n", progname,
parent, buf);
return -1;
}
return 0;
}
static int unmount_fuse_locked(const char *mnt, int quiet, int lazy)
{
char *copy;
const char *last;
int res;
if (getuid() != 0) {
res = may_unmount(mnt, quiet);
if (res == -1)
return -1;
}
copy = strdup(mnt);
if (copy == NULL) {
fprintf(stderr, "%s: failed to allocate memory\n", progname);
return -1;
}
res = chdir_to_parent(copy, &last);
if (res == -1)
goto out;
res = check_is_mount(last, mnt);
if (res == -1)
goto out;
res = fuse_mnt_umount(progname, mnt, last, lazy);
out:
free(copy);
return res;
}
static int unmount_fuse(const char *mnt, int quiet, int lazy)
{
int res;
int mtablock = lock_umount();
res = unmount_fuse_locked(mnt, quiet, lazy);
unlock_umount(mtablock);
return res;
}
static int count_fuse_fs(void)
{
struct mntent *entp;
int count = 0;
const char *mtab = _PATH_MOUNTED;
FILE *fp = setmntent(mtab, "r");
if (fp == NULL) {
fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
strerror(errno));
return -1;
}
while ((entp = getmntent(fp)) != NULL) {
if (strcmp(entp->mnt_type, "fuse") == 0 ||
strncmp(entp->mnt_type, "fuse.", 5) == 0)
count ++;
}
endmntent(fp);
return count;
}
#else /* IGNORE_MTAB */
static int count_fuse_fs()
{
return 0;
}
static int add_mount(const char *source, const char *mnt, const char *type,
const char *opts)
{
(void) source;
(void) mnt;
(void) type;
(void) opts;
return 0;
}
static int unmount_fuse(const char *mnt, int quiet, int lazy)
{
return fuse_mnt_umount(progname, mnt, mnt, lazy);
}
#endif /* IGNORE_MTAB */
static void strip_line(char *line)
{
char *s = strchr(line, '#');
if (s != NULL)
s[0] = '\0';
for (s = line + strlen(line) - 1;
s >= line && isspace((unsigned char) *s); s--);
s[1] = '\0';
for (s = line; isspace((unsigned char) *s); s++);
if (s != line)
memmove(line, s, strlen(s)+1);
}
static void parse_line(char *line, int linenum)
{
int tmp;
if (strcmp(line, "user_allow_other") == 0)
user_allow_other = 1;
else if (sscanf(line, "mount_max = %i", &tmp) == 1)
mount_max = tmp;
else if(line[0])
fprintf(stderr,
"%s: unknown parameter in %s at line %i: '%s'\n",
progname, FUSE_CONF, linenum, line);
}
static void read_conf(void)
{
FILE *fp = fopen(FUSE_CONF, "r");
if (fp != NULL) {
int linenum = 1;
char line[256];
int isnewline = 1;
while (fgets(line, sizeof(line), fp) != NULL) {
if (isnewline) {
if (strlen(line) && line[strlen(line)-1] == '\n') {
strip_line(line);
parse_line(line, linenum);
} else {
isnewline = 0;
}
} else if(strlen(line) && line[strlen(line)-1] == '\n') {
fprintf(stderr, "%s: reading %s: line %i too long\n", progname, FUSE_CONF, linenum);
isnewline = 1;
}
if (isnewline)
linenum ++;
}
if (!isnewline) {
fprintf(stderr, "%s: reading %s: missing newline at end of file\n", progname, FUSE_CONF);
}
fclose(fp);
} else if (errno != ENOENT) {
fprintf(stderr, "%s: failed to open %s: %s\n",
progname, FUSE_CONF, strerror(errno));
}
}
static int begins_with(const char *s, const char *beg)
{
if (strncmp(s, beg, strlen(beg)) == 0)
return 1;
else
return 0;
}
struct mount_flags {
const char *opt;
unsigned long flag;
int on;
int safe;
};
static struct mount_flags mount_flags[] = {
{"rw", MS_RDONLY, 0, 1},
{"ro", MS_RDONLY, 1, 1},
{"suid", MS_NOSUID, 0, 0},
{"nosuid", MS_NOSUID, 1, 1},
{"dev", MS_NODEV, 0, 0},
{"nodev", MS_NODEV, 1, 1},
{"exec", MS_NOEXEC, 0, 1},
{"noexec", MS_NOEXEC, 1, 1},
{"async", MS_SYNCHRONOUS, 0, 1},
{"sync", MS_SYNCHRONOUS, 1, 1},
{"atime", MS_NOATIME, 0, 1},
{"noatime", MS_NOATIME, 1, 1},
{"dirsync", MS_DIRSYNC, 1, 1},
{NULL, 0, 0, 0}
};
static int find_mount_flag(const char *s, unsigned len, int *on, int *flag)
{
int i;
for (i = 0; mount_flags[i].opt != NULL; i++) {
const char *opt = mount_flags[i].opt;
if (strlen(opt) == len && strncmp(opt, s, len) == 0) {
*on = mount_flags[i].on;
*flag = mount_flags[i].flag;
if (!mount_flags[i].safe && getuid() != 0) {
*flag = 0;
fprintf(stderr,
"%s: unsafe option %s ignored\n",
progname, opt);
}
return 1;
}
}
return 0;
}
static int add_option(char **optsp, const char *opt, unsigned expand)
{
char *newopts;
if (*optsp == NULL)
newopts = strdup(opt);
else {
unsigned oldsize = strlen(*optsp);
unsigned newsize = oldsize + 1 + strlen(opt) + expand + 1;
newopts = (char *) realloc(*optsp, newsize);
if (newopts)
sprintf(newopts + oldsize, ",%s", opt);
}
if (newopts == NULL) {
fprintf(stderr, "%s: failed to allocate memory\n", progname);
return -1;
}
*optsp = newopts;
return 0;
}
static int get_mnt_opts(int flags, char *opts, char **mnt_optsp)
{
int i;
size_t l;
if (!(flags & MS_RDONLY) && add_option(mnt_optsp, "rw", 0) == -1)
return -1;
for (i = 0; mount_flags[i].opt != NULL; i++) {
if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
add_option(mnt_optsp, mount_flags[i].opt, 0) == -1)
return -1;
}
if (add_option(mnt_optsp, opts, 0) == -1)
return -1;
/* remove comma from end of opts*/
l = strlen(*mnt_optsp);
if (l && (*mnt_optsp)[l-1] == ',')
(*mnt_optsp)[l-1] = '\0';
if (getuid() != 0) {
const char *user = get_user_name();
if (user == NULL)
return -1;
if (add_option(mnt_optsp, "user=", strlen(user)) == -1)
return -1;
strcat(*mnt_optsp, user);
}
return 0;
}
static int opt_eq(const char *s, unsigned len, const char *opt)
{
if(strlen(opt) == len && strncmp(s, opt, len) == 0)
return 1;
else
return 0;
}
static int get_string_opt(const char *s, unsigned len, const char *opt,
char **val)
{
int i;
unsigned opt_len = strlen(opt);
char *d;
free(*val);
*val = (char *) malloc(len - opt_len + 1);
if (!*val) {
fprintf(stderr, "%s: failed to allocate memory\n", progname);
return 0;
}
d = *val;
s += opt_len;
len -= opt_len;
for (i = 0; i < len; i++) {
if (s[i] == '\\' && i + 1 < len)
i++;
*d++ = s[i];
}
*d = '\0';
return 1;
}
static int do_mount(const char *mnt, char **typep, mode_t rootmode,
int fd, const char *opts, const char *dev, char **sourcep,
char **mnt_optsp, off_t rootsize)
{
int res;
int flags = MS_NOSUID | MS_NODEV;
char *optbuf;
char *mnt_opts = NULL;
const char *s;
char *d;
char *fsname = NULL;
char *subtype = NULL;
char *source = NULL;
char *type = NULL;
int check_empty = 1;
int blkdev = 0;
optbuf = (char *) malloc(strlen(opts) + 128);
if (!optbuf) {
fprintf(stderr, "%s: failed to allocate memory\n", progname);
return -1;
}
for (s = opts, d = optbuf; *s;) {
unsigned len;
const char *fsname_str = "fsname=";
const char *subtype_str = "subtype=";
for (len = 0; s[len]; len++) {
if (s[len] == '\\' && s[len + 1])
len++;
else if (s[len] == ',')
break;
}
if (begins_with(s, fsname_str)) {
if (!get_string_opt(s, len, fsname_str, &fsname))
goto err;
} else if (begins_with(s, subtype_str)) {
if (!get_string_opt(s, len, subtype_str, &subtype))
goto err;
} else if (opt_eq(s, len, "blkdev")) {
if (getuid() != 0) {
fprintf(stderr,
"%s: option blkdev is privileged\n",
progname);
goto err;
}
blkdev = 1;
} else if (opt_eq(s, len, "nonempty")) {
check_empty = 0;
} else if (!begins_with(s, "fd=") &&
!begins_with(s, "rootmode=") &&
!begins_with(s, "user_id=") &&
!begins_with(s, "group_id=")) {
int on;
int flag;
int skip_option = 0;
if (opt_eq(s, len, "large_read")) {
struct utsname utsname;
unsigned kmaj, kmin;
res = uname(&utsname);
if (res == 0 &&
sscanf(utsname.release, "%u.%u",
&kmaj, &kmin) == 2 &&
(kmaj > 2 || (kmaj == 2 && kmin > 4))) {
fprintf(stderr, "%s: note: 'large_read' mount option is deprecated for %i.%i kernels\n", progname, kmaj, kmin);
skip_option = 1;
}
}
if (getuid() != 0 && !user_allow_other &&
(opt_eq(s, len, "allow_other") ||
opt_eq(s, len, "allow_root"))) {
fprintf(stderr, "%s: option %.*s only allowed if 'user_allow_other' is set in /etc/fuse.conf\n", progname, len, s);
goto err;
}
if (!skip_option) {
if (find_mount_flag(s, len, &on, &flag)) {
if (on)
flags |= flag;
else
flags &= ~flag;
} else {
memcpy(d, s, len);
d += len;
*d++ = ',';
}
}
}
s += len;
if (*s)
s++;
}
*d = '\0';
res = get_mnt_opts(flags, optbuf, &mnt_opts);
if (res == -1)
goto err;
sprintf(d, "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
fd, rootmode, getuid(), getgid());
if (check_empty &&
fuse_mnt_check_empty(progname, mnt, rootmode, rootsize) == -1)
goto err;
source = malloc((fsname ? strlen(fsname) : 0) +
(subtype ? strlen(subtype) : 0) + strlen(dev) + 32);
type = malloc((subtype ? strlen(subtype) : 0) + 32);
if (!type || !source) {
fprintf(stderr, "%s: failed to allocate memory\n", progname);
goto err;
}
if (subtype)
sprintf(type, "%s.%s", blkdev ? "fuseblk" : "fuse", subtype);
else
strcpy(type, blkdev ? "fuseblk" : "fuse");
if (fsname)
strcpy(source, fsname);
else
strcpy(source, subtype ? subtype : dev);
res = mount(source, mnt, type, flags, optbuf);
if (res == -1 && errno == ENODEV && subtype) {
/* Probably missing subtype support */
strcpy(type, blkdev ? "fuseblk" : "fuse");
if (fsname) {
if (!blkdev)
sprintf(source, "%s#%s", subtype, fsname);
} else {
strcpy(source, type);
}
res = mount(source, mnt, type, flags, optbuf);
}
if (res == -1 && errno == EINVAL) {
/* It could be an old version not supporting group_id */
sprintf(d, "fd=%i,rootmode=%o,user_id=%i",
fd, rootmode, getuid());
res = mount(source, mnt, type, flags, optbuf);
}
if (res == -1) {
int errno_save = errno;
if (blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
fprintf(stderr, "%s: 'fuseblk' support missing\n",
progname);
else
fprintf(stderr, "%s: mount failed: %s\n", progname,
strerror(errno_save));
goto err;
}
*sourcep = source;
*typep = type;
*mnt_optsp = mnt_opts;
free(fsname);
free(optbuf);
return 0;
err:
free(fsname);
free(subtype);
free(source);
free(type);
free(mnt_opts);
free(optbuf);
return -1;
}
static int check_version(const char *dev)
{
int res;
int majorver;
int minorver;
const char *version_file;
FILE *vf;
if (strcmp(dev, FUSE_DEV_OLD) != 0)
return 0;
version_file = FUSE_VERSION_FILE_OLD;
vf = fopen(version_file, "r");
if (vf == NULL) {
fprintf(stderr, "%s: kernel interface too old\n", progname);
return -1;
}
res = fscanf(vf, "%i.%i", &majorver, &minorver);
fclose(vf);
if (res != 2) {
fprintf(stderr, "%s: error reading %s\n", progname,
version_file);
return -1;
}
if (majorver < 3) {
fprintf(stderr, "%s: kernel interface too old\n", progname);
return -1;
}
return 0;
}
static int check_perm(const char **mntp, struct stat *stbuf, int *mountpoint_fd)
{
int res;
const char *mnt = *mntp;
const char *origmnt = mnt;
res = lstat(mnt, stbuf);
if (res == -1) {
fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
progname, mnt, strerror(errno));
return -1;
}
/* No permission checking is done for root */
if (getuid() == 0)
return 0;
if (S_ISDIR(stbuf->st_mode)) {
res = chdir(mnt);
if (res == -1) {
fprintf(stderr,
"%s: failed to chdir to mountpoint: %s\n",
progname, strerror(errno));
return -1;
}
mnt = *mntp = ".";
res = lstat(mnt, stbuf);
if (res == -1) {
fprintf(stderr,
"%s: failed to access mountpoint %s: %s\n",
progname, origmnt, strerror(errno));
return -1;
}
if ((stbuf->st_mode & S_ISVTX) && stbuf->st_uid != getuid()) {
fprintf(stderr, "%s: mountpoint %s not owned by user\n",
progname, origmnt);
return -1;
}
res = access(mnt, W_OK);
if (res == -1) {
fprintf(stderr, "%s: user has no write access to mountpoint %s\n",
progname, origmnt);
return -1;
}
} else if (S_ISREG(stbuf->st_mode)) {
static char procfile[256];
*mountpoint_fd = open(mnt, O_WRONLY);
if (*mountpoint_fd == -1) {
fprintf(stderr, "%s: failed to open %s: %s\n",
progname, mnt, strerror(errno));
return -1;
}
res = fstat(*mountpoint_fd, stbuf);
if (res == -1) {
fprintf(stderr,
"%s: failed to access mountpoint %s: %s\n",
progname, mnt, strerror(errno));
return -1;
}
if (!S_ISREG(stbuf->st_mode)) {
fprintf(stderr,
"%s: mountpoint %s is no longer a regular file\n",
progname, mnt);
return -1;
}
sprintf(procfile, "/proc/self/fd/%i", *mountpoint_fd);
*mntp = procfile;
} else {
fprintf(stderr,
"%s: mountpoint %s is not a directory or a regular file\n",
progname, mnt);
return -1;
}
return 0;
}
static int try_open(const char *dev, char **devp, int silent)
{
int fd = open(dev, O_RDWR);
if (fd != -1) {
*devp = strdup(dev);
if (*devp == NULL) {
fprintf(stderr, "%s: failed to allocate memory\n",
progname);
close(fd);
fd = -1;
}
} else if (errno == ENODEV ||
errno == ENOENT)/* check for ENOENT too, for the udev case */
return -2;
else if (!silent) {
fprintf(stderr, "%s: failed to open %s: %s\n", progname, dev,
strerror(errno));
}
return fd;
}
static int try_open_fuse_device(char **devp)
{
int fd;
int err;
drop_privs();
fd = try_open(FUSE_DEV_NEW, devp, 0);
restore_privs();
if (fd >= 0)
return fd;
err = fd;
fd = try_open(FUSE_DEV_OLD, devp, 1);
if (fd >= 0)
return fd;
return err;
}
static int open_fuse_device(char **devp)
{
int fd = try_open_fuse_device(devp);
if (fd >= -1)
return fd;
fprintf(stderr,
"%s: fuse device not found, try 'modprobe fuse' first\n",
progname);
return -1;
}
static int check_fuse_device(char *devfd, char **devp)
{
int res;
char *devlink;
res = asprintf(&devlink, "/proc/self/fd/%s", devfd);
if (res == -1) {
fprintf(stderr, "%s: failed to allocate memory\n", progname);
return -1;
}
*devp = (char *) calloc(1, PATH_MAX + 1);
if (!*devp) {
fprintf(stderr, "%s: failed to allocate memory\n", progname);
free(devlink);
return -1;
}
res = readlink (devlink, *devp, PATH_MAX);
free (devlink);
if (res == -1) {
fprintf(stderr, "%s: specified fuse fd is invalid\n",
progname);
return -1;
}
return atoi(devfd);
}
static int mount_fuse(const char *mnt, const char *opts, char *devfd)
{
int res;
int fd;
char *dev;
struct stat stbuf;
char *type = NULL;
char *source = NULL;
char *mnt_opts = NULL;
const char *real_mnt = mnt;
int mountpoint_fd = -1;
fd = devfd ? check_fuse_device(devfd, &dev) : open_fuse_device(&dev);
if (fd == -1)
return -1;
drop_privs();
read_conf();
if (getuid() != 0 && mount_max != -1) {
int mount_count = count_fuse_fs();
if (mount_count >= mount_max) {
fprintf(stderr, "%s: too many FUSE filesystems mounted; mount_max=N can be set in /etc/fuse.conf\n", progname);
goto fail_close_fd;
}
}
res = check_version(dev);
if (res != -1) {
res = check_perm(&real_mnt, &stbuf, &mountpoint_fd);
restore_privs();
if (res != -1)
res = do_mount(real_mnt, &type, stbuf.st_mode & S_IFMT,
fd, opts, dev, &source, &mnt_opts,
stbuf.st_size);
} else
restore_privs();
if (mountpoint_fd != -1)
close(mountpoint_fd);
if (res == -1)
goto fail_close_fd;
res = chdir("/");
if (res == -1) {
fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
goto fail_close_fd;
}
if (geteuid() == 0) {
res = add_mount(source, mnt, type, mnt_opts);
if (res == -1) {
/* Can't clean up mount in a non-racy way */
goto fail_close_fd;
}
}
out_free:
free(source);
free(type);
free(mnt_opts);
free(dev);
return fd;
fail_close_fd:
close(fd);
fd = -1;
goto out_free;
}
static int send_fd(int sock_fd, int fd)
{
int retval;
struct msghdr msg;
struct cmsghdr *p_cmsg;
struct iovec vec;
size_t cmsgbuf[CMSG_SPACE(sizeof(fd)) / sizeof(size_t)];
int *p_fds;
char sendchar = 0;
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
p_cmsg = CMSG_FIRSTHDR(&msg);
p_cmsg->cmsg_level = SOL_SOCKET;
p_cmsg->cmsg_type = SCM_RIGHTS;
p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
p_fds = (int *) CMSG_DATA(p_cmsg);
*p_fds = fd;
msg.msg_controllen = p_cmsg->cmsg_len;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &vec;
msg.msg_iovlen = 1;
msg.msg_flags = 0;
/* "To pass file descriptors or credentials you need to send/read at
* least one byte" (man 7 unix) */
vec.iov_base = &sendchar;
vec.iov_len = sizeof(sendchar);
while ((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
if (retval != 1) {
perror("sending file descriptor");
return -1;
}
return 0;
}
static void usage(void)
{
fprintf(stderr,
"%s: [options] mountpoint\n"
"Options:\n"
" -h print help\n"
" -V print version\n"
" -o opt[,opt...] mount options\n"
" -u unmount\n"
" -q quiet\n"
" -z lazy unmount\n",
progname);
exit(1);
}
static void show_version(void)
{
printf("fusermount version: %s\n", PACKAGE_VERSION);
exit(0);
}
int main(int argc, char *argv[])
{
int ch;
int fd;
int res;
char *origmnt;
char *mnt;
static int unmount = 0;
static int lazy = 0;
static int quiet = 0;
char *devfd;
char *commfd;
int cfd;
const char *opts = "";
static const struct option long_opts[] = {
{"unmount", no_argument, NULL, 'u'},
{"lazy", no_argument, NULL, 'z'},
{"quiet", no_argument, NULL, 'q'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'V'},
{0, 0, 0, 0}};
progname = strdup(argv[0]);
if (progname == NULL) {
fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
exit(1);
}
while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts,
NULL)) != -1) {
switch (ch) {
case 'h':
usage();
break;
case 'V':
show_version();
break;
case 'o':
opts = optarg;
break;
case 'u':
unmount = 1;
break;
case 'z':
lazy = 1;
break;
case 'q':
quiet = 1;
break;
default:
exit(1);
}
}
if (lazy && !unmount) {
fprintf(stderr, "%s: -z can only be used with -u\n", progname);
exit(1);
}
if (optind >= argc) {
fprintf(stderr, "%s: missing mountpoint argument\n", progname);
exit(1);
} else if (argc > optind + 1) {
fprintf(stderr, "%s: extra arguments after the mountpoint\n",
progname);
exit(1);
}
origmnt = argv[optind];
drop_privs();
mnt = fuse_mnt_resolve_path(progname, origmnt);
if (mnt != NULL) {
res = chdir("/");
if (res == -1) {
fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
exit(1);
}
}
restore_privs();
if (mnt == NULL)
exit(1);
umask(033);
if (unmount) {
if (geteuid() == 0)
res = unmount_fuse(mnt, quiet, lazy);
else {
res = umount2(mnt, lazy ? 2 : 0);
if (res == -1 && !quiet)
fprintf(stderr,
"%s: failed to unmount %s: %s\n",
progname, mnt, strerror(errno));
}
if (res == -1)
exit(1);
return 0;
}
devfd = getenv(FUSE_DEVFD_ENV);
if (devfd == NULL) {
commfd = getenv(FUSE_COMMFD_ENV);
if (commfd == NULL) {
fprintf(stderr, "%s: old style mounting not supported\n",
progname);
exit(1);
}
}
fd = mount_fuse(mnt, opts, devfd);
if (fd == -1)
exit(1);
if (devfd == NULL) {
cfd = atoi(commfd);
res = send_fd(cfd, fd);
if (res == -1)
exit(1);
}
return 0;
}
glusterfs-3.4.2/contrib/fuse-util/Makefile.in 0000644 0000762 0000763 00000051450 12261516077 016122 0000000 0000000 # Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = fusermount-glusterfs$(EXEEXT)
subdir = contrib/fuse-util
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in COPYING
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/contrib/aclocal/mkdirp.m4 \
$(top_srcdir)/contrib/aclocal/python.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am_fusermount_glusterfs_OBJECTS = fusermount.$(OBJEXT) \
mount_util.$(OBJEXT) mount-common.$(OBJEXT)
fusermount_glusterfs_OBJECTS = $(am_fusermount_glusterfs_OBJECTS)
fusermount_glusterfs_LDADD = $(LDADD)
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_$(V))
am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
am__v_CC_0 = @echo " CC " $@;
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_$(V))
am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
am__v_CCLD_0 = @echo " CCLD " $@;
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(fusermount_glusterfs_SOURCES)
DIST_SOURCES = $(fusermount_glusterfs_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AM_LIBTOOLFLAGS = @AM_LIBTOOLFLAGS@
AM_MAKEFLAGS = @AM_MAKEFLAGS@
AR = @AR@
ARGP_STANDALONE_CPPFLAGS = @ARGP_STANDALONE_CPPFLAGS@
ARGP_STANDALONE_LDADD = @ARGP_STANDALONE_LDADD@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONTRIBDIR = @CONTRIBDIR@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DTRACE = @DTRACE@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FUSERMOUNT_SUBDIR = @FUSERMOUNT_SUBDIR@
FUSE_CLIENT_SUBDIR = @FUSE_CLIENT_SUBDIR@
GF_CFLAGS = @GF_CFLAGS@
GF_CPPFLAGS = @GF_CPPFLAGS@
GF_DISTRIBUTION = @GF_DISTRIBUTION@
GF_FUSE_CFLAGS = @GF_FUSE_CFLAGS@
GF_FUSE_LDADD = @GF_FUSE_LDADD@
GF_GLUSTERFS_CFLAGS = @GF_GLUSTERFS_CFLAGS@
GF_GLUSTERFS_LIBS = @GF_GLUSTERFS_LIBS@
GF_HOST_OS = @GF_HOST_OS@
GF_LDADD = @GF_LDADD@
GF_LDFLAGS = @GF_LDFLAGS@
GREP = @GREP@
HAVE_BACKTRACE = @HAVE_BACKTRACE@
HAVE_LINKAT = @HAVE_LINKAT@
HAVE_MALLOC_STATS = @HAVE_MALLOC_STATS@
HAVE_SPINLOCK = @HAVE_SPINLOCK@
HAVE_STRNLEN = @HAVE_STRNLEN@
IBVERBS_SUBDIR = @IBVERBS_SUBDIR@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBAIO = @LIBAIO@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
LIBXML2_LIBS = @LIBXML2_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OCF_SUBDIR = @OCF_SUBDIR@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PYTHON = @PYTHON@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
RDMA_SUBDIR = @RDMA_SUBDIR@
RLLIBS = @RLLIBS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SIZEOF_INT = @SIZEOF_INT@
SIZEOF_LONG = @SIZEOF_LONG@
SIZEOF_LONG_LONG = @SIZEOF_LONG_LONG@
SIZEOF_SHORT = @SIZEOF_SHORT@
STRIP = @STRIP@
SYNCDAEMON_COMPILE = @SYNCDAEMON_COMPILE@
SYNCDAEMON_SUBDIR = @SYNCDAEMON_SUBDIR@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
initdir = @initdir@
install_sh = @install_sh@
launchddir = @launchddir@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
mountutildir = @mountutildir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgconfigdir = @pkgconfigdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
systemddir = @systemddir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
fusermount_glusterfs_SOURCES = fusermount.c mount_util.c $(CONTRIBDIR)/fuse-lib/mount-common.c
noinst_HEADERS = $(CONTRIBDIR)/fuse-include/mount_util.h
AM_CPPFLAGS = $(GF_CPPFLAGS) -DFUSE_UTIL -I$(CONTRIBDIR)/fuse-include
AM_CFLAGS = -Wall $(GF_CFLAGS)
CLEANFILES =
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign contrib/fuse-util/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign contrib/fuse-util/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p || test -f $$p1; \
then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' `; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
clean-binPROGRAMS:
@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
fusermount-glusterfs$(EXEEXT): $(fusermount_glusterfs_OBJECTS) $(fusermount_glusterfs_DEPENDENCIES)
@rm -f fusermount-glusterfs$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(fusermount_glusterfs_OBJECTS) $(fusermount_glusterfs_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fusermount.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount-common.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount_util.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
mount-common.o: $(CONTRIBDIR)/fuse-lib/mount-common.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mount-common.o -MD -MP -MF $(DEPDIR)/mount-common.Tpo -c -o mount-common.o `test -f '$(CONTRIBDIR)/fuse-lib/mount-common.c' || echo '$(srcdir)/'`$(CONTRIBDIR)/fuse-lib/mount-common.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mount-common.Tpo $(DEPDIR)/mount-common.Po
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(CONTRIBDIR)/fuse-lib/mount-common.c' object='mount-common.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mount-common.o `test -f '$(CONTRIBDIR)/fuse-lib/mount-common.c' || echo '$(srcdir)/'`$(CONTRIBDIR)/fuse-lib/mount-common.c
mount-common.obj: $(CONTRIBDIR)/fuse-lib/mount-common.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mount-common.obj -MD -MP -MF $(DEPDIR)/mount-common.Tpo -c -o mount-common.obj `if test -f '$(CONTRIBDIR)/fuse-lib/mount-common.c'; then $(CYGPATH_W) '$(CONTRIBDIR)/fuse-lib/mount-common.c'; else $(CYGPATH_W) '$(srcdir)/$(CONTRIBDIR)/fuse-lib/mount-common.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mount-common.Tpo $(DEPDIR)/mount-common.Po
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(CONTRIBDIR)/fuse-lib/mount-common.c' object='mount-common.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mount-common.obj `if test -f '$(CONTRIBDIR)/fuse-lib/mount-common.c'; then $(CYGPATH_W) '$(CONTRIBDIR)/fuse-lib/mount-common.c'; else $(CYGPATH_W) '$(srcdir)/$(CONTRIBDIR)/fuse-lib/mount-common.c'; fi`
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-binPROGRAMS
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS
.MAKE: install-am install-exec-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
clean-generic clean-libtool ctags distclean distclean-compile \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-binPROGRAMS install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-exec-hook \
install-html install-html-am install-info install-info-am \
install-man install-pdf install-pdf-am install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-binPROGRAMS
install-exec-hook:
-chown root $(DESTDIR)$(bindir)/fusermount-glusterfs
chmod u+s $(DESTDIR)$(bindir)/fusermount-glusterfs
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
glusterfs-3.4.2/contrib/fuse-util/COPYING 0000644 0000762 0000763 00000043110 12261516067 015101 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
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; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will 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 to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
glusterfs-3.4.2/contrib/libgen/ 0000755 0000762 0000763 00000000000 12261516146 013450 5 0000000 0000000 glusterfs-3.4.2/contrib/libgen/dirname_r.c 0000644 0000762 0000763 00000020074 12261516067 015501 0000000 0000000 /*
* Borrowed from glibc-2.12.1/string/memrchr.c
* Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
* Removed code for long bigger than 32 bytes, renamed __ptr_t as void *
* changed reg_char type to char.
*/
#include
#include
#ifdef THREAD_UNSAFE_DIRNAME
/* memrchr -- find the last occurrence of a byte in a memory block
Copyright (C) 1991, 93, 96, 97, 99, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
with help from Dan Sahlin (dan@sics.se) and
commentary by Jim Blandy (jimb@ai.mit.edu);
adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
and implemented by Roland McGrath (roland@ai.mit.edu).
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
void *
__memrchr (s, c_in, n)
const void * s;
int c_in;
size_t n;
{
const unsigned char *char_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, magic_bits, charmask;
unsigned char c;
c = (unsigned char) c_in;
/* Handle the last few characters by reading one character at a time.
Do this until CHAR_PTR is aligned on a longword boundary. */
for (char_ptr = (const unsigned char *) s + n;
n > 0 && ((unsigned long int) char_ptr
& (sizeof (longword) - 1)) != 0;
--n)
if (*--char_ptr == c)
return (void *) char_ptr;
/* All these elucidatory comments refer to 4-byte longwords,
but the theory applies equally well to 8-byte longwords. */
longword_ptr = (const unsigned long int *) char_ptr;
/* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
the "holes." Note that there is a hole just to the left of
each byte, with an extra at the end:
bits: 01111110 11111110 11111110 11111111
bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
The 1-bits make sure that carries propagate to the next 0-bit.
The 0-bits provide holes for carries to fall into. */
if (sizeof (longword) != 4 && sizeof (longword) != 8)
abort ();
magic_bits = 0x7efefeff;
/* Set up a longword, each of whose bytes is C. */
charmask = c | (c << 8);
charmask |= charmask << 16;
/* Instead of the traditional loop which tests each character,
we will test a longword at a time. The tricky part is testing
if *any of the four* bytes in the longword in question are zero. */
while (n >= sizeof (longword))
{
/* We tentatively exit the loop if adding MAGIC_BITS to
LONGWORD fails to change any of the hole bits of LONGWORD.
1) Is this safe? Will it catch all the zero bytes?
Suppose there is a byte with all zeros. Any carry bits
propagating from its left will fall into the hole at its
least significant bit and stop. Since there will be no
carry from its most significant bit, the LSB of the
byte to the left will be unchanged, and the zero will be
detected.
2) Is this worthwhile? Will it ignore everything except
zero bytes? Suppose every byte of LONGWORD has a bit set
somewhere. There will be a carry into bit 8. If bit 8
is set, this will carry into bit 16. If bit 8 is clear,
one of bits 9-15 must be set, so there will be a carry
into bit 16. Similarly, there will be a carry into bit
24. If one of bits 24-30 is set, there will be a carry
into bit 31, so all of the hole bits will be changed.
The one misfire occurs when bits 24-30 are clear and bit
31 is set; in this case, the hole at bit 31 is not
changed. If we had access to the processor carry flag,
we could close this loophole by putting the fourth hole
at bit 32!
So it ignores everything except 128's, when they're aligned
properly.
3) But wait! Aren't we looking for C, not zero?
Good point. So what we do is XOR LONGWORD with a longword,
each of whose bytes is C. This turns each byte that is C
into a zero. */
longword = *--longword_ptr ^ charmask;
/* Add MAGIC_BITS to LONGWORD. */
if ((((longword + magic_bits)
/* Set those bits that were unchanged by the addition. */
^ ~longword)
/* Look at only the hole bits. If any of the hole bits
are unchanged, most likely one of the bytes was a
zero. */
& ~magic_bits) != 0)
{
/* Which of the bytes was C? If none of them were, it was
a misfire; continue the search. */
const unsigned char *cp = (const unsigned char *) longword_ptr;
if (cp[3] == c)
return (void *) &cp[3];
if (cp[2] == c)
return (void *) &cp[2];
if (cp[1] == c)
return (void *) &cp[1];
if (cp[0] == c)
return (void *) cp;
}
n -= sizeof (longword);
}
char_ptr = (const unsigned char *) longword_ptr;
while (n-- > 0)
{
if (*--char_ptr == c)
return (void *) char_ptr;
}
return 0;
}
/*
* Borrowed from glibc-2.12.1/misc/dirname.c
*/
/* dirname - return directory part of PATH.
Copyright (C) 1996, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper , 1996.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
char *
dirname_r (char *path)
{
static const char dot[] = ".";
char *last_slash;
/* Find last '/'. */
last_slash = path != NULL ? strrchr (path, '/') : NULL;
if (last_slash != NULL && last_slash != path && last_slash[1] == '\0')
{
/* Determine whether all remaining characters are slashes. */
char *runp;
for (runp = last_slash; runp != path; --runp)
if (runp[-1] != '/')
break;
/* The '/' is the last character, we have to look further. */
if (runp != path)
last_slash = __memrchr (path, '/', runp - path);
}
if (last_slash != NULL)
{
/* Determine whether all remaining characters are slashes. */
char *runp;
for (runp = last_slash; runp != path; --runp)
if (runp[-1] != '/')
break;
/* Terminate the path. */
if (runp == path)
{
/* The last slash is the first character in the string. We have to
return "/". As a special case we have to return "//" if there
are exactly two slashes at the beginning of the string. See
XBD 4.10 Path Name Resolution for more information. */
if (last_slash == path + 1)
++last_slash;
else
last_slash = path + 1;
}
else
last_slash = runp;
last_slash[0] = '\0';
}
else
/* This assignment is ill-designed but the XPG specs require to
return a string containing "." in any case no directory part is
found and so a static and constant string is required. */
path = (char *) dot;
return path;
}
#endif /* THREAD_UNSAFE_DIRNAME */
glusterfs-3.4.2/contrib/libgen/basename_r.c 0000644 0000762 0000763 00000002506 12261516067 015635 0000000 0000000 /*
* borrowed from glibc-2.12.1/string/basename.c
* Modified to return "." for NULL or "", as required for SUSv2.
*/
#include
#include
#ifdef THREAD_UNSAFE_BASENAME
/* Return the name-within-directory of a file name.
Copyright (C) 1996,97,98,2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
char *
basename_r (filename)
const char *filename;
{
char *p;
if ((filename == NULL) || (*filename == '\0'))
return ".";
p = strrchr (filename, '/');
return p ? p + 1 : (char *) filename;
}
#endif /* THREAD_UNSAFE_BASENAME */
glusterfs-3.4.2/contrib/aclocal/ 0000755 0000762 0000763 00000000000 12261516145 013605 5 0000000 0000000 glusterfs-3.4.2/contrib/aclocal/python.m4 0000644 0000762 0000763 00000020513 12261516067 015314 0000000 0000000 ## ------------------------ -*- Autoconf -*-
## Python file handling
## From Andrew Dalke
## Updated by James Henstridge
## ------------------------
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# ---------------------------------------------------------------------------
# Adds support for distributing Python modules and packages. To
# install modules, copy them to $(pythondir), using the python_PYTHON
# automake variable. To install a package with the same name as the
# automake package, install to $(pkgpythondir), or use the
# pkgpython_PYTHON automake variable.
#
# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as
# locations to install python extension modules (shared libraries).
# Another macro is required to find the appropriate flags to compile
# extension modules.
#
# If your package is configured with a different prefix to python,
# users will have to add the install directory to the PYTHONPATH
# environment variable, or create a .pth file (see the python
# documentation for details).
#
# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will
# cause an error if the version of python installed on the system
# doesn't meet the requirement. MINIMUM-VERSION should consist of
# numbers and dots only.
AC_DEFUN([AM_PATH_PYTHON],
[
dnl Find a Python interpreter. Python versions prior to 2.0 are not
dnl supported. (2.0 was released on October 16, 2000).
m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
[python python2 python3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 dnl
python2.1 python2.0])
m4_if([$1],[],[
dnl No version check is needed.
# Find any Python interpreter.
if test -z "$PYTHON"; then
AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :)
fi
am_display_PYTHON=python
], [
dnl A version check is needed.
if test -n "$PYTHON"; then
# If the user set $PYTHON, use it and don't search something else.
AC_MSG_CHECKING([whether $PYTHON version >= $1])
AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
[AC_MSG_RESULT(yes)],
[AC_MSG_ERROR(too old)])
am_display_PYTHON=$PYTHON
else
# Otherwise, try each interpreter until we find one that satisfies
# VERSION.
AC_CACHE_CHECK([for a Python interpreter with version >= $1],
[am_cv_pathless_PYTHON],[
for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do
test "$am_cv_pathless_PYTHON" = none && break
AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break])
done])
# Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON.
if test "$am_cv_pathless_PYTHON" = none; then
PYTHON=:
else
AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON])
fi
am_display_PYTHON=$am_cv_pathless_PYTHON
fi
])
if test "$PYTHON" = :; then
dnl Run any user-specified action, or abort.
m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
else
dnl Query Python for its version number. Getting [:3] seems to be
dnl the best way to do this; it's what "site.py" does in the standard
dnl library.
AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
[am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
dnl Use the values of $prefix and $exec_prefix for the corresponding
dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made
dnl distinct variables so they can be overridden if need be. However,
dnl general consensus is that you shouldn't need this ability.
AC_SUBST([PYTHON_PREFIX], ['${prefix}'])
AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}'])
dnl At times (like when building shared libraries) you may want
dnl to know which OS platform Python thinks this is.
AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform],
[am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform])
dnl Set up 4 directories:
dnl pythondir -- where to install python scripts. This is the
dnl site-packages directory, not the python standard library
dnl directory like in previous automake betas. This behavior
dnl is more consistent with lispdir.m4 for example.
dnl Query distutils for this directory. distutils does not exist in
dnl Python 1.5, so we fall back to the hardcoded directory if it
dnl doesn't work.
AC_CACHE_CHECK([for $am_display_PYTHON script directory],
[am_cv_python_pythondir],
[if test "x$prefix" = xNONE
then
am_py_prefix=$ac_default_prefix
else
am_py_prefix=$prefix
fi
am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null ||
echo "$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages"`
case $am_cv_python_pythondir in
$am_py_prefix*)
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"`
;;
*)
case $am_py_prefix in
/usr|/System*) ;;
*)
am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages
;;
esac
;;
esac
])
AC_SUBST([pythondir], [$am_cv_python_pythondir])
dnl pkgpythondir -- $PACKAGE directory under pythondir. Was
dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is
dnl more consistent with the rest of automake.
AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE])
dnl pyexecdir -- directory for installing python extension modules
dnl (shared libraries)
dnl Query distutils for this directory. distutils does not exist in
dnl Python 1.5, so we fall back to the hardcoded directory if it
dnl doesn't work.
AC_CACHE_CHECK([for $am_display_PYTHON extension module directory],
[am_cv_python_pyexecdir],
[if test "x$exec_prefix" = xNONE
then
am_py_exec_prefix=$am_py_prefix
else
am_py_exec_prefix=$exec_prefix
fi
am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null ||
echo "$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages"`
case $am_cv_python_pyexecdir in
$am_py_exec_prefix*)
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"`
;;
*)
case $am_py_exec_prefix in
/usr|/System*) ;;
*)
am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages
;;
esac
;;
esac
])
AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir])
dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE)
AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE])
dnl Run any user-specified action.
$2
fi
])
# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
# ---------------------------------------------------------------------------
# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION.
# Run ACTION-IF-FALSE otherwise.
# This test uses sys.hexversion instead of the string equivalent (first
# word of sys.version), in order to cope with versions such as 2.2c1.
# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000).
AC_DEFUN([AM_PYTHON_CHECK_VERSION],
[prog="import sys
# split strings by '.' and convert to numeric. Append some zeros
# because we need at least 4 digits for the hex conversion.
# map returns an iterator in Python 3.0 and a list in 2.x
minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]]
minverhex = 0
# xrange is not present in Python 3.0 and range returns an iterator
for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
sys.exit(sys.hexversion < minverhex)"
AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
glusterfs-3.4.2/contrib/aclocal/mkdirp.m4 0000644 0000762 0000763 00000014111 12261516067 015256 0000000 0000000 # Excerpt from autoconf/autoconf/programs.m4
# This file is part of Autoconf. -*- Autoconf -*-
# Checking for programs.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
# Foundation, Inc.
# This file is part of Autoconf. 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, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will 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.
#
# Under Section 7 of GPL version 3, you are granted additional
# permissions described in the Autoconf Configure Script Exception,
# version 3.0, as published by the Free Software Foundation.
#
# You should have received a copy of the GNU General Public License
# and a copy of the Autoconf Configure Script Exception along with
# this program; see the files COPYINGv3 and COPYING.EXCEPTION
# respectively. If not, see .
# Written by David MacKenzie, with help from
# Franc,ois Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor,
# Roland McGrath, Noah Friedman, david d zuhn, and many others.
# AC_PROG_MKDIR_P
# ---------------
# Check whether `mkdir -p' is known to be thread-safe, and fall back to
# install-sh -d otherwise.
#
# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
# created by `make install' are always world readable, even if the
# installer happens to have an overly restrictive umask (e.g. 077).
# This was a mistake. There are at least two reasons why we must not
# use `-m 0755':
# - it causes special bits like SGID to be ignored,
# - it may be too restrictive (some setups expect 775 directories).
#
# Do not use -m 0755 and let people choose whatever they expect by
# setting umask.
#
# We cannot accept any implementation of `mkdir' that recognizes `-p'.
# Some implementations (such as Solaris 8's) are vulnerable to race conditions:
# if a parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
# concurrently, both version can detect that a/ is missing, but only
# one can create it and the other will error out. Consequently we
# restrict ourselves to known race-free implementations.
#
# Automake used to define mkdir_p as `mkdir -p .', in order to
# allow $(mkdir_p) to be used without argument. As in
# $(mkdir_p) $(somedir)
# where $(somedir) is conditionally defined. However we don't do
# that for MKDIR_P.
# 1. before we restricted the check to GNU mkdir, `mkdir -p .' was
# reported to fail in read-only directories. The system where this
# happened has been forgotten.
# 2. in practice we call $(MKDIR_P) on directories such as
# $(MKDIR_P) "$(DESTDIR)$(somedir)"
# and we don't want to create $(DESTDIR) if $(somedir) is empty.
# To support the latter case, we have to write
# test -z "$(somedir)" || $(MKDIR_P) "$(DESTDIR)$(somedir)"
# so $(MKDIR_P) always has an argument.
# We will have better chances of detecting a missing test if
# $(MKDIR_P) complains about missing arguments.
# 3. $(MKDIR_P) is named after `mkdir -p' and we don't expect this
# to accept no argument.
# 4. having something like `mkdir .' in the output is unsightly.
#
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create.
AN_MAKEVAR([MKDIR_P], [AC_PROG_MKDIR_P])
AC_DEFUN_ONCE([AC_PROG_MKDIR_P],
[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
AC_MSG_CHECKING([for a thread-safe mkdir -p])
if test -z "$MKDIR_P"; then
AC_CACHE_VAL([ac_cv_path_mkdir],
[_AS_PATH_WALK([$PATH$PATH_SEPARATOR/opt/sfw/bin],
[for ac_prog in mkdir gmkdir; do
for ac_exec_ext in '' $ac_executable_extensions; do
AS_EXECUTABLE_P(["$as_dir/$ac_prog$ac_exec_ext"]) || continue
case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
'mkdir (GNU coreutils) '* | \
'mkdir (coreutils) '* | \
'mkdir (fileutils) '4.1*)
ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
break 3;;
esac
done
done])])
test -d ./--version && rmdir ./--version
if test "${ac_cv_path_mkdir+set}" = set; then
MKDIR_P="$ac_cv_path_mkdir -p"
else
# As a last resort, use the slow shell script. Don't cache a
# value for MKDIR_P within a source directory, because that will
# break other packages using the cache if that directory is
# removed, or if the value is a relative name.
MKDIR_P="$ac_install_sh -d"
fi
fi
dnl status.m4 does special magic for MKDIR_P instead of AC_SUBST,
dnl to get relative names right. However, also AC_SUBST here so
dnl that Automake versions before 1.10 will pick it up (they do not
dnl trace AC_SUBST_TRACE).
dnl FIXME: Remove this once we drop support for Automake < 1.10.
AC_SUBST([MKDIR_P])dnl
AC_MSG_RESULT([$MKDIR_P])
])# AC_PROG_MKDIR_P
# From automake/m4/mkdirp.m4
## -*- Autoconf -*-
# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_MKDIR_P
# ---------------
# Check for `mkdir -p'.
AC_DEFUN([AM_PROG_MKDIR_P],
[
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
dnl while keeping a definition of mkdir_p for backward compatibility.
dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
dnl Makefile.ins that do not define MKDIR_P, so we do our own
dnl adjustment using top_builddir (which is defined more often than
dnl MKDIR_P).
AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
case $mkdir_p in
[[\\/$]]* | ?:[[\\/]]*) ;;
*/*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
esac
])
glusterfs-3.4.2/contrib/fuse-lib/ 0000755 0000762 0000763 00000000000 12261516155 013716 5 0000000 0000000 glusterfs-3.4.2/contrib/fuse-lib/mount-gluster-compat.h 0000644 0000762 0000763 00000002411 12261516067 020115 0000000 0000000 /*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi
Copyright (c) 2010 Gluster, Inc.
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB.
*/
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef __NetBSD__
#include
#endif /* __NetBSD__ */
#include
#include
#include
#include
#include
#ifdef __NetBSD__
#include
#define umount2(dir, flags) unmount(dir, ((flags) != 0) ? MNT_FORCE : 0)
#define MS_RDONLY MNT_RDONLY
#endif
#ifdef linux
#define _PATH_MOUNT "/bin/mount"
#else /* NetBSD, MacOS X */
#define _PATH_MOUNT "/sbin/mount"
#endif
#ifdef FUSE_UTIL
#define MALLOC(size) malloc (size)
#define FREE(ptr) free (ptr)
#define GFFUSE_LOGERR(...) fprintf (stderr, ## __VA_ARGS__)
#else /* FUSE_UTIL */
#include "glusterfs.h"
#include "logging.h"
#include "common-utils.h"
#define GFFUSE_LOGERR(...) \
gf_log ("glusterfs-fuse", GF_LOG_ERROR, ## __VA_ARGS__)
#endif /* !FUSE_UTIL */
glusterfs-3.4.2/contrib/fuse-lib/misc.c 0000644 0000762 0000763 00000002531 12261516067 014740 0000000 0000000 /*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB
*/
#include
#include
#include
#include
#include "glusterfs.h"
#include "fuse_kernel.h"
#include "fuse-misc.h"
unsigned long
calc_timeout_sec (double t)
{
if (t > (double) ULONG_MAX)
return ULONG_MAX;
else if (t < 0.0)
return 0;
else
return (unsigned long) t;
}
unsigned int
calc_timeout_nsec (double t)
{
double f = t - (double) calc_timeout_sec (t);
if (f < 0.0)
return 0;
else if (f >= 0.999999999)
return 999999999;
else
return (unsigned int) (f * 1.0e9);
}
void
convert_fuse_file_lock (struct fuse_file_lock *fl, struct gf_flock *flock,
uint64_t lk_owner)
{
memset (flock, 0, sizeof (struct flock));
flock->l_type = fl->type;
flock->l_whence = SEEK_SET;
flock->l_start = fl->start;
if (fl->end == OFFSET_MAX)
flock->l_len = 0;
else
flock->l_len = fl->end - fl->start + 1;
flock->l_pid = fl->pid;
set_lk_owner_from_uint64 (&flock->l_owner, lk_owner);
}
glusterfs-3.4.2/contrib/fuse-lib/mount-common.c 0000644 0000762 0000763 00000020461 12261516067 016437 0000000 0000000 /*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi
Copyright (c) 2010 Gluster, Inc.
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB.
*/
#include "mount-gluster-compat.h"
/*
* These functions (and gf_fuse_umount() in mount.c)
* were originally taken from libfuse as of commit 7960e99e
* (http://fuse.git.sourceforge.net/git/gitweb.cgi?p=fuse/fuse;a=commit;h=7960e99e)
* almost verbatim. What has been changed upon adoption:
* - style adopted to that of glusterfs
* - s/fprintf/gf_log/
* - s/free/FREE/, s/malloc/MALLOC/
* - there are some other minor things
*
* For changes that were made later and syncs with upstream,
* see the commit log and per-function comments.
*/
#ifndef __NetBSD__
/* FUSE: cherry-picked bd99f9cf */
static int
mtab_needs_update (const char *mnt)
{
int res;
struct stat stbuf;
/* If mtab is within new mount, don't touch it */
if (strncmp (mnt, _PATH_MOUNTED, strlen (mnt)) == 0 &&
_PATH_MOUNTED[strlen (mnt)] == '/')
return 0;
/*
* Skip mtab update if /etc/mtab:
*
* - doesn't exist,
* - is a symlink,
* - is on a read-only filesystem.
*/
res = lstat (_PATH_MOUNTED, &stbuf);
if (res == -1) {
if (errno == ENOENT)
return 0;
} else {
uid_t ruid;
int err;
if (S_ISLNK (stbuf.st_mode))
return 0;
ruid = getuid ();
if (ruid != 0)
setreuid (0, -1);
res = access (_PATH_MOUNTED, W_OK);
err = (res == -1) ? errno : 0;
if (ruid != 0)
setreuid (ruid, -1);
if (err == EROFS)
return 0;
}
return 1;
}
#else /* __NetBSD__ */
#define mtab_needs_update(x) 1
#endif /* __NetBSD__ */
/* FUSE: called add_mount_legacy(); R.I.P. as of cbd3a2a8 */
int
fuse_mnt_add_mount (const char *progname, const char *fsname,
const char *mnt, const char *type, const char *opts)
{
int res;
int status;
sigset_t blockmask;
sigset_t oldmask;
if (!mtab_needs_update (mnt))
return 0;
sigemptyset (&blockmask);
sigaddset (&blockmask, SIGCHLD);
res = sigprocmask (SIG_BLOCK, &blockmask, &oldmask);
if (res == -1) {
GFFUSE_LOGERR ("%s: sigprocmask: %s",
progname, strerror (errno));
return -1;
}
res = fork ();
if (res == -1) {
GFFUSE_LOGERR ("%s: fork: %s", progname, strerror (errno));
goto out_restore;
}
if (res == 0) {
char templ[] = "/tmp/fusermountXXXXXX";
char *tmp;
sigprocmask (SIG_SETMASK, &oldmask, NULL);
setuid (geteuid ());
/*
* hide in a directory, where mount isn't able to resolve
* fsname as a valid path
*/
tmp = mkdtemp (templ);
if (!tmp) {
GFFUSE_LOGERR ("%s: failed to create temporary directory",
progname);
exit (1);
}
if (chdir (tmp)) {
GFFUSE_LOGERR ("%s: failed to chdir to %s: %s",
progname, tmp, strerror (errno));
exit (1);
}
rmdir (tmp);
execl (_PATH_MOUNT, _PATH_MOUNT, "-i", "-f", "-t", type,
"-o", opts, fsname, mnt, NULL);
GFFUSE_LOGERR ("%s: failed to execute %s: %s",
progname, _PATH_MOUNT, strerror (errno));
exit (1);
}
res = waitpid (res, &status, 0);
if (res == -1)
GFFUSE_LOGERR ("%s: waitpid: %s", progname, strerror (errno));
res = (res != -1 && status == 0) ? 0 : -1;
out_restore:
sigprocmask (SIG_SETMASK, &oldmask, NULL);
return res;
}
char *
fuse_mnt_resolve_path (const char *progname, const char *orig)
{
char buf[PATH_MAX];
char *copy;
char *dst;
char *end;
char *lastcomp;
const char *toresolv;
if (!orig[0]) {
GFFUSE_LOGERR ("%s: invalid mountpoint '%s'", progname, orig);
return NULL;
}
copy = strdup (orig);
if (copy == NULL) {
GFFUSE_LOGERR ("%s: failed to allocate memory", progname);
return NULL;
}
toresolv = copy;
lastcomp = NULL;
for (end = copy + strlen (copy) - 1; end > copy && *end == '/'; end --);
if (end[0] != '/') {
char *tmp;
end[1] = '\0';
tmp = strrchr (copy, '/');
if (tmp == NULL) {
lastcomp = copy;
toresolv = ".";
} else {
lastcomp = tmp + 1;
if (tmp == copy)
toresolv = "/";
}
if (strcmp (lastcomp, ".") == 0 || strcmp (lastcomp, "..") == 0) {
lastcomp = NULL;
toresolv = copy;
}
else if (tmp)
tmp[0] = '\0';
}
if (realpath (toresolv, buf) == NULL) {
GFFUSE_LOGERR ("%s: bad mount point %s: %s", progname, orig,
strerror (errno));
FREE (copy);
return NULL;
}
if (lastcomp == NULL)
dst = strdup (buf);
else {
dst = (char *) MALLOC (strlen (buf) + 1 + strlen (lastcomp) + 1);
if (dst) {
unsigned buflen = strlen (buf);
if (buflen && buf[buflen-1] == '/')
sprintf (dst, "%s%s", buf, lastcomp);
else
sprintf (dst, "%s/%s", buf, lastcomp);
}
}
FREE (copy);
if (dst == NULL)
GFFUSE_LOGERR ("%s: failed to allocate memory", progname);
return dst;
}
/* FUSE: to support some changes that were reverted since
* then, it was split in two (fuse_mnt_umount() and
* exec_umount()); however the actual code is same as here
* since 0197ce40
*/
int
fuse_mnt_umount (const char *progname, const char *abs_mnt,
const char *rel_mnt, int lazy)
{
int res;
int status;
sigset_t blockmask;
sigset_t oldmask;
if (!mtab_needs_update (abs_mnt)) {
res = umount2 (rel_mnt, lazy ? 2 : 0);
if (res == -1)
GFFUSE_LOGERR ("%s: failed to unmount %s: %s",
progname, abs_mnt, strerror (errno));
return res;
}
sigemptyset (&blockmask);
sigaddset (&blockmask, SIGCHLD);
res = sigprocmask (SIG_BLOCK, &blockmask, &oldmask);
if (res == -1) {
GFFUSE_LOGERR ("%s: sigprocmask: %s", progname,
strerror (errno));
return -1;
}
res = fork ();
if (res == -1) {
GFFUSE_LOGERR ("%s: fork: %s", progname, strerror (errno));
goto out_restore;
}
if (res == 0) {
sigprocmask (SIG_SETMASK, &oldmask, NULL);
setuid (geteuid ());
execl ("/bin/umount", "/bin/umount", "-i", rel_mnt,
lazy ? "-l" : NULL, NULL);
GFFUSE_LOGERR ("%s: failed to execute /bin/umount: %s",
progname, strerror (errno));
exit (1);
}
res = waitpid (res, &status, 0);
if (res == -1)
GFFUSE_LOGERR ("%s: waitpid: %s", progname, strerror (errno));
if (status != 0)
res = -1;
out_restore:
sigprocmask (SIG_SETMASK, &oldmask, NULL);
return res;
}
glusterfs-3.4.2/contrib/fuse-lib/mount.c 0000644 0000762 0000763 00000021620 12261516067 015147 0000000 0000000 /*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi
Copyright (c) 2010 Gluster, Inc.
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB.
*/
#include "mount_util.h"
#include "mount-gluster-compat.h"
#ifdef GF_FUSERMOUNT
#define FUSERMOUNT_PROG FUSERMOUNT_DIR "/fusermount-glusterfs"
#else
#define FUSERMOUNT_PROG "fusermount"
#endif
#define FUSE_DEVFD_ENV "_FUSE_DEVFD"
/* FUSE: function is called fuse_kern_unmount() */
void
gf_fuse_unmount (const char *mountpoint, int fd)
{
int res;
int pid;
if (!mountpoint)
return;
if (fd != -1) {
struct pollfd pfd;
pfd.fd = fd;
pfd.events = 0;
res = poll (&pfd, 1, 0);
/* If file poll returns POLLERR on the device file descriptor,
then the filesystem is already unmounted */
if (res == 1 && (pfd.revents & POLLERR))
return;
/* Need to close file descriptor, otherwise synchronous umount
would recurse into filesystem, and deadlock */
close (fd);
}
if (geteuid () == 0) {
fuse_mnt_umount ("fuse", mountpoint, mountpoint, 1);
return;
}
res = umount2 (mountpoint, 2);
if (res == 0)
return;
pid = fork ();
if (pid == -1)
return;
if (pid == 0) {
const char *argv[] = { FUSERMOUNT_PROG, "-u", "-q", "-z",
"--", mountpoint, NULL };
execvp (FUSERMOUNT_PROG, (char **)argv);
_exit (1);
}
waitpid (pid, NULL, 0);
}
/* gluster-specific routines */
static char *
escape (char *s)
{
size_t len = 0;
char *p = NULL;
char *q = NULL;
char *e = NULL;
for (p = s; *p; p++) {
if (*p == ',')
len++;
len++;
}
e = CALLOC (1, len + 1);
if (!e)
return NULL;
for (p = s, q = e; *p; p++, q++) {
if (*p == ',') {
*q = '\\';
q++;
}
*q = *p;
}
return e;
}
static int
fuse_mount_fusermount (const char *mountpoint, char *fsname,
unsigned long mountflags, char *mnt_param,
int fd)
{
int pid = -1;
int res = 0;
int ret = -1;
char *fm_mnt_params = NULL;
char *efsname = NULL;
#ifndef GF_FUSERMOUNT
GFFUSE_LOGERR ("Mounting via helper utility "
"(unprivileged mounting) is supported "
"only if glusterfs is compiled with "
"--enable-fusermount");
return -1;
#endif
efsname = escape (fsname);
if (!efsname) {
GFFUSE_LOGERR ("Out of memory");
return -1;
}
ret = asprintf (&fm_mnt_params,
"%s%s,fsname=%s,nonempty,subtype=glusterfs",
(mountflags & MS_RDONLY) ? "ro," : "",
mnt_param, efsname);
FREE (efsname);
if (ret == -1) {
GFFUSE_LOGERR ("Out of memory");
goto out;
}
/* fork to exec fusermount */
pid = fork ();
if (pid == -1) {
GFFUSE_LOGERR ("fork() failed: %s", strerror (errno));
ret = -1;
goto out;
}
if (pid == 0) {
char env[10];
const char *argv[32];
int a = 0;
argv[a++] = FUSERMOUNT_PROG;
argv[a++] = "-o";
argv[a++] = fm_mnt_params;
argv[a++] = "--";
argv[a++] = mountpoint;
argv[a++] = NULL;
snprintf (env, sizeof (env), "%i", fd);
setenv (FUSE_DEVFD_ENV, env, 1);
execvp (FUSERMOUNT_PROG, (char **)argv);
GFFUSE_LOGERR ("failed to exec fusermount: %s",
strerror (errno));
_exit (1);
}
ret = waitpid (pid, &res, 0);
ret = (ret == pid && res == 0) ? 0 : -1;
out:
FREE (fm_mnt_params);
return ret;
}
static int
fuse_mount_sys (const char *mountpoint, char *fsname,
unsigned long mountflags, char *mnt_param, int fd)
{
int ret = -1;
unsigned mounted = 0;
char *mnt_param_mnt = NULL;
char *fstype = "fuse.glusterfs";
char *source = fsname;
ret = asprintf (&mnt_param_mnt,
"%s,fd=%i,rootmode=%o,user_id=%i,group_id=%i",
mnt_param, fd, S_IFDIR, getuid (), getgid ());
if (ret == -1) {
GFFUSE_LOGERR ("Out of memory");
goto out;
}
ret = mount (source, mountpoint, fstype, mountflags,
mnt_param_mnt);
if (ret == -1 && errno == ENODEV) {
/* fs subtype support was added by 79c0b2df aka
v2.6.21-3159-g79c0b2d. Probably we have an
older kernel ... */
fstype = "fuse";
ret = asprintf (&source, "glusterfs#%s", fsname);
if (ret == -1) {
GFFUSE_LOGERR ("Out of memory");
goto out;
}
ret = mount (source, mountpoint, fstype, mountflags,
mnt_param_mnt);
}
if (ret == -1)
goto out;
else
mounted = 1;
#ifndef __NetBSD__
if (geteuid () == 0) {
char *newmnt = fuse_mnt_resolve_path ("fuse", mountpoint);
char *mnt_param_mtab = NULL;
if (!newmnt) {
ret = -1;
goto out;
}
ret = asprintf (&mnt_param_mtab, "%s%s",
mountflags & MS_RDONLY ? "ro," : "",
mnt_param);
if (ret == -1)
GFFUSE_LOGERR ("Out of memory");
else {
ret = fuse_mnt_add_mount ("fuse", source, newmnt,
fstype, mnt_param_mtab);
FREE (mnt_param_mtab);
}
FREE (newmnt);
if (ret == -1) {
GFFUSE_LOGERR ("failed to add mtab entry");
goto out;
}
}
#endif /* __NetBSD__ */
out:
if (ret == -1) {
if (mounted)
umount2 (mountpoint, 2); /* lazy umount */
}
FREE (mnt_param_mnt);
if (source != fsname)
FREE (source);
return ret;
}
int
gf_fuse_mount (const char *mountpoint, char *fsname,
unsigned long mountflags, char *mnt_param,
pid_t *mnt_pid, int status_fd)
{
int fd = -1;
pid_t pid = -1;
int ret = -1;
fd = open ("/dev/fuse", O_RDWR);
if (fd == -1) {
GFFUSE_LOGERR ("cannot open /dev/fuse (%s)",
strerror (errno));
return -1;
}
/* start mount agent */
pid = fork();
switch (pid) {
case 0:
/* hello it's mount agent */
if (!mnt_pid) {
/* daemonize mount agent, caller is
* not interested in waiting for it
*/
pid = fork ();
if (pid)
exit (pid == -1 ? 1 : 0);
}
ret = fuse_mount_sys (mountpoint, fsname, mountflags, mnt_param, fd);
if (ret == -1) {
gf_log ("glusterfs-fuse", GF_LOG_INFO,
"direct mount failed (%s), "
"retry to mount via fusermount",
strerror (errno));
ret = fuse_mount_fusermount (mountpoint, fsname, mountflags,
mnt_param, fd);
}
if (ret == -1)
GFFUSE_LOGERR ("mount of %s to %s (%s) failed",
fsname, mountpoint, mnt_param);
if (status_fd >= 0)
(void)write (status_fd, &ret, sizeof (ret));
exit (!!ret);
/* bye mount agent */
case -1:
close (fd);
fd = -1;
}
if (mnt_pid)
*mnt_pid = pid;
return fd;
}
glusterfs-3.4.2/contrib/macfuse/ 0000755 0000762 0000763 00000000000 12261516155 013633 5 0000000 0000000 glusterfs-3.4.2/contrib/macfuse/mount_darwin.c 0000644 0000762 0000763 00000020351 12261516067 016430 0000000 0000000 /*
* Derived from mount_bsd.c from the fuse distribution.
*
* FUSE: Filesystem in Userspace
* Copyright (C) 2005-2006 Csaba Henk
* Copyright (C) 2007-2009 Amit Singh
* Copyright (c) 2010 Gluster, Inc.
*
* This program can be distributed under the terms of the GNU LGPLv2.
* See the file COPYING.LIB.
*/
#undef _POSIX_C_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "fuse_param.h"
#include "fuse_ioctl.h"
#include "glusterfs.h"
#include "logging.h"
#include "common-utils.h"
#define GFFUSE_LOGERR(...) \
gf_log ("glusterfs-fuse", GF_LOG_ERROR, ## __VA_ARGS__)
static long
fuse_os_version_major_np(void)
{
int ret = 0;
long major = 0;
char *c = NULL;
struct utsname u;
size_t oldlen;
oldlen = sizeof(u.release);
ret = sysctlbyname("kern.osrelease", u.release, &oldlen, NULL, 0);
if (ret != 0) {
return -1;
}
c = strchr(u.release, '.');
if (c == NULL) {
return -1;
}
*c = '\0';
errno = 0;
major = strtol(u.release, NULL, 10);
if ((errno == EINVAL) || (errno == ERANGE)) {
return -1;
}
return major;
}
static int
fuse_running_under_rosetta(void)
{
int result = 0;
int is_native = 1;
size_t sz = sizeof(result);
int ret = sysctlbyname("sysctl.proc_native", &result, &sz, NULL, (size_t)0);
if ((ret == 0) && !result) {
is_native = 0;
}
return !is_native;
}
static int
loadkmod(void)
{
int result = -1;
int pid, terminated_pid;
union wait status;
long major;
major = fuse_os_version_major_np();
if (major < 9) { /* not Mac OS X 10.5+ */
return EINVAL;
}
pid = fork();
if (pid == 0) {
execl(MACFUSE_LOAD_PROG, MACFUSE_LOAD_PROG, NULL);
/* exec failed */
exit(ENOENT);
}
require_action(pid != -1, Return, result = errno);
while ((terminated_pid = wait4(pid, (int *)&status, 0, NULL)) < 0) {
/* retry if EINTR, else break out with error */
if (errno != EINTR) {
break;
}
}
if ((terminated_pid == pid) && (WIFEXITED(status))) {
result = WEXITSTATUS(status);
} else {
result = -1;
}
Return:
check_noerr_string(result, strerror(errno));
return result;
}
int
gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,
pid_t *mtab_pid /* not used on OS X */)
{
int fd, pid;
int result;
char *fdnam, *dev;
const char *mountprog = MACFUSE_MOUNT_PROG;
sig_t chldf;
/* mount_fusefs should not try to spawn the daemon */
setenv("MOUNT_FUSEFS_SAFE", "1", 1);
/* to notify mount_fusefs it's called from lib */
setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);
if (!mountpoint) {
fprintf(stderr, "missing or invalid mount point\n");
return -1;
}
if (fuse_running_under_rosetta()) {
fprintf(stderr, "MacFUSE does not work under Rosetta\n");
return -1;
}
chldf = signal(SIGCHLD, SIG_DFL); /* So that we can wait4() below. */
result = loadkmod();
if (result == EINVAL)
GFFUSE_LOGERR("OS X >= 10.5 (at least Leopard) required");
else if (result == 0 || result == ENOENT || result == EBUSY) {
/* Module loaded, but now need to check for user<->kernel match. */
char version[MAXHOSTNAMELEN + 1] = { 0 };
size_t version_len = MAXHOSTNAMELEN;
size_t version_len_desired = 0;
result = sysctlbyname(SYSCTL_MACFUSE_VERSION_NUMBER, version,
&version_len, NULL, (size_t)0);
if (result == 0) {
/* sysctlbyname() includes the trailing '\0' in version_len */
version_len_desired = strlen("2.x.y") + 1;
if (version_len != version_len_desired)
result = -1;
} else
strcpy(version, "?.?.?");
if (result == 0) {
char *ep;
char vstr[4];
unsigned vval;
int i;
for (i = 0; i < 3; i++)
vstr[i] = version[2*i];
vstr[3] = '\0';
vval = strtoul(vstr, &ep, 10);
if (*ep || vval < 203 || vval > 217)
result = -1;
else
gf_log("glusterfs-fuse", GF_LOG_INFO,
"MacFUSE kext version %s", version);
}
if (result != 0)
GFFUSE_LOGERR("MacFUSE version %s is not supported", version);
} else
GFFUSE_LOGERR("cannot load MacFUSE kext");
if (result != 0)
return -1;
fdnam = getenv("FUSE_DEV_FD");
if (fdnam) {
char *ep;
fd = strtol(fdnam, &ep, 10);
if (*ep != '\0' || fd < 0) {
GFFUSE_LOGERR("invalid value given in FUSE_DEV_FD");
return -1;
}
goto mount;
}
dev = getenv("FUSE_DEV_NAME");
if (dev) {
if ((fd = open(dev, O_RDWR)) < 0) {
GFFUSE_LOGERR("failed to open device (%s)", strerror(errno));
return -1;
}
} else {
int r, devidx = -1;
char devpath[MAXPATHLEN];
for (r = 0; r < MACFUSE_NDEVICES; r++) {
snprintf(devpath, MAXPATHLEN - 1,
_PATH_DEV MACFUSE_DEVICE_BASENAME "%d", r);
fd = open(devpath, O_RDWR);
if (fd >= 0) {
dev = devpath;
devidx = r;
break;
}
}
if (devidx == -1) {
GFFUSE_LOGERR("failed to open device (%s)", strerror(errno));
return -1;
}
}
mount:
if (getenv("FUSE_NO_MOUNT") || ! mountpoint)
goto out;
signal(SIGCHLD, chldf);
pid = fork();
if (pid == -1) {
GFFUSE_LOGERR("fork() failed (%s)", strerror(errno));
close(fd);
return -1;
}
if (pid == 0) {
pid = fork();
if (pid == -1) {
GFFUSE_LOGERR("fork() failed (%s)", strerror(errno));
close(fd);
exit(1);
}
if (pid == 0) {
const char *argv[32];
int a = 0;
char *opts = NULL;
if (asprintf(&opts, "%s,fssubtype=glusterfs", mnt_param) == -1) {
GFFUSE_LOGERR("Out of memory");
exit(1);
}
if (! fdnam)
asprintf(&fdnam, "%d", fd);
argv[a++] = mountprog;
if (opts) {
argv[a++] = "-o";
argv[a++] = opts;
}
argv[a++] = fdnam;
argv[a++] = mountpoint;
argv[a++] = NULL;
{
char title[MAXPATHLEN + 1] = { 0 };
u_int32_t len = MAXPATHLEN;
int ret = proc_pidpath(getpid(), title, len);
if (ret) {
setenv("MOUNT_FUSEFS_DAEMON_PATH", title, 1);
}
}
execvp(mountprog, (char **) argv);
GFFUSE_LOGERR("MacFUSE: failed to exec mount program (%s)", strerror(errno));
exit(1);
}
_exit(0);
}
out:
return fd;
}
void
gf_fuse_unmount(const char *mountpoint, int fd)
{
int ret;
struct stat sbuf;
char dev[128];
char resolved_path[PATH_MAX];
char *ep, *rp = NULL;
unsigned int hs_complete = 0;
ret = ioctl(fd, FUSEDEVIOCGETHANDSHAKECOMPLETE, &hs_complete);
if (ret || !hs_complete) {
return;
}
/* XXX does this have any use here? */
ret = ioctl(fd, FUSEDEVIOCSETDAEMONDEAD, &fd);
if (ret) {
return;
}
if (fstat(fd, &sbuf) == -1) {
return;
}
devname_r(sbuf.st_rdev, S_IFCHR, dev, 128);
if (strncmp(dev, MACFUSE_DEVICE_BASENAME,
sizeof(MACFUSE_DEVICE_BASENAME) - 1)) {
return;
}
strtol(dev + 4, &ep, 10);
if (*ep != '\0') {
return;
}
rp = realpath(mountpoint, resolved_path);
if (rp) {
ret = unmount(resolved_path, 0);
}
close(fd);
return;
}
glusterfs-3.4.2/contrib/uuid/ 0000755 0000762 0000763 00000000000 12261516146 013156 5 0000000 0000000 glusterfs-3.4.2/contrib/uuid/clear.c 0000644 0000762 0000763 00000003214 12261516067 014332 0000000 0000000 /*
* clear.c -- Clear a UUID
*
* Copyright (C) 1996, 1997 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#include "string.h"
#include "uuidP.h"
void uuid_clear(uuid_t uu)
{
memset(uu, 0, 16);
}
glusterfs-3.4.2/contrib/uuid/parse.c 0000644 0000762 0000763 00000004565 12261516067 014370 0000000 0000000 /*
* parse.c --- UUID parsing
*
* Copyright (C) 1996, 1997 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#include
#include
#include
#include
#include "uuidP.h"
int uuid_parse(const char *in, uuid_t uu)
{
struct uuid uuid;
int i;
const char *cp;
char buf[3];
if (strlen(in) != 36)
return -1;
for (i=0, cp = in; i <= 36; i++,cp++) {
if ((i == 8) || (i == 13) || (i == 18) ||
(i == 23)) {
if (*cp == '-')
continue;
else
return -1;
}
if (i== 36)
if (*cp == 0)
continue;
if (!isxdigit(*cp))
return -1;
}
uuid.time_low = strtoul(in, NULL, 16);
uuid.time_mid = strtoul(in+9, NULL, 16);
uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
uuid.clock_seq = strtoul(in+19, NULL, 16);
cp = in+24;
buf[2] = 0;
for (i=0; i < 6; i++) {
buf[0] = *cp++;
buf[1] = *cp++;
uuid.node[i] = strtoul(buf, NULL, 16);
}
uuid_pack(&uuid, uu);
return 0;
}
glusterfs-3.4.2/contrib/uuid/uuid_types.h.in 0000644 0000762 0000763 00000002232 12261516067 016047 0000000 0000000 /*
* If linux/types.h is already been included, assume it has defined
* everything we need. (cross fingers) Other header files may have
* also defined the types that we need.
*/
#if (!defined(_STDINT_H) && !defined(_UUID_STDINT_H))
#define _UUID_STDINT_H
typedef unsigned char uint8_t;
typedef signed char int8_t;
#if (@SIZEOF_INT@ == 8)
typedef int int64_t;
typedef unsigned int uint64_t;
#elif (@SIZEOF_LONG@ == 8)
typedef long int64_t;
typedef unsigned long uint64_t;
#elif (@SIZEOF_LONG_LONG@ == 8)
#if defined(__GNUC__)
typedef __signed__ long long int64_t;
#else
typedef signed long long int64_t;
#endif
typedef unsigned long long uint64_t;
#endif
#if (@SIZEOF_INT@ == 2)
typedef int int16_t;
typedef unsigned int uint16_t;
#elif (@SIZEOF_SHORT@ == 2)
typedef short int16_t;
typedef unsigned short uint16_t;
#else
?==error: undefined 16 bit type
#endif
#if (@SIZEOF_INT@ == 4)
typedef int int32_t;
typedef unsigned int uint32_t;
#elif (@SIZEOF_LONG@ == 4)
typedef long int32_t;
typedef unsigned long uint32_t;
#elif (@SIZEOF_SHORT@ == 4)
typedef short int32_t;
typedef unsigned short uint32_t;
#else
?== error: undefined 32 bit type
#endif
#endif
glusterfs-3.4.2/contrib/uuid/isnull.c 0000644 0000762 0000763 00000003436 12261516067 014560 0000000 0000000 /*
* isnull.c --- Check whether or not the UUID is null
*
* Copyright (C) 1996, 1997 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#include "uuidP.h"
/* Returns 1 if the uuid is the NULL uuid */
int uuid_is_null(const uuid_t uu)
{
const unsigned char *cp;
int i;
for (i=0, cp = uu; i < 16; i++)
if (*cp++)
return 0;
return 1;
}
glusterfs-3.4.2/contrib/uuid/pack.c 0000644 0000762 0000763 00000004305 12261516067 014164 0000000 0000000 /*
* Internal routine for packing UUID's
*
* Copyright (C) 1996, 1997 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#include
#include "uuidP.h"
void uuid_pack(const struct uuid *uu, uuid_t ptr)
{
uint32_t tmp;
unsigned char *out = ptr;
tmp = uu->time_low;
out[3] = (unsigned char) tmp;
tmp >>= 8;
out[2] = (unsigned char) tmp;
tmp >>= 8;
out[1] = (unsigned char) tmp;
tmp >>= 8;
out[0] = (unsigned char) tmp;
tmp = uu->time_mid;
out[5] = (unsigned char) tmp;
tmp >>= 8;
out[4] = (unsigned char) tmp;
tmp = uu->time_hi_and_version;
out[7] = (unsigned char) tmp;
tmp >>= 8;
out[6] = (unsigned char) tmp;
tmp = uu->clock_seq;
out[9] = (unsigned char) tmp;
tmp >>= 8;
out[8] = (unsigned char) tmp;
memcpy(out+10, uu->node, 6);
}
glusterfs-3.4.2/contrib/uuid/uuid.h 0000644 0000762 0000763 00000006316 12261516067 014225 0000000 0000000 /*
* Public include file for the UUID library
*
* Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#ifndef _UUID_UUID_H
#define _UUID_UUID_H
#include "config.h"
#include
#ifndef _WIN32
#include
#endif
#include
typedef unsigned char uuid_t[16];
/* UUID Variant definitions */
#define UUID_VARIANT_NCS 0
#define UUID_VARIANT_DCE 1
#define UUID_VARIANT_MICROSOFT 2
#define UUID_VARIANT_OTHER 3
/* UUID Type definitions */
#define UUID_TYPE_DCE_TIME 1
#define UUID_TYPE_DCE_RANDOM 4
/* Allow UUID constants to be defined */
#ifdef __GNUC__
#define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \
static const uuid_t name __attribute__ ((unused)) = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15}
#else
#define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \
static const uuid_t name = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15}
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* clear.c */
void uuid_clear(uuid_t uu);
/* compare.c */
int uuid_compare(const uuid_t uu1, const uuid_t uu2);
/* copy.c */
void uuid_copy(uuid_t dst, const uuid_t src);
/* gen_uuid.c */
void uuid_generate(uuid_t out);
void uuid_generate_random(uuid_t out);
void uuid_generate_time(uuid_t out);
/* isnull.c */
int uuid_is_null(const uuid_t uu);
/* parse.c */
int uuid_parse(const char *in, uuid_t uu);
/* unparse.c */
void uuid_unparse(const uuid_t uu, char *out);
void uuid_unparse_lower(const uuid_t uu, char *out);
void uuid_unparse_upper(const uuid_t uu, char *out);
/* uuid_time.c */
time_t uuid_time(const uuid_t uu, struct timeval *ret_tv);
int uuid_type(const uuid_t uu);
int uuid_variant(const uuid_t uu);
#ifdef __cplusplus
}
#endif
#endif /* _UUID_UUID_H */
glusterfs-3.4.2/contrib/uuid/compare.c 0000644 0000762 0000763 00000004171 12261516067 014675 0000000 0000000 /*
* compare.c --- compare whether or not two UUID's are the same
*
* Returns 0 if the two UUID's are different, and 1 if they are the same.
*
* Copyright (C) 1996, 1997 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#include "uuidP.h"
#include
#define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1);
int uuid_compare(const uuid_t uu1, const uuid_t uu2)
{
struct uuid uuid1, uuid2;
uuid_unpack(uu1, &uuid1);
uuid_unpack(uu2, &uuid2);
UUCMP(uuid1.time_low, uuid2.time_low);
UUCMP(uuid1.time_mid, uuid2.time_mid);
UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version);
UUCMP(uuid1.clock_seq, uuid2.clock_seq);
return memcmp(uuid1.node, uuid2.node, 6);
}
glusterfs-3.4.2/contrib/uuid/uuid_time.c 0000644 0000762 0000763 00000010352 12261516067 015231 0000000 0000000 /*
* uuid_time.c --- Interpret the time field from a uuid. This program
* violates the UUID abstraction barrier by reaching into the guts
* of a UUID and interpreting it.
*
* Copyright (C) 1998, 1999 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#ifdef _WIN32
#define _WIN32_WINNT 0x0500
#include
#define UUID MYUUID
#endif
#include
#ifdef HAVE_UNISTD_H
#include
#endif
#include
#include
#ifdef HAVE_SYS_TIME_H
#include
#endif
#include
#include "uuidP.h"
time_t uuid_time(const uuid_t uu, struct timeval *ret_tv)
{
struct timeval tv;
struct uuid uuid;
uint32_t high;
uint64_t clock_reg;
uuid_unpack(uu, &uuid);
high = uuid.time_mid | ((uuid.time_hi_and_version & 0xFFF) << 16);
clock_reg = uuid.time_low | ((uint64_t) high << 32);
clock_reg -= (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
tv.tv_sec = clock_reg / 10000000;
tv.tv_usec = (clock_reg % 10000000) / 10;
if (ret_tv)
*ret_tv = tv;
return tv.tv_sec;
}
int uuid_type(const uuid_t uu)
{
struct uuid uuid;
uuid_unpack(uu, &uuid);
return ((uuid.time_hi_and_version >> 12) & 0xF);
}
int uuid_variant(const uuid_t uu)
{
struct uuid uuid;
int var;
uuid_unpack(uu, &uuid);
var = uuid.clock_seq;
if ((var & 0x8000) == 0)
return UUID_VARIANT_NCS;
if ((var & 0x4000) == 0)
return UUID_VARIANT_DCE;
if ((var & 0x2000) == 0)
return UUID_VARIANT_MICROSOFT;
return UUID_VARIANT_OTHER;
}
#ifdef DEBUG
static const char *variant_string(int variant)
{
switch (variant) {
case UUID_VARIANT_NCS:
return "NCS";
case UUID_VARIANT_DCE:
return "DCE";
case UUID_VARIANT_MICROSOFT:
return "Microsoft";
default:
return "Other";
}
}
int
main(int argc, char **argv)
{
uuid_t buf;
time_t time_reg;
struct timeval tv;
int type, variant;
if (argc != 2) {
fprintf(stderr, "Usage: %s uuid\n", argv[0]);
exit(1);
}
if (uuid_parse(argv[1], buf)) {
fprintf(stderr, "Invalid UUID: %s\n", argv[1]);
exit(1);
}
variant = uuid_variant(buf);
type = uuid_type(buf);
time_reg = uuid_time(buf, &tv);
printf("UUID variant is %d (%s)\n", variant, variant_string(variant));
if (variant != UUID_VARIANT_DCE) {
printf("Warning: This program only knows how to interpret "
"DCE UUIDs.\n\tThe rest of the output is likely "
"to be incorrect!!\n");
}
printf("UUID type is %d", type);
switch (type) {
case 1:
printf(" (time based)\n");
break;
case 2:
printf(" (DCE)\n");
break;
case 3:
printf(" (name-based)\n");
break;
case 4:
printf(" (random)\n");
break;
default:
printf("\n");
}
if (type != 1) {
printf("Warning: not a time-based UUID, so UUID time "
"decoding will likely not work!\n");
}
printf("UUID time is: (%ld, %ld): %s\n", tv.tv_sec, tv.tv_usec,
ctime(&time_reg));
return 0;
}
#endif
glusterfs-3.4.2/contrib/uuid/uuidP.h 0000644 0000762 0000763 00000004064 12261516067 014343 0000000 0000000 /*
* uuid.h -- private header file for uuids
*
* Copyright (C) 1996, 1997 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#include "uuid.h"
#ifdef HAVE_INTTYPES_H
#include
#else
#include "uuid_types.h"
#endif
#include
/*
* Offset between 15-Oct-1582 and 1-Jan-70
*/
#define TIME_OFFSET_HIGH 0x01B21DD2
#define TIME_OFFSET_LOW 0x13814000
struct uuid {
uint32_t time_low;
uint16_t time_mid;
uint16_t time_hi_and_version;
uint16_t clock_seq;
uint8_t node[6];
};
/*
* prototypes
*/
void uuid_pack(const struct uuid *uu, uuid_t ptr);
void uuid_unpack(const uuid_t in, struct uuid *uu);
glusterfs-3.4.2/contrib/uuid/unpack.c 0000644 0000762 0000763 00000004051 12261516067 014525 0000000 0000000 /*
* Internal routine for unpacking UUID
*
* Copyright (C) 1996, 1997 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#include
#include "uuidP.h"
void uuid_unpack(const uuid_t in, struct uuid *uu)
{
const uint8_t *ptr = in;
uint32_t tmp;
tmp = *ptr++;
tmp = (tmp << 8) | *ptr++;
tmp = (tmp << 8) | *ptr++;
tmp = (tmp << 8) | *ptr++;
uu->time_low = tmp;
tmp = *ptr++;
tmp = (tmp << 8) | *ptr++;
uu->time_mid = tmp;
tmp = *ptr++;
tmp = (tmp << 8) | *ptr++;
uu->time_hi_and_version = tmp;
tmp = *ptr++;
tmp = (tmp << 8) | *ptr++;
uu->clock_seq = tmp;
memcpy(uu->node, ptr, 6);
}
glusterfs-3.4.2/contrib/uuid/unparse.c 0000644 0000762 0000763 00000004736 12261516067 014733 0000000 0000000 /*
* unparse.c -- convert a UUID to string
*
* Copyright (C) 1996, 1997 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#include
#include "uuidP.h"
static const char *fmt_lower =
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
static const char *fmt_upper =
"%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X";
#ifdef UUID_UNPARSE_DEFAULT_UPPER
#define FMT_DEFAULT fmt_upper
#else
#define FMT_DEFAULT fmt_lower
#endif
static void uuid_unparse_x(const uuid_t uu, char *out, const char *fmt)
{
struct uuid uuid;
uuid_unpack(uu, &uuid);
sprintf(out, fmt,
uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
uuid.node[0], uuid.node[1], uuid.node[2],
uuid.node[3], uuid.node[4], uuid.node[5]);
}
void uuid_unparse_lower(const uuid_t uu, char *out)
{
uuid_unparse_x(uu, out, fmt_lower);
}
void uuid_unparse_upper(const uuid_t uu, char *out)
{
uuid_unparse_x(uu, out, fmt_upper);
}
void uuid_unparse(const uuid_t uu, char *out)
{
uuid_unparse_x(uu, out, FMT_DEFAULT);
}
glusterfs-3.4.2/contrib/uuid/copy.c 0000644 0000762 0000763 00000003357 12261516067 014226 0000000 0000000 /*
* copy.c --- copy UUIDs
*
* Copyright (C) 1996, 1997 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#include "uuidP.h"
void uuid_copy(uuid_t dst, const uuid_t src)
{
unsigned char *cp1;
const unsigned char *cp2;
int i;
for (i=0, cp1 = dst, cp2 = src; i < 16; i++)
*cp1++ = *cp2++;
}
glusterfs-3.4.2/contrib/uuid/gen_uuid.c 0000644 0000762 0000763 00000036177 12261516067 015061 0000000 0000000 /*
* gen_uuid.c --- generate a DCE-compatible uuid
*
* Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
/*
* Force inclusion of SVID stuff since we need it if we're compiling in
* gcc-wall wall mode
*/
#define _SVID_SOURCE
#include "config.h"
#ifdef _WIN32
#define _WIN32_WINNT 0x0500
#include
#define UUID MYUUID
#endif
#include
#ifdef HAVE_UNISTD_H
#include
#endif
#ifdef HAVE_STDLIB_H
#include
#endif
#include
#include
#include
#include
#ifdef HAVE_SYS_TIME_H
#include
#endif
#include
#include
#ifdef HAVE_SYS_FILE_H
#include
#endif
#ifdef HAVE_SYS_IOCTL_H
#include
#endif
#ifdef HAVE_SYS_SOCKET_H
#include
#endif
#ifdef HAVE_SYS_UN_H
#include
#endif
#ifdef HAVE_SYS_SOCKIO_H
#include
#endif
#ifdef HAVE_NET_IF_H
#include
#endif
#ifdef HAVE_NETINET_IN_H
#include
#endif
#ifdef HAVE_NET_IF_DL_H
#include
#endif
#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
#include
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include
#endif
#include
#include "uuidP.h"
#include "uuidd.h"
#ifdef HAVE_SRANDOM
#define srand(x) srandom(x)
#define rand() random()
#endif
#ifdef TLS
#define THREAD_LOCAL static TLS
#else
#define THREAD_LOCAL static
#endif
#if defined(__linux__) && defined(__NR_gettid) && defined(HAVE_JRAND48)
#define DO_JRAND_MIX
THREAD_LOCAL unsigned short jrand_seed[3];
#endif
#ifndef OPEN_MAX
#define OPEN_MAX 1024
#endif
#ifdef _WIN32
static void gettimeofday (struct timeval *tv, void *dummy)
{
FILETIME ftime;
uint64_t n;
GetSystemTimeAsFileTime (&ftime);
n = (((uint64_t) ftime.dwHighDateTime << 32)
+ (uint64_t) ftime.dwLowDateTime);
if (n) {
n /= 10;
n -= ((369 * 365 + 89) * (uint64_t) 86400) * 1000000;
}
tv->tv_sec = n / 1000000;
tv->tv_usec = n % 1000000;
}
static int getuid (void)
{
return 1;
}
#endif
static int get_random_fd(void)
{
struct timeval tv;
static int fd = -2;
int i;
if (fd == -2) {
gettimeofday(&tv, 0);
#ifndef _WIN32
fd = open("/dev/urandom", O_RDONLY);
if (fd == -1)
fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
if (fd >= 0) {
i = fcntl(fd, F_GETFD);
if (i >= 0)
fcntl(fd, F_SETFD, i | FD_CLOEXEC);
}
#endif
srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
#ifdef DO_JRAND_MIX
jrand_seed[0] = getpid() ^ (tv.tv_sec & 0xFFFF);
jrand_seed[1] = getppid() ^ (tv.tv_usec & 0xFFFF);
jrand_seed[2] = (tv.tv_sec ^ tv.tv_usec) >> 16;
#endif
}
/* Crank the random number generator a few times */
gettimeofday(&tv, 0);
for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
rand();
return fd;
}
/*
* Generate a series of random bytes. Use /dev/urandom if possible,
* and if not, use srandom/random.
*/
static void get_random_bytes(void *buf, int nbytes)
{
int i, n = nbytes, fd = get_random_fd();
int lose_counter = 0;
unsigned char *cp = (unsigned char *) buf;
#ifdef DO_JRAND_MIX
unsigned short tmp_seed[3];
#endif
if (fd >= 0) {
while (n > 0) {
i = read(fd, cp, n);
if (i <= 0) {
if (lose_counter++ > 16)
break;
continue;
}
n -= i;
cp += i;
lose_counter = 0;
}
}
/*
* We do this all the time, but this is the only source of
* randomness if /dev/random/urandom is out to lunch.
*/
for (cp = buf, i = 0; i < nbytes; i++)
*cp++ ^= (rand() >> 7) & 0xFF;
#ifdef DO_JRAND_MIX
memcpy(tmp_seed, jrand_seed, sizeof(tmp_seed));
jrand_seed[2] = jrand_seed[2] ^ syscall(__NR_gettid);
for (cp = buf, i = 0; i < nbytes; i++)
*cp++ ^= (jrand48(tmp_seed) >> 7) & 0xFF;
memcpy(jrand_seed, tmp_seed,
sizeof(jrand_seed)-sizeof(unsigned short));
#endif
return;
}
/*
* Get the ethernet hardware address, if we can find it...
*
* XXX for a windows version, probably should use GetAdaptersInfo:
* http://www.codeguru.com/cpp/i-n/network/networkinformation/article.php/c5451
* commenting out get_node_id just to get gen_uuid to compile under windows
* is not the right way to go!
*/
static int get_node_id(unsigned char *node_id)
{
#ifdef HAVE_NET_IF_H
int sd;
struct ifreq ifr, *ifrp;
struct ifconf ifc;
char buf[1024];
int n, i;
unsigned char *a;
#ifdef HAVE_NET_IF_DL_H
struct sockaddr_dl *sdlp;
#endif
/*
* BSD 4.4 defines the size of an ifreq to be
* max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
* However, under earlier systems, sa_len isn't present, so the size is
* just sizeof(struct ifreq)
*/
#ifdef HAVE_SA_LEN
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
#define ifreq_size(i) max(sizeof(struct ifreq),\
sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
#else
#define ifreq_size(i) sizeof(struct ifreq)
#endif /* HAVE_SA_LEN*/
sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sd < 0) {
return -1;
}
memset(buf, 0, sizeof(buf));
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
close(sd);
return -1;
}
n = ifc.ifc_len;
for (i = 0; i < n; i+= ifreq_size(*ifrp) ) {
ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
#ifdef SIOCGIFHWADDR
if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
continue;
a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
#else
#ifdef SIOCGENADDR
if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
continue;
a = (unsigned char *) ifr.ifr_enaddr;
#else
#ifdef HAVE_NET_IF_DL_H
sdlp = (struct sockaddr_dl *) &ifrp->ifr_addr;
if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6))
continue;
a = (unsigned char *) &sdlp->sdl_data[sdlp->sdl_nlen];
#else
/*
* XXX we don't have a way of getting the hardware
* address
*/
close(sd);
return 0;
#endif /* HAVE_NET_IF_DL_H */
#endif /* SIOCGENADDR */
#endif /* SIOCGIFHWADDR */
if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
continue;
if (node_id) {
memcpy(node_id, a, 6);
close(sd);
return 1;
}
}
close(sd);
#endif
return 0;
}
/* Assume that the gettimeofday() has microsecond granularity */
#define MAX_ADJUSTMENT 10
static int get_clock(uint32_t *clock_high, uint32_t *clock_low,
uint16_t *ret_clock_seq, int *num)
{
THREAD_LOCAL int adjustment = 0;
THREAD_LOCAL struct timeval last = {0, 0};
THREAD_LOCAL int state_fd = -2;
THREAD_LOCAL FILE *state_f;
THREAD_LOCAL uint16_t clock_seq;
struct timeval tv;
struct flock fl;
uint64_t clock_reg;
mode_t save_umask;
int len;
if (state_fd == -2) {
save_umask = umask(0);
state_fd = open("/var/lib/libuuid/clock.txt",
O_RDWR|O_CREAT, 0660);
(void) umask(save_umask);
state_f = fdopen(state_fd, "r+");
if (!state_f) {
close(state_fd);
state_fd = -1;
}
}
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = 0;
if (state_fd >= 0) {
rewind(state_f);
while (fcntl(state_fd, F_SETLKW, &fl) < 0) {
if ((errno == EAGAIN) || (errno == EINTR))
continue;
fclose(state_f);
close(state_fd);
state_fd = -1;
break;
}
}
if (state_fd >= 0) {
unsigned int cl;
unsigned long tv1, tv2;
int a;
if (fscanf(state_f, "clock: %04x tv: %lu %lu adj: %d\n",
&cl, &tv1, &tv2, &a) == 4) {
clock_seq = cl & 0x3FFF;
last.tv_sec = tv1;
last.tv_usec = tv2;
adjustment = a;
}
}
if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
get_random_bytes(&clock_seq, sizeof(clock_seq));
clock_seq &= 0x3FFF;
gettimeofday(&last, 0);
last.tv_sec--;
}
try_again:
gettimeofday(&tv, 0);
if ((tv.tv_sec < last.tv_sec) ||
((tv.tv_sec == last.tv_sec) &&
(tv.tv_usec < last.tv_usec))) {
clock_seq = (clock_seq+1) & 0x3FFF;
adjustment = 0;
last = tv;
} else if ((tv.tv_sec == last.tv_sec) &&
(tv.tv_usec == last.tv_usec)) {
if (adjustment >= MAX_ADJUSTMENT)
goto try_again;
adjustment++;
} else {
adjustment = 0;
last = tv;
}
clock_reg = tv.tv_usec*10 + adjustment;
clock_reg += ((uint64_t) tv.tv_sec)*10000000;
clock_reg += (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
if (num && (*num > 1)) {
adjustment += *num - 1;
last.tv_usec += adjustment / 10;
adjustment = adjustment % 10;
last.tv_sec += last.tv_usec / 1000000;
last.tv_usec = last.tv_usec % 1000000;
}
if (state_fd > 0) {
rewind(state_f);
len = fprintf(state_f,
"clock: %04x tv: %016lu %08lu adj: %08d\n",
clock_seq, last.tv_sec, last.tv_usec, adjustment);
fflush(state_f);
if (ftruncate(state_fd, len) < 0) {
fprintf(state_f, " \n");
fflush(state_f);
}
rewind(state_f);
fl.l_type = F_UNLCK;
fcntl(state_fd, F_SETLK, &fl);
}
*clock_high = clock_reg >> 32;
*clock_low = clock_reg;
*ret_clock_seq = clock_seq;
return 0;
}
#if defined(USE_UUIDD) && defined(HAVE_SYS_UN_H)
static ssize_t read_all(int fd, char *buf, size_t count)
{
ssize_t ret;
ssize_t c = 0;
int tries = 0;
memset(buf, 0, count);
while (count > 0) {
ret = read(fd, buf, count);
if (ret <= 0) {
if ((errno == EAGAIN || errno == EINTR || ret == 0) &&
(tries++ < 5))
continue;
return c ? c : -1;
}
if (ret > 0)
tries = 0;
count -= ret;
buf += ret;
c += ret;
}
return c;
}
#endif
/*
* Close all file descriptors
*/
#if defined(USE_UUIDD) && defined(HAVE_SYS_UN_H)
static void close_all_fds(void)
{
int i, max;
#if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
max = sysconf(_SC_OPEN_MAX);
#elif defined(HAVE_GETDTABLESIZE)
max = getdtablesize();
#elif defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
struct rlimit rl;
getrlimit(RLIMIT_NOFILE, &rl);
max = rl.rlim_cur;
#else
max = OPEN_MAX;
#endif
for (i=0; i < max; i++) {
close(i);
if (i <= 2)
open("/dev/null", O_RDWR);
}
}
#endif
/*
* Try using the uuidd daemon to generate the UUID
*
* Returns 0 on success, non-zero on failure.
*/
static int get_uuid_via_daemon(int op, uuid_t out, int *num)
{
#if defined(USE_UUIDD) && defined(HAVE_SYS_UN_H)
char op_buf[64];
int op_len;
int s;
ssize_t ret;
int32_t reply_len = 0, expected = 16;
struct sockaddr_un srv_addr;
struct stat st;
pid_t pid;
static const char *uuidd_path = UUIDD_PATH;
static int access_ret = -2;
static int start_attempts = 0;
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
return -1;
srv_addr.sun_family = AF_UNIX;
strcpy(srv_addr.sun_path, UUIDD_SOCKET_PATH);
if (connect(s, (const struct sockaddr *) &srv_addr,
sizeof(struct sockaddr_un)) < 0) {
if (access_ret == -2)
access_ret = access(uuidd_path, X_OK);
if (access_ret == 0)
access_ret = stat(uuidd_path, &st);
if (access_ret == 0 && (st.st_mode & (S_ISUID | S_ISGID)) == 0)
access_ret = access(UUIDD_DIR, W_OK);
if (access_ret == 0 && start_attempts++ < 5) {
if ((pid = fork()) == 0) {
close_all_fds();
execl(uuidd_path, "uuidd", "-qT", "300",
(char *) NULL);
exit(1);
}
(void) waitpid(pid, 0, 0);
if (connect(s, (const struct sockaddr *) &srv_addr,
sizeof(struct sockaddr_un)) < 0)
goto fail;
} else
goto fail;
}
op_buf[0] = op;
op_len = 1;
if (op == UUIDD_OP_BULK_TIME_UUID) {
memcpy(op_buf+1, num, sizeof(*num));
op_len += sizeof(*num);
expected += sizeof(*num);
}
ret = write(s, op_buf, op_len);
if (ret < 1)
goto fail;
ret = read_all(s, (char *) &reply_len, sizeof(reply_len));
if (ret < 0)
goto fail;
if (reply_len != expected)
goto fail;
ret = read_all(s, op_buf, reply_len);
if (op == UUIDD_OP_BULK_TIME_UUID)
memcpy(op_buf+16, num, sizeof(int));
memcpy(out, op_buf, 16);
close(s);
return ((ret == expected) ? 0 : -1);
fail:
close(s);
#endif
return -1;
}
void uuid__generate_time(uuid_t out, int *num)
{
static unsigned char node_id[6];
static int has_init = 0;
struct uuid uu;
uint32_t clock_mid;
if (!has_init) {
if (get_node_id(node_id) <= 0) {
get_random_bytes(node_id, 6);
/*
* Set multicast bit, to prevent conflicts
* with IEEE 802 addresses obtained from
* network cards
*/
node_id[0] |= 0x01;
}
has_init = 1;
}
get_clock(&clock_mid, &uu.time_low, &uu.clock_seq, num);
uu.clock_seq |= 0x8000;
uu.time_mid = (uint16_t) clock_mid;
uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000;
memcpy(uu.node, node_id, 6);
uuid_pack(&uu, out);
}
void uuid_generate_time(uuid_t out)
{
#ifdef TLS
THREAD_LOCAL int num = 0;
THREAD_LOCAL struct uuid uu;
THREAD_LOCAL time_t last_time = 0;
time_t now;
if (num > 0) {
now = time(0);
if (now > last_time+1)
num = 0;
}
if (num <= 0) {
num = 1000;
if (get_uuid_via_daemon(UUIDD_OP_BULK_TIME_UUID,
out, &num) == 0) {
last_time = time(0);
uuid_unpack(out, &uu);
num--;
return;
}
num = 0;
}
if (num > 0) {
uu.time_low++;
if (uu.time_low == 0) {
uu.time_mid++;
if (uu.time_mid == 0)
uu.time_hi_and_version++;
}
num--;
uuid_pack(&uu, out);
return;
}
#else
if (get_uuid_via_daemon(UUIDD_OP_TIME_UUID, out, 0) == 0)
return;
#endif
uuid__generate_time(out, 0);
}
void uuid__generate_random(uuid_t out, int *num)
{
uuid_t buf;
struct uuid uu;
int i, n;
if (!num || !*num)
n = 1;
else
n = *num;
for (i = 0; i < n; i++) {
get_random_bytes(buf, sizeof(buf));
uuid_unpack(buf, &uu);
uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF)
| 0x4000;
uuid_pack(&uu, out);
out += sizeof(uuid_t);
}
}
void uuid_generate_random(uuid_t out)
{
int num = 1;
/* No real reason to use the daemon for random uuid's -- yet */
uuid__generate_random(out, &num);
}
/*
* This is the generic front-end to uuid_generate_random and
* uuid_generate_time. It uses uuid_generate_random only if
* /dev/urandom is available, since otherwise we won't have
* high-quality randomness.
*/
void uuid_generate(uuid_t out)
{
if (get_random_fd() >= 0)
uuid_generate_random(out);
else
uuid_generate_time(out);
}
glusterfs-3.4.2/contrib/uuid/uuid_types.h 0000644 0000762 0000763 00000002066 12261516131 015437 0000000 0000000 /*
* If linux/types.h is already been included, assume it has defined
* everything we need. (cross fingers) Other header files may have
* also defined the types that we need.
*/
#if (!defined(_STDINT_H) && !defined(_UUID_STDINT_H))
#define _UUID_STDINT_H
typedef unsigned char uint8_t;
typedef signed char int8_t;
#if (4 == 8)
typedef int int64_t;
typedef unsigned int uint64_t;
#elif (8 == 8)
typedef long int64_t;
typedef unsigned long uint64_t;
#elif (8 == 8)
#if defined(__GNUC__)
typedef __signed__ long long int64_t;
#else
typedef signed long long int64_t;
#endif
typedef unsigned long long uint64_t;
#endif
#if (4 == 2)
typedef int int16_t;
typedef unsigned int uint16_t;
#elif (2 == 2)
typedef short int16_t;
typedef unsigned short uint16_t;
#else
?==error: undefined 16 bit type
#endif
#if (4 == 4)
typedef int int32_t;
typedef unsigned int uint32_t;
#elif (8 == 4)
typedef long int32_t;
typedef unsigned long uint32_t;
#elif (2 == 4)
typedef short int32_t;
typedef unsigned short uint32_t;
#else
?== error: undefined 32 bit type
#endif
#endif
glusterfs-3.4.2/contrib/uuid/uuidd.h 0000644 0000762 0000763 00000004215 12261516067 014365 0000000 0000000 /*
* Definitions used by the uuidd daemon
*
* Copyright (C) 2007 Theodore Ts'o.
*
* %Begin-Header%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
* %End-Header%
*/
#ifndef _UUID_UUIDD_H
#define _UUID_UUIDD_H
#define UUIDD_DIR "/var/lib/libuuid"
#define UUIDD_SOCKET_PATH UUIDD_DIR "/request"
#define UUIDD_PIDFILE_PATH UUIDD_DIR "/uuidd.pid"
#define UUIDD_PATH "/usr/sbin/uuidd"
#define UUIDD_OP_GETPID 0
#define UUIDD_OP_GET_MAXOP 1
#define UUIDD_OP_TIME_UUID 2
#define UUIDD_OP_RANDOM_UUID 3
#define UUIDD_OP_BULK_TIME_UUID 4
#define UUIDD_OP_BULK_RANDOM_UUID 5
#define UUIDD_MAX_OP UUIDD_OP_BULK_RANDOM_UUID
extern void uuid__generate_time(uuid_t out, int *num);
extern void uuid__generate_random(uuid_t out, int *num);
#endif /* _UUID_UUID_H */
glusterfs-3.4.2/INSTALL 0000644 0000762 0000763 00000001615 12261516067 011526 0000000 0000000 Installation Instructions
*************************
Run ./configure after untaring the package.
bash# ./configure
GlusterFS configure summary
===========================
FUSE client : yes
Infiniband verbs : yes
epoll IO multiplex : yes
Berkeley-DB : yes
libglusterfsclient : yes
mod_glusterfs : yes
argp-standalone : no
The configure summary will tell you what all components will be built with
GlusterFS. Other than 'argp-standalone' if something else says 'no', that
feature in GlusterFS will not be built. 'argp-standalone' package will only
be used if the system doesn't have a proper argp package installed.
Now just run 'make' and later run 'make install' to install the package.
bash# make
bash# make install
Installation complete :-)
bash# glusterfs --version
Make sure your version is the latest from the release, and the one you
just installed :-)
glusterfs-3.4.2/cli/ 0000755 0000762 0000763 00000000000 12261516157 011321 5 0000000 0000000 glusterfs-3.4.2/cli/Makefile.am 0000644 0000762 0000763 00000000034 12261516067 013272 0000000 0000000 SUBDIRS = src
CLEANFILES =
glusterfs-3.4.2/cli/src/ 0000755 0000762 0000763 00000000000 12261516157 012110 5 0000000 0000000 glusterfs-3.4.2/cli/src/Makefile.am 0000644 0000762 0000763 00000002063 12261516067 014065 0000000 0000000 sbin_PROGRAMS = gluster
gluster_SOURCES = cli.c registry.c input.c cli-cmd.c cli-rl.c \
cli-cmd-volume.c cli-cmd-peer.c cli-rpc-ops.c cli-cmd-parser.c\
cli-cmd-system.c cli-cmd-misc.c cli-xml-output.c
if ENABLE_BD_XLATOR
gluster_SOURCES += cli-cmd-volume-bdevice.c
endif
gluster_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(GF_LDADD)\
$(RLLIBS) $(top_builddir)/rpc/xdr/src/libgfxdr.la \
$(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
$(GF_GLUSTERFS_LIBS) $(LIBXML2_LIBS)
gluster_LDFLAGS = $(GF_LDFLAGS)
noinst_HEADERS = cli.h cli-mem-types.h cli-cmd.h
AM_CPPFLAGS = $(GF_CPPFLAGS) \
-I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/rpc-lib/src\
-I$(top_srcdir)/rpc/xdr/src\
-DDATADIR=\"$(localstatedir)\" \
-DCONFDIR=\"$(sysconfdir)/glusterfs\" \
-DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\
-DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) -DSBIN_DIR=\"$(sbindir)\"\
$(LIBXML2_CFLAGS)
AM_CFLAGS = -Wall $(GF_GLUSTERFS_CFLAGS)
CLEANFILES =
$(top_builddir)/libglusterfs/src/libglusterfs.la:
$(MAKE) -C $(top_builddir)/libglusterfs/src/ all
glusterfs-3.4.2/cli/src/cli.c 0000644 0000762 0000763 00000036501 12261516067 012750 0000000 0000000 /*
Copyright (c) 2010-2012 Red Hat, Inc.
This file is part of GlusterFS.
This file is licensed to you under your choice of the GNU Lesser
General Public License, version 3 or any later version (LGPLv3 or
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_MALLOC_H
#include
#endif
#ifdef HAVE_MALLOC_STATS
#ifdef DEBUG
#include
#endif
#endif
#include "cli.h"
#include "cli-cmd.h"
#include "cli-mem-types.h"
#include "xlator.h"
#include "glusterfs.h"
#include "compat.h"
#include "logging.h"
#include "dict.h"
#include "list.h"
#include "timer.h"
#include "stack.h"
#include "revision.h"
#include "common-utils.h"
#include "event.h"
#include "globals.h"
#include "syscall.h"
#include "call-stub.h"
#include
#include "xdr-generic.h"
extern int connected;
/* using argp for command line parsing */
const char *argp_program_version = "" \
PACKAGE_NAME" "PACKAGE_VERSION" built on "__DATE__" "__TIME__ \
"\nRepository revision: " GLUSTERFS_REPOSITORY_REVISION "\n" \
"Copyright (c) 2006-2011 Gluster Inc. " \
"\n" \
"GlusterFS comes with ABSOLUTELY NO WARRANTY.\n" \
"You may redistribute copies of GlusterFS under the terms of "\
"the GNU General Public License.";
const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
struct rpc_clnt *global_rpc;
rpc_clnt_prog_t *cli_rpc_prog;
extern struct rpc_clnt_program cli_prog;
static int
glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
{
cmd_args_t *cmd_args = NULL;
struct rlimit lim = {0, };
call_pool_t *pool = NULL;
xlator_mem_acct_init (THIS, cli_mt_end);
ctx->process_uuid = generate_glusterfs_ctx_id ();
if (!ctx->process_uuid)
return -1;
ctx->page_size = 128 * GF_UNIT_KB;
ctx->iobuf_pool = iobuf_pool_new ();
if (!ctx->iobuf_pool)
return -1;
ctx->event_pool = event_pool_new (DEFAULT_EVENT_POOL_SIZE);
if (!ctx->event_pool)
return -1;
pool = GF_CALLOC (1, sizeof (call_pool_t),
cli_mt_call_pool_t);
if (!pool)
return -1;
/* frame_mem_pool size 112 * 64 */
pool->frame_mem_pool = mem_pool_new (call_frame_t, 32);
if (!pool->frame_mem_pool)
return -1;
/* stack_mem_pool size 256 * 128 */
pool->stack_mem_pool = mem_pool_new (call_stack_t, 16);
if (!pool->stack_mem_pool)
return -1;
ctx->stub_mem_pool = mem_pool_new (call_stub_t, 16);
if (!ctx->stub_mem_pool)
return -1;
ctx->dict_pool = mem_pool_new (dict_t, 32);
if (!ctx->dict_pool)
return -1;
ctx->dict_pair_pool = mem_pool_new (data_pair_t, 512);
if (!ctx->dict_pair_pool)
return -1;
ctx->dict_data_pool = mem_pool_new (data_t, 512);
if (!ctx->dict_data_pool)
return -1;
INIT_LIST_HEAD (&pool->all_frames);
LOCK_INIT (&pool->lock);
ctx->pool = pool;
pthread_mutex_init (&(ctx->lock), NULL);
cmd_args = &ctx->cmd_args;
INIT_LIST_HEAD (&cmd_args->xlator_options);
lim.rlim_cur = RLIM_INFINITY;
lim.rlim_max = RLIM_INFINITY;
setrlimit (RLIMIT_CORE, &lim);
return 0;
}
static int
logging_init (glusterfs_ctx_t *ctx, struct cli_state *state)
{
char *log_file = state->log_file ? state->log_file :
DEFAULT_CLI_LOG_FILE_DIRECTORY "/cli.log";
if (gf_log_init (ctx, log_file) == -1) {
fprintf (stderr, "ERROR: failed to open logfile %s\n",
log_file);
return -1;
}
/* CLI should not have something to DEBUG after the release,
hence defaulting to INFO loglevel */
gf_log_set_loglevel ((state->log_level == -1) ? GF_LOG_INFO :
state->log_level);
return 0;
}
int
cli_submit_request (void *req, call_frame_t *frame,
rpc_clnt_prog_t *prog,
int procnum, struct iobref *iobref,
xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
{
int ret = -1;
int count = 0;
struct iovec iov = {0, };
struct iobuf *iobuf = NULL;
char new_iobref = 0;
ssize_t xdr_size = 0;
GF_ASSERT (this);
if (req) {
xdr_size = xdr_sizeof (xdrproc, req);
iobuf = iobuf_get2 (this->ctx->iobuf_pool, xdr_size);
if (!iobuf) {
goto out;
};
if (!iobref) {
iobref = iobref_new ();
if (!iobref) {
goto out;
}
new_iobref = 1;
}
iobref_add (iobref, iobuf);
iov.iov_base = iobuf->ptr;
iov.iov_len = iobuf_size (iobuf);
/* Create the xdr payload */
ret = xdr_serialize_generic (iov, req, xdrproc);
if (ret == -1) {
goto out;
}
iov.iov_len = ret;
count = 1;
}
/* Send the msg */
ret = rpc_clnt_submit (global_rpc, prog, procnum, cbkfn,
&iov, count,
NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
ret = 0;
out:
if (new_iobref)
iobref_unref (iobref);
if (iobuf)
iobuf_unref (iobuf);
return ret;
}
int
cli_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
void *data)
{
xlator_t *this = NULL;
int ret = 0;
this = mydata;
switch (event) {
case RPC_CLNT_CONNECT:
{
cli_cmd_broadcast_connected ();
gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT");
break;
}
case RPC_CLNT_DISCONNECT:
{
gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT");
connected = 0;
if (!global_state->prompt && global_state->await_connected) {
ret = 1;
cli_out ("Connection failed. Please check if gluster "
"daemon is operational.");
exit (ret);
}
break;
}
default:
gf_log (this->name, GF_LOG_TRACE,
"got some other RPC event %d", event);
ret = 0;
break;
}
return ret;
}
/*
* ret: 0: option successfully processed
* 1: signalling end of option list
* -1: unknown option or other issue
*/
int
cli_opt_parse (char *opt, struct cli_state *state)
{
char *oarg;
if (strcmp (opt, "") == 0)
return 1;
if (strcmp (opt, "version") == 0) {
cli_out ("%s", argp_program_version);
exit (0);
}
if (strcmp (opt, "print-logdir") == 0) {
cli_out ("%s", DEFAULT_LOG_FILE_DIRECTORY);
exit (0);
}
if (strcmp (opt, "print-statedumpdir") == 0) {
cli_out ("%s", DEFAULT_VAR_RUN_DIRECTORY);
exit (0);
}
if (strcmp (opt, "xml") == 0) {
#if (HAVE_LIB_XML)
state->mode |= GLUSTER_MODE_XML;
#else
cli_err ("XML output not supported. Ignoring '--xml' option");
#endif
return 0;
}
oarg = strtail (opt, "mode=");
if (oarg) {
if (strcmp (oarg, "script") == 0) {
state->mode |= GLUSTER_MODE_SCRIPT;
return 0;
}
if (strcmp (oarg, "interactive") == 0)
return 0;
return -1;
}
oarg = strtail (opt, "remote-host=");
if (oarg) {
state->remote_host = oarg;
return 0;
}
oarg = strtail (opt, "log-file=");
if (oarg) {
state->log_file = oarg;
return 0;
}
oarg = strtail (opt, "log-level=");
if (oarg) {
state->log_level = glusterd_check_log_level(oarg);
if (state->log_level == -1)
return -1;
return 0;
}
return -1;
}
int
parse_cmdline (int argc, char *argv[], struct cli_state *state)
{
int ret = 0;
int i = 0;
int j = 0;
char *opt = NULL;
state->argc=argc-1;
state->argv=&argv[1];
for (i = 0; i < state->argc; i++) {
opt = strtail (state->argv[i], "--");
if (opt) {
ret = cli_opt_parse (opt, state);
if (ret == -1) {
cli_out ("unrecognized option --%s", opt);
return ret;
}
for (j = i; j < state->argc - 1; j++)
state->argv[j] = state->argv[j + 1];
state->argc--;
/* argv shifted, next check should be at i again */
i--;
if (ret == 1) {
/* end of cli options */
ret = 0;
break;
}
}
}
state->argv[state->argc] = NULL;
return ret;
}
int
cli_cmd_tree_init (struct cli_cmd_tree *tree)
{
struct cli_cmd_word *root = NULL;
int ret = 0;
root = &tree->root;
root->tree = tree;
return ret;
}
int
cli_state_init (struct cli_state *state)
{
struct cli_cmd_tree *tree = NULL;
int ret = 0;
state->remote_host = "localhost";
state->log_level = -1;
tree = &state->tree;
tree->state = state;
ret = cli_cmd_tree_init (tree);
return ret;
}
int
cli_usage_out (const char *usage)
{
GF_ASSERT (usage);
GF_ASSERT (usage[0] != '\0');
if (!usage || usage[0] == '\0')
return -1;
cli_err ("Usage: %s", usage);
return 0;
}
int
_cli_err (const char *fmt, ...)
{
struct cli_state *state = NULL;
va_list ap;
int ret = 0;
state = global_state;
va_start (ap, fmt);
#ifdef HAVE_READLINE
if (state->rl_enabled && !state->rl_processing)
return cli_rl_err(state, fmt, ap);
#endif
ret = vfprintf (stderr, fmt, ap);
fprintf (stderr, "\n");
va_end (ap);
return ret;
}
int
_cli_out (const char *fmt, ...)
{
struct cli_state *state = NULL;
va_list ap;
int ret = 0;
state = global_state;
va_start (ap, fmt);
#ifdef HAVE_READLINE
if (state->rl_enabled && !state->rl_processing)
return cli_rl_out(state, fmt, ap);
#endif
ret = vprintf (fmt, ap);
printf ("\n");
va_end (ap);
return ret;
}
struct rpc_clnt *
cli_rpc_init (struct cli_state *state)
{
struct rpc_clnt *rpc = NULL;
dict_t *options = NULL;
int ret = -1;
int port = CLI_GLUSTERD_PORT;
xlator_t *this = NULL;
this = THIS;
cli_rpc_prog = &cli_prog;
options = dict_new ();
if (!options)
goto out;
ret = dict_set_str (options, "remote-host", state->remote_host);
if (ret)
goto out;
if (state->remote_port)
port = state->remote_port;
ret = dict_set_int32 (options, "remote-port", port);
if (ret)
goto out;
ret = dict_set_str (options, "transport.address-family", "inet");
if (ret)
goto out;
rpc = rpc_clnt_new (options, this->ctx, this->name, 16);
if (!rpc)
goto out;
ret = rpc_clnt_register_notify (rpc, cli_rpc_notify, this);
if (ret) {
gf_log ("cli", GF_LOG_ERROR, "failed to register notify");
goto out;
}
rpc_clnt_start (rpc);
out:
if (ret) {
if (rpc)
rpc_clnt_unref (rpc);
rpc = NULL;
}
return rpc;
}
cli_local_t *
cli_local_get ()
{
cli_local_t *local = NULL;
local = GF_CALLOC (1, sizeof (*local), cli_mt_cli_local_t);
return local;
}
void
cli_local_wipe (cli_local_t *local)
{
if (local) {
GF_FREE (local->get_vol.volname);
if (local->dict)
dict_unref (local->dict);
GF_FREE (local);
}
return;
}
struct cli_state *global_state;
int
main (int argc, char *argv[])
{
struct cli_state state = {0, };
int ret = -1;
glusterfs_ctx_t *ctx = NULL;
ctx = glusterfs_ctx_new ();
if (!ctx)
return ENOMEM;
#ifdef DEBUG
gf_mem_acct_enable_set (ctx);
#endif
ret = glusterfs_globals_init (ctx);
if (ret)
return ret;
THIS->ctx = ctx;
ret = glusterfs_ctx_defaults_init (ctx);
if (ret)
goto out;
ret = cli_state_init (&state);
if (ret)
goto out;
state.ctx = ctx;
global_state = &state;
ret = parse_cmdline (argc, argv, &state);
if (ret)
goto out;
ret = logging_init (ctx, &state);
if (ret)
goto out;
global_rpc = cli_rpc_init (&state);
if (!global_rpc)
goto out;
ret = cli_cmds_register (&state);
if (ret)
goto out;
ret = cli_cmd_cond_init ();
if (ret)
goto out;
ret = cli_input_init (&state);
if (ret)
goto out;
ret = event_dispatch (ctx->event_pool);
out:
// glusterfs_ctx_destroy (ctx);
return ret;
}
void
cli_print_line (int len)
{
GF_ASSERT (len > 0);
while (len--)
printf ("-");
printf ("\n");
}
glusterfs-3.4.2/cli/src/input.c 0000644 0000762 0000763 00000004376 12261516067 013345 0000000 0000000 /*
Copyright (c) 2010-2012 Red Hat, Inc.
This file is part of GlusterFS.
This file is licensed to you under your choice of the GNU Lesser
General Public License, version 3 or any later version (LGPLv3 or
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
*/
#include
#include
#include
#include
#include
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif
#include "cli.h"
#include "cli-mem-types.h"
#define CMDBUFSIZ 1024
void *
cli_batch (void *d)
{
struct cli_state *state = NULL;
int ret = 0;
state = d;
ret = cli_cmd_process (state, state->argc, state->argv);
gf_log ("", GF_LOG_INFO, "Exiting with: %d", ret);
exit (-ret);
return NULL;
}
void *
cli_input (void *d)
{
struct cli_state *state = NULL;
int ret = 0;
char cmdbuf[CMDBUFSIZ];
char *cmd = NULL;
size_t len = 0;
state = d;
for (;;) {
printf ("%s", state->prompt);
cmd = fgets (cmdbuf, CMDBUFSIZ, stdin);
if (!cmd)
break;
len = strlen(cmd);
if (len > 0 && cmd[len - 1] == '\n') //strip trailing \n
cmd[len - 1] = '\0';
ret = cli_cmd_process_line (state, cmd);
if (ret != 0 && state->mode & GLUSTER_MODE_ERR_FATAL)
break;
}
exit (-ret);
return NULL;
}
int
cli_input_init (struct cli_state *state)
{
int ret = 0;
if (state->argc) {
ret = pthread_create (&state->input, NULL, cli_batch, state);
return ret;
}
if (isatty (STDIN_FILENO)) {
state->prompt = "gluster> ";
cli_rl_enable (state);
} else {
state->prompt = "";
state->mode = GLUSTER_MODE_SCRIPT | GLUSTER_MODE_ERR_FATAL;
}
if (!state->rl_enabled)
ret = pthread_create (&state->input, NULL, cli_input, state);
return ret;
}
glusterfs-3.4.2/cli/src/cli-cmd-system.c 0000644 0000762 0000763 00000030340 12261516067 015026 0000000 0000000 /*
Copyright (c) 2010-2012 Red Hat, Inc.
This file is part of GlusterFS.
This file is licensed to you under your choice of the GNU Lesser
General Public License, version 3 or any later version (LGPLv3 or
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
*/
#include
#include
#include
#include
#include
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif
#include "cli.h"
#include "cli-cmd.h"
#include "cli-mem-types.h"
#include "protocol-common.h"
extern struct rpc_clnt *global_rpc;
extern rpc_clnt_prog_t *cli_rpc_prog;
int cli_cmd_system_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount);
int
cli_cmd_getspec_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
dict_t *dict = NULL;
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
dict = dict_new ();
if (!dict)
goto out;
if (wordcount != 3) {
cli_usage_out (word->pattern);
goto out;
}
ret = dict_set_str (dict, "volid", (char *)words[2]);
if (ret)
goto out;
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GETSPEC];
if (proc->fn) {
ret = proc->fn (frame, THIS, dict);
}
out:
if (!proc && ret) {
if (dict)
dict_destroy (dict);
if (wordcount > 1)
cli_out ("Fetching spec for volume %s failed",
(char *)words[2]);
}
return ret;
}
int
cli_cmd_pmap_b2p_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
dict_t *dict = NULL;
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
dict = dict_new ();
if (!dict)
goto out;
if (wordcount != 4) {
cli_usage_out (word->pattern);
goto out;
}
ret = dict_set_str (dict, "brick", (char *)words[3]);
if (ret)
goto out;
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_PMAP_PORTBYBRICK];
if (proc->fn) {
ret = proc->fn (frame, THIS, dict);
}
out:
if (!proc && ret) {
if (dict)
dict_destroy (dict);
if (wordcount > 1)
cli_out ("Fetching spec for volume %s failed",
(char *)words[3]);
}
return ret;
}
int
cli_cmd_fsm_log_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
char *name = "";
if ((wordcount != 4) && (wordcount != 3)) {
cli_usage_out (word->pattern);
goto out;
}
if (wordcount == 4)
name = (char*)words[3];
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_FSM_LOG];
if (proc && proc->fn) {
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
ret = proc->fn (frame, THIS, (void*)name);
}
out:
return ret;
}
int
cli_cmd_getwd_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
if (wordcount != 2) {
cli_usage_out (word->pattern);
goto out;
}
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GETWD];
if (proc && proc->fn) {
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
ret = proc->fn (frame, THIS, NULL);
}
out:
return ret;
}
static dict_t *
make_seq_dict (int argc, char **argv)
{
char index[] = "4294967296"; // 1<<32
int i = 0;
int ret = 0;
dict_t *dict = dict_new ();
if (!dict)
return NULL;
for (i = 0; i < argc; i++) {
snprintf(index, sizeof(index), "%d", i);
ret = dict_set_str (dict, index, argv[i]);
if (ret == -1)
break;
}
if (ret) {
dict_destroy (dict);
dict = NULL;
}
return dict;
}
int
cli_cmd_mount_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
int ret = -1;
dict_t *dict = NULL;
void *dataa[] = {NULL, NULL};
if (wordcount < 4) {
cli_usage_out (word->pattern);
goto out;
}
dict = make_seq_dict (wordcount - 3, (char **)words + 3);
if (!dict)
goto out;
dataa[0] = (void *)words[2];
dataa[1] = dict;
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_MOUNT];
if (proc && proc->fn) {
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
ret = proc->fn (frame, THIS, dataa);
}
out:
if (dict)
dict_unref (dict);
if (!proc && ret)
cli_out ("Mount command failed");
return ret;
}
int
cli_cmd_umount_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
int ret = -1;
dict_t *dict = NULL;
if (!(wordcount == 3 ||
(wordcount == 4 && strcmp (words[3], "lazy") == 0))) {
cli_usage_out (word->pattern);
goto out;
}
dict = dict_new ();
if (!dict)
goto out;
ret = dict_set_str (dict, "path", (char *)words[2]);
if (ret != 0)
goto out;
ret = dict_set_int32 (dict, "lazy", wordcount == 4);
if (ret != 0)
goto out;
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_UMOUNT];
if (proc && proc->fn) {
frame = create_frame (THIS, THIS->ctx->pool);
if (!frame)
goto out;
ret = proc->fn (frame, THIS, dict);
}
out:
if (dict)
dict_unref (dict);
if (!proc && ret)
cli_out ("Umount command failed");
return ret;
}
int
cli_cmd_uuid_get_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
int sent = 0;
int parse_error = 0;
dict_t *dict = NULL;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
cli_local_t *local = NULL;
xlator_t *this = NULL;
this = THIS;
if (wordcount != 3) {
cli_usage_out (word->pattern);
parse_error = 1;
goto out;
}
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_UUID_GET];
frame = create_frame (this, this->ctx->pool);
if (!frame)
goto out;
dict = dict_new ();
if (!dict)
goto out;
CLI_LOCAL_INIT (local, words, frame, dict);
if (proc->fn)
ret = proc->fn (frame, this, dict);
out:
if (ret) {
cli_cmd_sent_status_get (&sent);
if ((sent == 0) && (parse_error == 0))
cli_out ("uuid get failed");
}
if (dict)
dict_unref (dict);
CLI_STACK_DESTROY (frame);
return ret;
}
int
cli_cmd_uuid_reset_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
{
int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
int sent = 0;
int parse_error = 0;
gf_answer_t answer = GF_ANSWER_NO;
char *question = NULL;
cli_local_t *local = NULL;
dict_t *dict = NULL;
xlator_t *this = NULL;
question = "Resetting uuid changes the uuid of local glusterd. "
"Do you want to continue?";
if (wordcount != 3) {
cli_usage_out (word->pattern);
parse_error = 1;
goto out;
}
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_UUID_RESET];
this = THIS;
frame = create_frame (this, this->ctx->pool);
if (!frame)
goto out;
dict = dict_new ();
if (!dict) {
ret = -1;
goto out;
}
CLI_LOCAL_INIT (local, words, frame, dict);
answer = cli_cmd_get_confirmation (state, question);
if (GF_ANSWER_NO == answer) {
ret = 0;
goto out;
}
//send NULL as argument since no dictionary is sent to glusterd
if (proc->fn) {
ret = proc->fn (frame, this, dict);
}
out:
if (ret) {
cli_cmd_sent_status_get (&sent);
if ((sent == 0) && (parse_error == 0))
cli_out ("uuid reset failed");
}
CLI_STACK_DESTROY (frame);
return ret;
}
struct cli_cmd cli_system_cmds[] = {
{ "system:: getspec ",
cli_cmd_getspec_cbk,
"fetch spec for volume "},
{ "system:: portmap brick2port ",
cli_cmd_pmap_b2p_cbk,
"query which port listens on"},
{ "system:: fsm log []",
cli_cmd_fsm_log_cbk,
"display fsm transitions"},
{ "system:: getwd",
cli_cmd_getwd_cbk,
"query glusterd work directory"},
{ "system:: mount