network/lizardfs: Added (GPLv3 implementation of GoogleFS).

Signed-off-by: David Spencer <idlemoor@slackbuilds.org>
This commit is contained in:
Marcin Szychowski 2018-02-27 09:39:29 +00:00 committed by Willy Sudiarto Raharjo
parent da1cfc02cf
commit 16e19b7f76
11 changed files with 718 additions and 0 deletions

55
network/lizardfs/README Normal file
View file

@ -0,0 +1,55 @@
LizardFS is a highly scalable, fault-tolerant, POSIX-compatible, FUSE-based,
high performance distributed filesystem, licensed under GNU General Public
License version 3.
LizardFS is an implementation of GoogleFS, and a fork of the earlier project,
MooseFS. LizardFS supports writable snapshots (instant copies), undeleting
files, automatic data rebalancing, self-healing, data tiering, periodic data
patrols and many more.
LizardFS system consists of a master server, one or more metadata logging
servers (meta loggers), and many chunk servers, that store the data on their
locally-attached drives. Both meta loggers and chunk servers can be added and
removed without restarting the master server.
Filesystem metadata is stored on the master server (and constantly replicated
to meta loggers), whereas filesystem data is divided into chunks and spread as
files over chunk servers, according to pre-defined 'goals', which can be set
on file-, directory-, or filesystem level. A goal can be an n-way mirroring
goal, n+1 xor-ed goal (each chunk divided into n parts and xor-ed to calculate
one part of redundancy), or more sophisticated, erasure code based n+k
redundancy, where n parts of each chunk are backed by k parts of redundancy
data.
A set of administrative commands exists to support querying and setting
redundancy goals and trash preservation time. LizardFS is admin-friendly since
any missing chunks can be provided from any sort of backup to any running
chunk server.
This package contains all binaries needed to run LizardFS system: mfsmaster,
mfsmetalogger, mfschunkserver, as well as lizardfs-cgiserver (web-based
monitoring console).
You need an "mfs" user and group prior to building lizardfs. Something like
this will suffice for most systems:
groupadd -g 353 mfs
useradd -u 353 -g 353 -d /var/lib/mfs mfs
Feel free to use a different uid and gid if desired, but 353 is recommended to
avoid conflicts with other stuff from SlackBuilds.org.
It is also advisable to make name 'mfsmaster' pointing at your Master server
across your network. It is not strictly required, but it will make things much
easier. If you are unable to configure your DNS server, adding this line to
/etc/hosts on each master, metalogger, chunkserver, and client machines will
do:
a.b.c.d mfsmaster mfsmaster.my-domain.ext
where a.b.c.d is an IP address of your master server.
Then on each node add '/etc/rc.d/rc.lizardfs start' to /etc/rc.d/rc.local (or
wherever you find appropriate), and use '/etc/rc.d/rc.lizardfs setup' to
configure which services should run on the server. Since most installations
consists mostly of chunkservers, rc.lizardfs-chunkserver is marked executable
by default (but will not run until rc.lizardfs-chunkserver or rc.lizardfs is
added to rc.local, so no need to worry).

View file

@ -0,0 +1,31 @@
config() {
NEW="$1"
OLD="$(dirname $NEW)/$(basename $NEW .new)"
# If there's no config file by that name, mv it over:
if [ ! -r $OLD ]; then
mv $NEW $OLD
elif [ "$(cat $OLD | md5sum)" = "$(cat $NEW | md5sum)" ]; then
# toss the redundant copy
rm $NEW
fi
# Otherwise, we leave the .new copy for the admin to consider...
}
config etc/mfs/mfschunkserver.cfg.new
config etc/mfs/mfshdd.cfg.new
config etc/mfs/mfsmetalogger.cfg.new
config etc/mfs/mfsmaster.cfg.new
config etc/mfs/mfsexports.cfg.new
config etc/mfs/mfstopology.cfg.new
config etc/mfs/mfsmount.cfg.new
config etc/mfs/globaliolimits.cfg.new
config etc/mfs/iolimits.cfg.new
config etc/mfs/mfsgoals.cfg.new
config etc/rc.d/rc.lizardfs.new
config etc/rc.d/rc.lizardfs-chunkserver.new
config etc/rc.d/rc.lizardfs-cgiserv.new
config etc/rc.d/rc.lizardfs-master.new
config etc/rc.d/rc.lizardfs-metalogger.new
config var/log/setup/setup.lizardfs-services.new

View file

@ -0,0 +1,149 @@
#!/bin/sh
# Slackware build script for LizardFS
# Copyright 2018 Marcin Szychowski <szycha@gmail.com>
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 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
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
PRGNAM=lizardfs
VERSION=${VERSION:-3.12.0}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
LIZARDFS_UID=${LIZARDFS_UID:-353}
LIZARDFS_GID=${LIZARDFS_GID:-353}
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
i?86) ARCH=i586 ;;
arm*) ARCH=arm ;;
*) ARCH=$( uname -m ) ;;
esac
fi
CWD=$(pwd)
TMP=${TMP:-/tmp/SBo}
PKG=$TMP/package-$PRGNAM
OUTPUT=${OUTPUT:-/tmp}
# Bail out if user or group isn't valid on your system
# For slackbuilds.org, assigned mfs uid/gid are 353/353
# See http://slackbuilds.org/uid_gid.txt
if ! getent group mfs 2>&1 > /dev/null; then
echo " You must have a mfs group to run this script."
echo " # groupadd -g $LIZARDFS_GID mfs"
exit 1
elif ! getent passwd mfs 2>&1 > /dev/null; then
echo " You must have a mfs user to run this script."
echo " # useradd -u $LIZARDFS_UID -g $LIZARDFS_GID -d /var/lib/pgsql mfs"
exit 1
fi
if [ "$ARCH" = "i586" ]; then
SLKCFLAGS="-O2 -march=i586 -mtune=i686"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "i686" ]; then
SLKCFLAGS="-O2 -march=i686 -mtune=i686"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
SLKCFLAGS="-O2 -fPIC"
LIBDIRSUFFIX="64"
else
SLKCFLAGS="-O2"
LIBDIRSUFFIX=""
fi
set -e
rm -rf $PKG
mkdir -p $TMP $PKG $OUTPUT
cd $TMP
rm -rf $PRGNAM-$VERSION
tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
cd $PRGNAM-$VERSION
for z in $CWD/*.zip; do
unzip $z -d external/
done
chown -R root:root .
find -L . \
\( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
-o -perm 511 \) -exec chmod 755 {} \; -o \
\( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
-o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
mkdir -p build
cd build
cmake \
-DCMAKE_C_FLAGS:STRING="$SLKCFLAGS" \
-DCMAKE_CXX_FLAGS:STRING="$SLKCFLAGS" \
-DCMAKE_INSTALL_PREFIX=/ \
-DENABLE_DEBIAN_PATHS=YES \
-DENABLE_TESTS=NO \
-DENABLE_DOCS=YES \
-DENABLE_OFFICIAL_BUILD=NO \
-DSET_RC_BUILD_NUMBER=NO \
-DENABLE_CLIENT_LIB=YES \
-DENABLE_NFS_GANESHA=YES \
-DCMAKE_BUILD_TYPE=Release ..
make
make install DESTDIR=$PKG
cd ..
find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
mv $PKG/usr/share/man $PKG/usr/
find $PKG/usr/man -type f -exec gzip -9 {} \;
for i in $( find $PKG/usr/man -type l ) ; do ln -s $( readlink $i ).gz $i.gz ; rm $i ; done
for d in chunkserver exports goals hdd master metalogger mount topology; do
mv $PKG/etc/mfs/mfs$d.cfg.dist $PKG/etc/mfs/mfs$d.cfg.new
done
for l in '' global; do
mv $PKG/etc/mfs/${l}iolimits.cfg.dist $PKG/etc/mfs/${l}iolimits.cfg.new
done
mkdir -p $PKG/var/run/mfs $PKG/var/lib/mfs
chown mfs:mfs $PKG/var/run/mfs $PKG/var/lib/mfs
mkdir -p $PKG/etc/rc.d
cp -a $CWD/rc.lizardfs-cgiserv.new $CWD/rc.lizardfs-chunkserver.new \
$CWD/rc.lizardfs-master.new $CWD/rc.lizardfs-metalogger.new \
$CWD/rc.lizardfs.new $PKG/etc/rc.d/
mkdir -p $PKG/var/log/setup
cp -a $CWD/setup.lizardfs-services.new $PKG/var/log/setup/
chmod +x $PKG/var/log/setup/setup.lizardfs-services.new \
$PKG/etc/rc.d/rc.lizardfs-chunkserver.new
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
cp -a \
COPYING INSTALL NEWS README.md UPGRADE ReleaseNotes \
$PKG/usr/doc/$PRGNAM-$VERSION
cat $CWD/README > $PKG/usr/doc/$PRGNAM-$VERSION/README.SBo
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
mkdir -p $PKG/install
cat $CWD/slack-desc > $PKG/install/slack-desc
cat $CWD/doinst.sh > $PKG/install/doinst.sh
cd $PKG
/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-tgz}

View file

@ -0,0 +1,16 @@
PRGNAM="lizardfs"
VERSION="3.12.0"
HOMEPAGE="http://lizardfs.org"
DOWNLOAD="https://github.com/lizardfs/lizardfs/archive/v3.12.0/lizardfs-3.12.0.tar.gz \
https://github.com/nfs-ganesha/nfs-ganesha/archive/V2.5-stable/nfs-ganesha-2.5-stable.zip \
https://github.com/nfs-ganesha/ntirpc/archive/v1.5/ntirpc-1.5.zip \
https://github.com/gabime/spdlog/archive/v0.14.0/spdlog-0.14.0.zip"
MD5SUM="e584aa9534f900ca04d40a4772e01302 \
2a63aeff51df42fa76e4d40a5672219e \
af615a75e656e8cc0b107aee9b2c25ab \
f213d83c466aa7044a132e2488d71b11"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES=""
MAINTAINER="Marcin Szychowski"
EMAIL="szycha@gmail.com"

View file

@ -0,0 +1,72 @@
#!/bin/sh
#
# /etc/rc.d/rc.lizardfs-cgiserv
#
# Init file for the LizardFS web console service
# Adapted for Slackware Linux by Marcin Szychowski <szycha@gmail.com>
#
# See mfscgiserv(8) for more information.
# For general information on LizardFS, see mfs(7) or visit
# http://lizardfs.org/
# Source function library.
. /etc/init.d/functions
MFSCGISERV_USER=nobody
RETVAL=0
prog="lizardfs-cgiserver"
start () {
echo -n $"Starting $prog: "
/bin/su -s /bin/bash -c "/usr/sbin/$prog > /dev/null 2>&1 &" $MFSCGISERV_USER
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
touch /var/lock/subsys/$prog
echo '...done'
else
echo '...failed!'
fi
return $RETVAL
}
stop () {
echo -n $"Stopping $prog: "
fuser -kn tcp 9425 >/dev/null 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
rm -f /var/lock/subsys/$prog
fi
echo '...done'
return $RETVAL
}
restart () {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
restart
;;
condrestart)
[ -e /var/lock/subsys/$prog ] && restart
RETVAL=$?
;;
status)
status $prog
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
RETVAL=1
esac
exit $RETVAL

View file

@ -0,0 +1,76 @@
#!/bin/sh
#
# /etc/rc.d/rc.lizardfs-chunkserver
#
# Init file for the LizardFS chunkserver service
# Adapted for Slackware Linux by Marcin Szychowski <szycha@gmail.com>
#
# NOTE: This script is executable by default, BUT it will not start
# unless its' parent script (rc.lizardfs) is enabled first.
# This is for big sites admin convenience. You are safe with it.
# See rc.lizardfs and lizardfs(7) for details.
# Source function library.
. /etc/init.d/functions
RETVAL=0
prog=mfschunkserver
if [ ! -r "/etc/mfs/mfshdd.cfg" ]; then
echo $prog will not run: /etc/mfs/mfshdd.cfg file is missing
exit 1
fi
start () {
echo -n $"Starting $prog: "
daemon $prog >/dev/null 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
touch /var/lock/subsys/$prog
echo '...done'
else
echo '...failed! (check syslog for details)'
fi
return $RETVAL
}
stop () {
echo -n $"Stopping $prog: "
$prog stop >/dev/null 2>&1 || killproc $prog >/dev/null 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
rm -f /var/lock/subsys/$prog
fi
echo '...done'
return $RETVAL
}
restart () {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
restart
;;
condrestart)
[ -e /var/lock/subsys/$prog ] && restart
RETVAL=$?
;;
status)
status $prog
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
RETVAL=1
esac
exit $RETVAL

View file

@ -0,0 +1,70 @@
#!/bin/sh
#
# Init file for the LizardFS master service
# Adapted for Slackware Linux by Marcin Szychowski <szycha@gmail.com>
#
#
# Source function library.
. /etc/init.d/functions
RETVAL=0
prog="mfsmaster"
if [ ! -r "/etc/mfs/mfsexports.cfg" ]; then
echo $prog will not run: /etc/mfs/mfsexports.cfg file is missing
exit 1
fi
start () {
echo -n $"Starting $prog: "
daemon $prog >/dev/null 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
touch /var/lock/subsys/$prog
echo '...done'
else
echo '...failed! (check syslog for details)'
fi
return $RETVAL
}
stop () {
echo -n $"Stopping $prog: "
$prog stop >/dev/null 2>&1 || killproc $prog >/dev/null 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
rm -f /var/lock/subsys/$prog
fi
echo '...done'
return $RETVAL
}
restart () {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
restart
;;
condrestart)
[ -e /var/lock/subsys/$prog ] && restart
RETVAL=$?
;;
status)
status $prog
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
RETVAL=1
esac
exit $RETVAL

View file

@ -0,0 +1,70 @@
#!/bin/bash
#
# /etc/rc.d/rc.lizardfs-metalogger
#
# Init file for the LizardFS metalogger service
# Adapted for Slackware Linux by Marcin Szychowski <szycha@gmail.com>
#
# See mfsmetalogger(8) for more information.
# For general information on LizardFS, see /etc/rc.d/rc.lizardfs, lizardfs(7)
# or visit http://lizardfs.org/
# Source function library.
. /etc/init.d/functions
RETVAL=0
prog="mfsmetalogger"
start () {
echo -n $"Starting $prog: "
daemon $prog >/dev/null 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
touch /var/lock/subsys/$prog
echo '...done'
else
echo '...failed! (check syslog for details)'
fi
return $RETVAL
}
stop () {
echo -n $"Stopping $prog: "
$prog stop >/dev/null 2>&1 || killproc $prog >/dev/null 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
rm -f /var/lock/subsys/$prog
fi
echo '...done'
return $RETVAL
}
restart () {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
restart
;;
condrestart)
[ -e /var/lock/subsys/$prog ] && restart
RETVAL=$?
;;
status)
status $prog
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
RETVAL=1
esac
exit $RETVAL

View file

@ -0,0 +1,66 @@
#!/bin/sh
# Init script file for LizardFS (or MooseFS) system.
# Written for Slackware Linux by Marcin Szychowski <szycha@gmail.com>
# This script starts enabled LizardFS services.
#
# LizardFS is a distributed, self-healing, self-replicating filesystem,
# available under GNU GPLv3 License for any FUSE-capable operating system.
#
# Typical LizardFS installation consists of one master server, one or
# more meta-loggers and any number of chunk servers (the more the better).
# lizardfs Slackware Package contains software to run any of them.
#
# Although it is possible to run entire LizardFS system within one host
# you should not mix their roles across machines in a production
# environment. Especially you should not run anything along with master
# server process on the same machine.
# For more details refer to lizardfs(7) manual page or LizardFS website
# http://lizardfs.org/
#
# Enable this script to start/stop/restart all enabled services in a convenient
# way rather than run services directly. For your convenience,
# rc.lizardfs-chunkserver is enabled (executable) by default, since
# chunkservers are dominant group in average LizardFS installation.
services="master cgiserv metalogger chunkserver"
function everyone() {
action="$1"
if [ "$action" = "stop" ]; then
local services="$(echo $services|tr ' ' "\n"|tac)"
fi
for svc in $services; do
if [ -x /etc/rc.d/rc.lizardfs-$svc ]; then
/etc/rc.d/rc.lizardfs-$svc $action
fi
done
}
case "$1" in
'start')
everyone start
;;
'stop')
everyone stop
;;
'restart')
everyone stop
everyone start
;;
'condrestart')
everyone condrestart
;;
'status')
everyone status
;;
'setup')
/var/log/setup/setup.lizardfs-services
;;
*)
echo "Usage: $0 {setup|start|stop|restart|reload|condrestart|status}"
;;
esac

View file

@ -0,0 +1,94 @@
#!/bin/sh
#BLURB="Select/deselect LizardFS services"
#
# /var/log/setup/setup.lizardfs-services
#
# LizardFS configuration script. Lets you choose which of four
# it's processes will run on this box.
#
TMP=/var/log/setup/tmp
if [ ! -d $TMP ]; then
mkdir -p $TMP
fi
T_PX="$1"
cd $T_PX
rm -f $TMP/tmpscript
cat << EOF > $TMP/tmpscript
dialog --title "CHOOSE LizardFS SERVICES TO RUN ON THIS BOX" --item-help --checklist \\
"The selected services will be started by rc.lizardfs init script.\\n\\n
1. You need exactly ONE master server (run on your best machine)\\n
2. You should have one, two or more meta loggers\\n
3. On most machines you will need chunk server process only \\
(therefore rc.lizardfs-chunkserver is enabled by default.\\n\\n
Press the ENTER key when you are finished." \\
19 70 4 \\
EOF
if [ -r /etc/rc.d/rc.lizardfs-master ]; then
if [ -x /etc/rc.d/rc.lizardfs-master ]; then
MFS_MASTER=on
else
MFS_MASTER=off
fi
cat << EOF >> $TMP/tmpscript
"rc.lizardfs-master" "LizardFS master server" $MFS_MASTER "The Master Server is a central point of LizardFS. You need exactly ONE." \\
EOF
fi
if [ -r /etc/rc.d/rc.lizardfs-cgiserv ]; then
if [ -x /etc/rc.d/rc.lizardfs-cgiserv ]; then
MFS_CGI=on
else
MFS_CGI=off
fi
cat << EOF >> $TMP/tmpscript
"rc.lizardfs-cgiserv" "LizardFS Web Console" $MFS_CGI "The CGI server displays information on LizardFS status." \\
EOF
fi
if [ -r /etc/rc.d/rc.lizardfs-metalogger ]; then
if [ -x /etc/rc.d/rc.lizardfs-metalogger ]; then
MFS_METALOGGER=on
else
MFS_METALOGGER=off
fi
cat << EOF >> $TMP/tmpscript
"rc.lizardfs-metalogger" "Metalogger process" $MFS_METALOGGER "Metalogger is a backup machine for Master Server. Deploy some in your network." \\
EOF
fi
if [ -r /etc/rc.d/rc.lizardfs-chunkserver ]; then
if [ -x /etc/rc.d/rc.lizardfs-chunkserver ]; then
MFS_CHUNK=on
else
MFS_CHUNK=off
fi
cat << EOF >> $TMP/tmpscript
"rc.lizardfs-chunkserver" "Chunk server process" $MFS_CHUNK "The Chunk Server stores actual filesystem data in chunks. All other machines." \\
EOF
fi
cat << EOF >> $TMP/tmpscript
2> $TMP/reply
EOF
. $TMP/tmpscript
if [ ! $? = 0 ]; then
rm -f $TMP/reply $TMP/tmpscript
exit
fi
for service in rc.lizardfs-cgiserv rc.lizardfs-chunkserver rc.lizardfs-master rc.lizardfs-metalogger; do
if [ -f /etc/rc.d/$service ]; then
if grep -w $service $TMP/reply 1> /dev/null ; then
chmod 755 /etc/rc.d/$service
else
chmod 644 /etc/rc.d/$service
fi
fi
done
rm -f $TMP/reply $TMP/tmpscript

View file

@ -0,0 +1,19 @@
# HOW TO EDIT THIS FILE:
# The "handy ruler" below makes it easier to edit a package description.
# Line up the first '|' above the ':' following the base package name, and
# the '|' on the right side marks the last column you can put a character in.
# You must make exactly 11 lines for the formatting to be correct. It's also
# customary to leave one space after the ':' except on otherwise blank lines.
|-----handy-ruler------------------------------------------------------|
lizardfs: lizardfs (GPLv3 implementation of GoogleFS)
lizardfs:
lizardfs: GPLv3-licensed implementation of GoogleFS, with snapshots.
lizardfs:
lizardfs: LizardFS is FUSE-based, scalable, self-healing, self-replicating
lizardfs: distributed filesystem that can be deployed on anything. With it's
lizardfs: torrent-like replication scheme, LizardFS performance grows with the
lizardfs: number of participating nodes (called chunk nodes). Chunk node can be
lizardfs: any machine capable of running Linux, *BSD, MacOSX, or Windows.
lizardfs:
lizardfs: