Skip to content

Commit

Permalink
Merge branch 'dev' into coredumps
Browse files Browse the repository at this point in the history
  • Loading branch information
uristdwarf committed May 27, 2024
2 parents 177ca00 + 64acea4 commit 69ad22d
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 20 deletions.
45 changes: 45 additions & 0 deletions src/protocol/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
## Description of protocol

This is not a complete description, but describes the very basics. Contributions
are welcome.

There are two versions of protocol used. One is older and used for legacy purposes,
and a newer version currently used.

Both protocols have a header and include at least two fields: type and length.
All the types and what kind of data it includes are described in
SFSCommunication.h. The format in the comments are:

- name:\[bits\], where the bits part describes how many bits is included. Since
you are most likely running this on modern hardware, these will always be a
multiple of 8, so think of them as how many bytes it includes (8 for 1 byte, 16
for 2 etc.). As for the exact type, it's not described and you must look at the
implementation code (mostly it's some type of unsigned integer).
- name:STDSTRING, where the data type is a string
- name:(N * \[various data\]), represents a vector for various data types

All multi-byte values are ordered big-endian.

### V1 protocol

The first version of the protocol uses a data type and length fields as its
header fields, both of which are 32-bit integers (may be both unsigned and
signed). The length field indicates the length of the data after the header.

Strings include a 8, 16 or 32-bit integer before the string to indicate the size
of the string. The string does not end with a NULL byte.

### V2 protocol

In this new version, the length is the sum of the version and data lengths.
The version field is a 32-byte unsigned integer.

These are prefixed by "SAU" in SFSCommunication.h, and includes several changes
to the first protocol:

- String lengths are always 32-bit unsigned integers.
- Strings end with a NULL byte.
- Vectors and other collections include a 32-bit integer for indicating length.

In addition, the packet types can have multiple versions, which is indicated
by `version==N`. The default version is 0.
20 changes: 12 additions & 8 deletions tests/ci_build/ganesha/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ RUN set -e ; \
bison \
build-essential \
byacc \
ceph \
cmake \
dbus \
docbook \
Expand All @@ -50,21 +49,16 @@ RUN set -e ; \
libboost-program-options-dev \
libboost-system-dev \
libcap-dev \
libcephfs-dev \
libdbus-1-dev \
libglusterfs-dev \
libgssapi-krb5-2 \
libjemalloc-dev \
libjudy-dev \
libkrb5-dev \
libkrb5support0 \
libnfsidmap-dev \
libradospp-dev \
libradosstriper-dev \
librgw-dev \
libnsl-dev \
libsqlite3-dev \
liburcu-dev \
xfslibs-dev \
pkg-config \
wget \
unzip \
Expand All @@ -84,8 +78,18 @@ RUN set -e ; \
mkdir nfs-ganesha-${GANESHA_VERSION}/build ; \
cmake -Bnfs-ganesha-${GANESHA_VERSION}/build \
-DCMAKE_INSTALL_PREFIX=/ \
-DUSE_9P=NO \
-DUSE_FSAL_CEPH=NO \
-DUSE_FSAL_GLUSTER=NO \
-DUSE_FSAL_GPFS=NO \
-DUSE_FSAL_KVSFS=NO \
-DUSE_FSAL_LIZARDFS=NO \
-DUSE_FSAL_LUSTRE=NO \
-DUSE_FSAL_PROXY_V3=NO \
-DUSE_FSAL_PROXY_V4=NO \
-DUSE_FSAL_RGW=NO \
-DUSE_FSAL_XFS=NO \
-DUSE_GSS=NO \
-DUSE_FSAL_SAUNAFS=NO \
-Snfs-ganesha-${GANESHA_VERSION}/src; \
make -Cnfs-ganesha-${GANESHA_VERSION}/build -j$(($(nproc)*3/4+1)) install ; \
rm -rf nfs-ganesha-${GANESHA_VERSION} ntirpc-${NTIRPC_VERSION} ; \
Expand Down
14 changes: 2 additions & 12 deletions tests/setup_machine.sh
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ common_packages=(
# fio
bison
byacc
ceph
dbus
doxygen
flex
Expand Down Expand Up @@ -147,17 +146,13 @@ apt_packages=(
krb5-user
libacl1-dev
libcap-dev
libcephfs-dev
libdbus-1-dev
libglusterfs-dev
libgssapi-krb5-2
libjemalloc-dev
libkrb5-dev
libkrb5support0
libnfsidmap-dev
libradospp-dev
libradosstriper-dev
librgw-dev
libnsl-dev
libsqlite3-dev
xfslibs-dev
inotify-tools
Expand All @@ -179,6 +174,7 @@ dnf_packages=(
libblkid-devel
libcutl-devel
libdb-devel
libnsl
libtirpc-devel
netcat
pam-devel
Expand Down Expand Up @@ -210,14 +206,8 @@ dnf_packages=(
krb5-workstation
libacl-devel
libcap-devel
libcephfs-devel
libglusterfs-devel
libnfsidmap-devel
librados-devel
libradosstriper-devel
librgw-devel
libsqlite3x-devel
xfsprogs-devel
)
python_packages=(
asciidoc
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#
# To run this test you need to add the following lines to /etc/sudoers.d/saunafstest:
#
# saunafstest ALL = NOPASSWD: /bin/mount, /bin/umount, /bin/pkill, /bin/mkdir, /bin/touch
# saunafstest ALL = NOPASSWD: /usr/bin/ganesha.nfsd
#
# The path for the Ganesha daemon should match the installation folder inside the test.
#

timeout_set 2 minutes

CHUNKSERVERS=3 \
MOUNT_EXTRA_CONFIG="sfscachemode=NEVER" \
CHUNKSERVER_EXTRA_CONFIG="READ_AHEAD_KB = 1024|MAX_READ_BEHIND_KB = 2048"
setup_local_empty_saunafs info

test_error_cleanup() {
cd "${TEMP_DIR}"
sudo umount -l "${TEMP_DIR}/mnt/ganesha"
sudo pkill -9 ganesha.nfsd
}

# Function to get the checksum of a given file
get_checksum() {
sha256sum $1 | awk '{ print $1 }'
}

mkdir -p "${TEMP_DIR}/mnt/ganesha"

# Create PID file for Ganesha
PID_FILE=/var/run/ganesha/ganesha.pid
if [ ! -f ${PID_FILE} ]; then
echo "ganesha.pid doesn't exists, creating it...";
sudo mkdir -p /var/run/ganesha;
sudo touch "${PID_FILE}";
else
echo "ganesha.pid already exists";
fi

cd "${info[mount0]}"

cat <<EOF > "${info[mount0]}/ganesha.conf"
NFS_KRB5 {
Active_krb5=false;
}
NFSV4 {
Grace_Period = 5;
Lease_Lifetime = 3;
}
EXPORT {
Attr_Expiration_Time = 0;
Export_Id = 99;
Path = /;
Pseudo = /;
Access_Type = RW;
FSAL {
Name = SaunaFS;
hostname = localhost;
port = ${saunafs_info_[matocl]};
# How often to retry to connect
io_retries = 5;
cache_expiration_time_ms = 2500;
}
Protocols = 4;
CLIENT {
Clients = localhost;
}
}
EOF

sudo /usr/bin/ganesha.nfsd -f "${info[mount0]}/ganesha.conf"
assert_eventually 'showmount -e localhost'

sudo mount -vvvv localhost:/ "${TEMP_DIR}/mnt/ganesha"

# Create a file for testing with checksum
head -c 3G /dev/random | tee "${TEMP_DIR}/test_file" > /dev/null

# Restart master server after 15 seconds
(
sleep 15
assert_success saunafs_master_daemon restart
) &

# Wait for Grace period so NFS Ganesha server will be ready
sleep 5

# Try to copy the file after master restart
while true; do
cp "${TEMP_DIR}/test_file" "$TEMP_DIR/mnt/ganesha/test_file" && break
echo "Unable to copy test_file through NFS, retrying in 5 seconds..."
sleep 5
done

# Get checksums
checksum1=$(get_checksum "${TEMP_DIR}/test_file")

# To get the checksum of the file from NFS could require several retries in case
# NFS mount will not be available after restarting master server
while true; do
checksum2=$(get_checksum "${TEMP_DIR}/mnt/ganesha/test_file")
if [ "${checksum2}" != "" ]; then
break
fi
echo "Unable to get checksums through NFS, retrying in 5 seconds..."
sleep 5
done

checksum3=$(get_checksum "${info[mount0]}/test_file")

# Print checksums
echo "Checksum of original file: ${checksum1}"
echo "Checksum of file from NFS mount: ${checksum2}"
echo "Checksum of file from SaunaFS mount: ${checksum3}"

# Verify checksums
assert_equals "${checksum1}" "${checksum2}"
assert_equals "${checksum1}" "${checksum3}"

test_error_cleanup || true

0 comments on commit 69ad22d

Please sign in to comment.