Contributing and Using Git

	Paul Sheer <paulsheer@gmail.com> - 18 October 2012
	Dominique Martinet <dominique.martinet@cea.fr> - 2015-02-26
	Frank Filz <ffilzlnx@mindspring.com> - 2015-08-12

If you would like to contribute to nfs-ganesha development:

There is a process to dumping the source (using git), modifying the
source, and pushing your changes back. This process is quite simple and
requires only a few commands. These are as follows:

Establish from the other developers which branch of whose repository is
the best to work in. Create an account on github.com, login and view
that developers repository. Click "Fork" on the top right to create a
copy of that repository. Let's say your name is "Paul Sheer" (replace
"paul", "p_sheer" and "paulsheer" with your own name below), and say the
the developer who owns the repository is named Code Leader and his
github.com login is "codeleader". Now let's say the code branch is
"new-unstable-dev-project".

In addition to a Github account, you also need a linked Gerrithub account
to push and review changes. Sign up for an account on gerrithub.io by linking it
to your Github account.

To update the content of the Wiki pages on github.com, you also need to be a
member of nfs-ganesha organisation on Github. If you'd like to help keeping
the documentation up to date, ask the developers for an invite. It's not
required for code contributions.

FETCHING THE CODE:

First you need to fetch the code you wish to work on:

    git clone https://github.com/codeleader/nfs-ganesha.git --branch new-branch
    cd nfs-ganesha

The current (as of 2019-02-07) branch for development is:

    git clone https://github.com/nfs-ganesha/nfs-ganesha.git --branch next

Now check what you have:

    cd nfs-ganesha
    git status

Now visit COMPILING_HOWTO.txt for instructions on building and running.

Now fetch the latest updates:

    git remote update

You will also need to pull in the libntirpc submodule:

    git submodule update --init

TESTING

Patches should be tested before submission. Some tests that are easy to run are:

(Use src/test/run_test_mode.sh to run Ganesha for testing)

Connectathon (cthon04)

https://wiki.linux-nfs.org/wiki/index.php/Connectathon_test_suite

Ideally should be run for both NFSv3 and NFSv4.x even if you don't support
both.

pynfs

https://wiki.linux-nfs.org/wiki/index.php/Pynfs

The pynfs tests must be run for both 4.0 and 4.1, the 4.1 tests do not include
a lot of the basic functionality that is tested by 4.0. There are also some
Ganesha specific tests.

I (Frank Filz - maintainer) personally run:

./testserver.py -v --outfile /home/ffilz/ganesha/pynfs-results/TESTOUT.nfs4.0.all-ganesha-RD12-LOCK8c.2024-08-23.log --maketree 127.0.0.1:/export/test1/pynfs --showomit --secure --rundeps all ganesha RD12 LOCK8c

and 

./testserver.py -v --outfile /home/ffilz/ganesha/pynfs-results/TESTOUT.nfs4.1.all-ganesha.2024-08-23.log --maketree 127.0.0.1:/export/test1/pynfs --showomit --rundeps all ganesha

As of V6.0 I get the following non-success results when run against FSAL_VFS:

For 4.0:

**************************************************
GSS2     st_gss.testInconsistentGssSeqnum                         : OMIT
           Dependency function _using_gss failed
GSS6     st_gss.testHighSeqNum                                    : OMIT
           Dependency function _using_gss failed
GSS5     st_gss.testBadVersion                                    : OMIT
           Dependency function _using_gss failed
GSS3     st_gss.testBadVerfChecksum                               : OMIT
           Dependency function _using_gss failed
GSS8     st_gss.testBadService                                    : OMIT
           Dependency function _using_gss failed
GSS7     st_gss.testBadProcedure                                  : OMIT
           Dependency function _using_gss failed
GSS1     st_gss.testBadGssSeqnum                                  : OMIT
           Dependency function _using_gss failed
GSS4     st_gss.testBadDataChecksum                               : OMIT
           Dependency function _using_gss failed
WRT18    st_write.testChangeGranularityWrite                      : FAILURE
           consecutive SETATTR(mode)'s don't all change change
           attribute
SATT9    st_setattr.testNonUTF8                                   : UNSUPPORTED
           FATTR4_MIMETYPE not supported
RD5a     st_read.testVeryLargeOffset                              : FAILURE
           Reading file /b'export/test1/pynfs/tree/file' should
           return NFS4_OK, instead got NFS4ERR_FBIG
LOCK8c   st_lock.testNonzeroLockSeqid                             : WARNING
           LOCK with newlockowner's lockseqid=1 should return
           NFS4ERR_BAD_SEQID, instead got NFS4_OK
LOCK20   st_lock.testBlockTimeout                                 : FAILURE
           Grabbing lock after another owner let his 'turn'
           expire should return NFS4_OK, instead got
           NFS4ERR_DENIED
ACL10    st_acl.testLargeACL                                      : OMIT
           Dependency ACL0 st_acl.testACLsupport had status
           UNSUPPORTED.
ACL0     st_acl.testACLsupport                                    : UNSUPPORTED
           FATTR4_ACL not supported
ACL5     st_acl.testACL                                           : OMIT
           Dependency ACL0 st_acl.testACLsupport had status
           UNSUPPORTED.
**************************************************
Command line asked for 614 of 679 tests
Of those: 10 Skipped, 3 Failed, 3 Warned, 598 Passed

For 4.1:

**************************************************
SEQ6     st_sequence.testRequestTooBig                            : FAILURE
           OP_LOOKUP should return NFS4ERR_REQ_TOO_BIG, instead
           got NFS4ERR_NAMETOOLONG
CSESS21  st_create_session.testCallbackVersion                    : FAILURE
           No CB_NULL sent
CSESS20  st_create_session.testCallbackProgram                    : FAILURE
           No CB_NULL sent
EID9     st_exchange_id.testLeasePeriod                           : FAILURE
           OP_CREATE_SESSION should return
           NFS4ERR_STALE_CLIENTID, instead got NFS4_OK
**************************************************
Command line asked for 179 of 262 tests
Of those: 0 Skipped, 4 Failed, 0 Warned, 175 Passed

There are some other tests mentioned on the Linux NFS Wiki:

https://wiki.linux-nfs.org/wiki/index.php/Main_Page

I also have two versions of the pjdfstests that have been modified to run
better against Ganesha:

https://github.com/ffilz/pjdfstest
https://github.com/ffilz/ntfs-3g-pjd-fstest

RUNNING GANESHA FOR TESTING

Use src/test/run_test_mode.sh to run Ganesha for basic testing.

PREPARING FOR PATCH SUBMISSION:

We also have several commit hooks, please install them:

    src/scripts/git_hooks/install_git_hooks.sh

If you haven't already, generate ssh keys and install them on Github and
Gerrithub:

    ssh-keygen
    cat ~/.ssh/id_rsa.pub

Copy the output into:
    Your Github account in "Settings" -> "SSH and GPG keys".
    Your Gerrithub account in "Settings" -> "SSH Keys".

Also update your "Full Name" in Gerrithub: "Settings" -> "Profile".

Install the Gerrithub change id commit hook

    scp -p -P 29418 USERNAMEHERE@review.gerrithub.io:hooks/commit-msg .git/hooks/

You may also want to do the following so you don't have to always provide your
identity:

    git config user.name "Your Real Name"
    git config user.email "you@some.place"

You can use the --global option to set these for all your git repos.

Now do your development work.

When you are developing, testing etc.:

    git commit --signoff -a

There may be updates from other developers. Update to their new branch
"more-stable-dev-project" to include other work other people may have
done:

    git rebase origin/more-stable-dev-project

SUBMITTING PATCHES:

To push to the project, we now use Gerrithub for code submission and review.

First, when creating a Gerrithub account (first time sign-in), do NOT copy your
ganesha repo unless you plan to receive changes from someone else. It makes NO
sense to push changes to your own repo (except for the gatekeeper)

Now you have an account, you want to push some patch for us to review to
ffilz/nfs-ganesha - you need to start by adding a new remote.

You have a list of targets (anonymous http, ssh, http) to add on the project
page:

    https://review.gerrithub.io/#/admin/projects/ffilz/nfs-ganesha

If your network allows it, ssh is easier. http needs you to setup a generated
password (settings page, "HTTP Password" menu on the left) Also make sure you
use https (not http)

so taking an example:

    git remote add gerrit ssh://USERNAMEHERE@review.gerrithub.io:29418/ffilz/nfs-ganesha
    git fetch gerrit
    git log gerrit/next..HEAD

This should ONLY list the commits you want to push! Also, all should have a Change-Id.

Finally push your patches to Gerrithub:

    git push gerrit HEAD:refs/for/next

That's it. If you edit a commit, just push it again, gerrit will notice it has
the same Change-Id and update your change with a new patch set. Please make
sure you don't change the Change-Id if you update the patch otherwise this
creates disconnected review.

To re-use a Change-Id, add the --amend option:

    git commit --amend

If you want specific people to review your code, please go to Gerrithub and
add them.

Please note that you can only push changes to another repo that you wrote,
Gerrithub will check the mail address you're using and ask you to add any
different mail address to your profile (settings -> Contact information).
Well, just read the text if you get an error, it's usually clear enough :)

PUSHING MULTIPLE PATCHES:

If you have multiple patches to submit, you can either submit them separately
to gerrithub, or you can submit them as a set of patches. If you have all
the patches in a single branch on your github, the git push command above
will submit them all as a group of patches. This is handy for the maintainer
when merging because the patches may be pulled together. On the other hand,
if you need to update any of the patches, you SHOULD push all of them again
otherwise the maintainer risks not getting the latest version of the patches.
For example, if you submitted 3 patches originally, and then only pushed updates
to the first two, the 3rd patch which appears to be the "HEAD" when pulled
from gerrithub will also pull the OLD versions of the first two patches.

Pushing separate patches may make sense when they are truly independent but
it does make more effort for the maintainer especially if they happen to
conflict with each other and don't trivially merge. The maintainer appreciates
when submitters resolve merge conflicts. For this reason you should also make
sure your patches are based on the latest upstream next branch.

If you are coordinating development with someone else, make sure one person
pushes all the patches and has resolved any merge conflicts.

gerrithub makes it easy to cherrypick patches, so if multiple independent
patches have been submitted together and not all patches are ready for merge,
the maintainer can simply cherrypick the patches that are ready for merge.

PATCH UPDATES AND CHANGE ID:

If you submit a new version of a patch, even if it's a very significant rewrite,
please maintain the Change-Id. This allows gerrithub to keep all the comments
and patch versions associated to better understand the history of the change.
The multiple patch versions can easily be compared within gerrithub. If you do
submit a new patch with a new Change-Id, perhaps because a completely different
method is used to resolve the issue and is in a different section of code,
make sure to abandon the old patch.

Finally, if you're a new contributor and found a problem in this document,
please submit fixes. Thank you!
