diff options
448 files changed, 22026 insertions, 10520 deletions
diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE index 306b4eebc15..386ed2d8dd5 100644 --- a/.github/ISSUE_TEMPLATE +++ b/.github/ISSUE_TEMPLATE @@ -1,13 +1,30 @@ -This repository (glusterfs) uses github issues to track feature requests *only*. +<!-- Please use this template while reporting an issue, providing as much information as possible. Failure to do so may result in a delayed response. Thank you! --> -For assistance with bugs, please file a bug in our bugzilla instance [1] +**Description of problem:** -For other queries regarding glusterfs, please post to the users [2] or devel [3] lists as appropriate. -You may further want to subscribe to these lists or view the archives for these lists, see [4] [5]. +**The exact command to reproduce the issue**: + + +**The full output of the command that failed**: +<details> + + + +</details> + +**Expected results:** + + +**Additional info:** + + +**- The output of the `gluster volume info` command**: +<details> + + + +</details> + +**- The operating system / glusterfs version**: -[1] glusterfs Bugzilla: https://bugzilla.redhat.com/enter_bug.cgi?product=GlusterFS -[2] Gluster users list ID: gluster-users@gluster.org -[3] Gluster devel list ID: gluster-devel@gluster.org -[4] Gluster users list subscribe/view archives: https://lists.gluster.org/mailman/listinfo/gluster-users -[5] Gluster devel list subscribe/view archives: https://lists.gluster.org/mailman/listinfo/gluster-devel diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE index 0ec6eb319ee..e69de29bb2d 100644 --- a/.github/PULL_REQUEST_TEMPLATE +++ b/.github/PULL_REQUEST_TEMPLATE @@ -1,33 +0,0 @@ -Many thanks for your interest in improving GlusterFS! - -GlusterFS does not use GitHub Pull-Requests. Instead, changes are reviewed -on the Gerrit instance of the Gluster Community at https://review.gluster.org - -In order to send your changes for review, follow these steps: - -1. login on https://review.gluster.org with your GitHub account -2. add a public ssh-key to your profile on https://review.gluster.org/#/settings/ssh-keys -3. add the Gerrit remote to your locally cloned git repository - - $ git remote add gerrit ssh://$USER@review.gluster.org/glusterfs.git - -4. configure the commit hooks - - $ git review --setup - -5. post your changes to Gerrit - - $ git review - - -You may need to install the 'git-review' package if 'git review' is not -available. Note that the hooks for the repository make sure to add a ChangeId -label in the commit messages. Gerrit uses the ChangeId to track single patches -and its updated versions. - -For more details, see the documented development workflow at - http://gluster.readthedocs.io/en/latest/Developer-guide/Simplified-Development-Workflow/ - -If there are any troubles or difficulties with these instructions, please -contact us on gluster-devel@gluster.org or on Freenode IRC in the #gluster-dev -channel. diff --git a/.github/RELEASE_TRACKER_TEMPLATE b/.github/RELEASE_TRACKER_TEMPLATE new file mode 100644 index 00000000000..502bbd5556c --- /dev/null +++ b/.github/RELEASE_TRACKER_TEMPLATE @@ -0,0 +1,12 @@ +<!-- Please use this template while creating a tracker issue --> + +**Description of problem:** +A tracker issue to track the issues that will be fixed as a part of this release + + +**Major or minor release**: + + +**Release version**: + + diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000000..460e327c6ea --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,25 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 210 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 15 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: wontfix + +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + Thank you for your contributions. + + Noticed that this issue is not having any activity in last ~6 months! We + are marking this issue as stale because it has not had recent activity. + + It will be closed in 2 weeks if no one responds with a comment here. + + +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: > + Closing this issue as there was no update since my last update on issue. + If this is an issue which is still valid, feel free to open it. diff --git a/.gitignore b/.gitignore index 849a0f1a8be..fc5ba586f8e 100644 --- a/.gitignore +++ b/.gitignore @@ -121,3 +121,5 @@ xlators/features/cloudsync/src/cloudsync-autogen-fops.c xlators/features/cloudsync/src/cloudsync-autogen-fops.h xlators/features/utime/src/utime-autogen-fops.c xlators/features/utime/src/utime-autogen-fops.h +tests/basic/metadisp/ftruncate +xlators/features/metadisp/src/fops.c diff --git a/.testignore b/.testignore index 190573191e1..fe8f838bf2b 100644 --- a/.testignore +++ b/.testignore @@ -1,4 +1,6 @@ .github/ISSUE_TEMPLATE +.github/PULL_REQUEST_TEMPLATE +.github/stale.yml .gitignore .mailmap .testignore @@ -6,7 +8,7 @@ rfc.sh submit-for-review.sh AUTHORS -CONTRIBUTING +CONTRIBUTING.md COPYING-GPLV2 COPYING-LGPLV3 ChangeLog diff --git a/CONTRIBUTING b/CONTRIBUTING deleted file mode 100644 index 7bccd88d7e5..00000000000 --- a/CONTRIBUTING +++ /dev/null @@ -1,25 +0,0 @@ - Developer's Certificate of Origin 1.1 - - By making a contribution to this project, I certify that: - - (a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - - (b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - - (c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - - (d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000000..65fc3497104 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,114 @@ +# GlusterFS project Contribution guidelines + +## Development Workflow + +We follow most of the details as per the [document here](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests). If you are not aware of the github workflow, it is recommended to go through them before continuing here. + + +#### Get the Repository setup + +0. Fork Repository + - Fork [GlusterFS repository](https://github.com/gluster/glusterfs/fork). + +1. Clone Repository + - Clone the glusterfs repo freshly from github using below steps. + +``` + git clone git@github.com:${username}/glusterfs.git + cd glusterfs/ + git remote add upstream git@github.com:gluster/glusterfs.git +``` + +About two tasks are one time for the life time. You can continue to use the same repository for all the work in future. + +#### Development & Other flows + +0. Issue: + - Make sure there is an issue filed for the task you are working on. + - If it is not filed, open the issue with all the description. + - If it is a bug fix, add label "Type:Bug". + - If it is an RFC, provide all the documentation, and request for "DocApproved", and "SpecApproved" label. + +1. Code: + - Start coding + - Build and test locally + - Make sure clang-format is installed and is run on the patch. + +2. Keep up-to-date + - GlusterFS is a large project with many developers, so there would be one or the other patch everyday. + - It is critical for developer to be up-to-date with `devel` repo to be Conflict-Free when PR is opened. + - Git provides many options to keep up-to-date, below is one of them +``` + git fetch upstream + git rebase upstream/devel +``` + - It is recommended you keep pushing to your repo every day, so you don't loose any work. + - It can be done by `./rfc.sh` (or `git push origin HEAD:issueNNN`) + +2. Commit Message / PR description: + - The name of the branch on your personal fork can start with issueNNNN, followed by anything of your choice. + - PRs continue to have the title of format "component: \<title\>", like it is practiced now. + - When you open a PR, having a reference Issue for the commit is mandatory in GlusterFS. + - Commit message can have, either `Fixes: #NNNN` or `Updates: #NNNN` in a separate line in the commit message. + - Here, NNNN is the Issue ID in glusterfs repository. + - Each commit needs the author to have the "Signed-off-by: Name \<email\>" line. + - Can do this by `-s` option for `git commit`. + - If the PR is not ready for review, apply the label `work-in-progress`. + - Check the availability of "Draft PR" is present for you, if yes, use that instead. + +3. Tests: + - All the required smoke tests would be auto-triggered. + - Developers get a chance to retrigger the smoke tests using **"/recheck smoke"** as comment. + - The "regression" tests would be triggered by a comment **"/run regression"** from developers in the [@gluster-maintainers](https://github.com/orgs/gluster/teams/gluster-maintainers) group. + - Ask for help as comment in PR if you have any questions about the process! + +4. Review Process: + - `+2` : is equivalent to "Approve" from the people in the maintainer's group. + - `+1` : can be given by a maintainer/reviewer by explicitly stating that in the comment. + - `-1` : provide details on required changes and pick "Request Changes" while submitting your review. + - `-2` : done by adding the `DO-NOT-MERGE` label. + + - Any further discussions can happen as comments in the PR. + +5. Making changes: + - There are 2 approaches to submit changes done after addressing review comments. + - Commit changes as a new commit on top of the original commits in the branch, and push the changes to same branch (issueNNNN) + - Commit changes into the same commit with `--amend` option, and do a push to the same branch with `--force` option. + +6. Merging: + - GlusterFS project follows 'Squash and Merge' method + - This is mainly to preserve the historic Gerrit method of one patch in `git log` for one URL link. + - This also makes every merge a complete patch, which has passed all tests. + - The merging of the patch is expected to be done by the maintainers. + - It can be done when all the tests (smoke and regression) pass. + - When the PR has 'Approved' flag from corresponding maintainer. + - If you feel there is delay, feel free to add a comment, discuss the same in Slack channel, or send email. + +## By contributing to this project, the contributor would need to agree to below. + +### Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. + diff --git a/MAINTAINERS b/MAINTAINERS index b4d8195e0e9..953e8755fd9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -53,8 +53,7 @@ General Project Architects -------------------------- M: Amar Tumballi <amarts@gmail.com> M: Xavier Hernandez <xhernandez@redhat.com> -P: Pranith Karampuri <pkarampu@redhat.com> -P: Raghavendra Gowdappa <rgowdapp@redhat.com> +P: Pranith Karampuri <pranith.karampuri@phonepe.com> P: Atin Mukherjee <amukherj@redhat.com> xlators: @@ -67,13 +66,14 @@ F: xlators/system/posix-acl/ Arbiter M: Ravishankar N <ravishankar@redhat.com> -P: Pranith Karampuri <pkarampu@redhat.com> +P: Pranith Karampuri <pranith.karampuri@phonepe.com> S: Maintained F: xlators/features/arbiter/ Automatic File Replication (AFR) -M: Pranith Karampuri <pkarampu@redhat.com> -P: Ravishankar N <ravishankar@redhat.com> +M: Pranith Karampuri <pranith.karampuri@phonepe.com> +M: Ravishankar N <ravishankar@redhat.com> +P: Karthik US <ksubrahm@redhat.com> S: Maintained F: xlators/cluster/afr/ @@ -96,13 +96,12 @@ S: Maintained F: xlators/features/changelog/ Distributed Hashing Table (DHT) -M: Raghavendra Gowdappa <rgowdapp@redhat.com> P: Susant Palai <spalai@redhat.com> S: Maintained F: xlators/cluster/dht/ Erasure Coding -M: Pranith Karampuri <pkarampu@redhat.com> +M: Pranith Karampuri <pranith.karampuri@phonepe.com> M: Xavier Hernandez <xhernandez@redhat.com> P: Ashish Pandey <aspandey@redhat.com> S: Maintained @@ -115,20 +114,18 @@ F: xlators/debug/error-gen/ FUSE Bridge M: Csaba Henk <chenk@redhat.com> -P: Raghavendra Gowdappa <rgowdapp@redhat.com> P: Niels de Vos <ndevos@redhat.com> S: Maintained F: xlators/mount/ Index -M: Pranith Karampuri <pkarampu@redhat.com> +M: Pranith Karampuri <pranith.karampuri@phonepe.com> P: Ravishankar N <ravishankar@redhat.com> S: Maintained F: xlators/features/index/ IO Cache -M: Raghavendra Gowdappa <rgowdapp@redhat.com> -P: Mohammed Rafi KC <rkavunga@redhat.com> +P: Mohammed Rafi KC <rafi.kavungal@iternity.com> S: Maintained F: xlators/performance/io-cache/ @@ -139,7 +136,7 @@ S: Maintained F: xlators/debug/io-stats/ IO threads -M: Pranith Karampuri <pkarampu@redhat.com> +M: Pranith Karampuri <pranith.karampuri@phonepe.com> P: Ravishankar N <ravishankar@redhat.com> S: Maintained F: xlators/performance/io-threads/ @@ -158,13 +155,12 @@ S: Maintained F: xlators/features/locks/ Marker -M: Raghavendra Gowdappa <rgowdapp@redhat.com> M: Kotresh HR <khiremat@redhat.com> S: Maintained F: xlators/features/marker/ Meta -M: Mohammed Rafi KC <rkavunga@redhat.com> +M: Mohammed Rafi KC <rafi.kavungal@iternity.com> S: Maintained F: xlators/features/meta/ @@ -176,7 +172,7 @@ F: xlators/performance/md-cache/ Negative-lookup Cache M: Poornima G <pgurusid@redhat.com> -P: Pranith Karampuri <pkarampu@redhat.com> +P: Pranith Karampuri <pranith.karampuri@phonepe.com> S: Maintained F: xlators/performance/nl-cache/ @@ -188,7 +184,6 @@ S: Odd Fixes F: xlators/nfs/server/ Open-behind -M: Raghavendra Gowdappa <rgowdapp@redhat.com> S: Maintained F: xlators/performance/open-behind/ @@ -200,25 +195,21 @@ S: Maintained F: xlators/storage/posix/ Quick-read -M: Raghavendra Gowdappa <rgowdapp@redhat.com> S: Maintained F: xlators/performance/quick-read/ Quota -M: Raghavendra Gowdappa <rgowdapp@redhat.com> M: Shyamsundar Ranganathan <srangana@redhat.com> P: Hari Gowtham <hgowtham@redhat.com> S: Maintained F: xlators/features/quota/ Read-ahead -M: Raghavendra Gowdappa <rgowdapp@redhat.com> P: Csaba Henk <chenk@redhat.com> S: Maintained F: xlators/performance/read-ahead/ Readdir-ahead -M: Raghavendra Gowdappa <rgowdapp@redhat.com> S: Maintained F: xlators/performance/readdir-ahead/ @@ -242,7 +233,6 @@ S: Maintained F: xlators/features/upcall/ Write-behind -M: Raghavendra Gowdappa <rgowdapp@redhat.com> P: Csaba Henk <chenk@redhat.com> S: Maintained F: xlators/performance/write-behind/ @@ -292,8 +282,7 @@ M: Xavier Hernandez <xhernandez@redhat.com> M: Jeff Darcy <jeff@pl.atyp.us> P: Kaleb Keithley <kkeithle@redhat.com> P: Niels de Vos <ndevos@redhat.com> -P: Pranith Karampuri <pkarampu@redhat.com> -P: Raghavendra Gowdappa <rgowdapp@redhat.com> +P: Pranith Karampuri <pranith.karampuri@phonepe.com> P: Shyamsundar Ranganathan <srangana@redhat.com> S: Maintained F: libglusterfs/ @@ -316,13 +305,11 @@ F: xlators/mgmt/glusterd/ Protocol M: Niels de Vos <ndevos@redhat.com> -M: Raghavendra Gowdappa <rgowdapp@redhat.com> -P: Mohammed Rafi KC <rkavunga@redhat.com> +P: Mohammed Rafi KC <rafi.kavungal@iternity.com> S: Maintained F: xlators/protocol/ Remote Procedure Call subsystem -M: Raghavendra Gowdappa <rgowdapp@redhat.com> P: Mohit Agrawal <moagrawa@redhat.com> S: Maintained F: rpc/rpc-lib/ @@ -330,17 +317,16 @@ F: rpc/xdr/ Snapshot M: Raghavendra Bhat <raghavendra@redhat.com> -P: Mohammed Rafi KC <rkavunga@redhat.com> +P: Mohammed Rafi KC <rafi.kavungal@iternity.com> P: Sunny Kumar <sunkumar@redhat.com> S: Maintained F: xlators/mgmt/glusterd/src/glusterd-snap* F: extras/snap-scheduler.py Socket subsystem -M: Raghavendra Gowdappa <rgowdapp@redhat.com> P: Krutika Dhananjay <kdhananj@redhat.com> P: Milind Changire <mchangir@redhat.com> -P: Mohammed Rafi KC <rkavunga@redhat.com> +P: Mohammed Rafi KC <rafi.kavungal@iternity.com> P: Mohit Agrawal <moagrawa@redhat.com> S: Maintained F: rpc/rpc-transport/socket/ @@ -521,3 +507,4 @@ M: Luis Pabon M: Ira Cooper M: Shwetha Panduranga M: Nithya Balachandran +M: Raghavendra Gowdappa diff --git a/Makefile.am b/Makefile.am index aa0ca5c2a04..98ea5c1038d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,9 +19,13 @@ pkgconfig_DATA = glusterfs-api.pc libgfchangelog.pc CLEANFILES = glusterfs-api.pc libgfchangelog.pc contrib/umountd/Makefile +clean-local: + find . -name '*.o' -o -name '*.lo' -o -name '.Po' | xargs rm -f + gitclean: distclean find . -name Makefile.in -exec rm -f {} \; find . -name mount.glusterfs -exec rm -f {} \; + find . -name .deps -o -name .libs | xargs rm -rf rm -fr autom4te.cache rm -f missing aclocal.m4 config.h.in config.guess config.sub ltmain.sh install-sh configure depcomp @@ -49,4 +53,3 @@ gen-VERSION: ./build-aux/pkg-version --full \ > $(abs_top_builddir)/$(distdir)/VERSION; \ fi - diff --git a/README.md b/README.md index 92f829e431e..9d68e033782 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ petabytes. It provides interfaces for object, block and file storage. ## Development - Contributions to gluster in the form of patches and new feature additions can - be made by following steps outlined at [Developers Guide](http://docs.gluster.org/en/latest/Developer-guide/Developers-Index/#contributing-to-the-gluster-community). + The development workflow is documented in [Contributors guide](CONTRIBUTING.md) ## Documentation The Gluster documentation can be found at [Gluster Docs](http://docs.gluster.org). diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index 603f37afb09..6aa3c5602d1 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -292,6 +292,7 @@ glfs_iatt_to_statx(struct glfs *fs, const struct iatt *iatt, statx->glfs_st_attributes_mask = 0; } +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_iatt_from_statx, 6.0) void priv_glfs_iatt_from_statx(struct iatt *iatt, const struct glfs_stat *statx) { @@ -371,7 +372,6 @@ priv_glfs_iatt_from_statx(struct iatt *iatt, const struct glfs_stat *statx) iatt->ia_attributes = statx->glfs_st_attributes; iatt->ia_attributes_mask = statx->glfs_st_attributes_mask; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_iatt_from_statx, 6.0); void glfsflags_from_gfapiflags(struct glfs_stat *stat, int *glvalid) @@ -415,6 +415,7 @@ glfs_loc_unlink(loc_t *loc) return 0; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_open, 3.4.0) struct glfs_fd * pub_glfs_open(struct glfs *fs, const char *path, int flags) { @@ -509,8 +510,7 @@ invalid_fs: return glfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_open, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_close, 3.4.0) int pub_glfs_close(struct glfs_fd *glfd) { @@ -565,8 +565,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_close, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lstat, 3.4.0) int pub_glfs_lstat(struct glfs *fs, const char *path, struct stat *stat) { @@ -607,8 +606,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lstat, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_stat, 3.4.0) int pub_glfs_stat(struct glfs *fs, const char *path, struct stat *stat) { @@ -649,8 +647,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_stat, 3.4.0); - +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_statx, 6.0) int priv_glfs_statx(struct glfs *fs, const char *path, const unsigned int mask, struct glfs_stat *statxbuf) @@ -704,8 +701,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_statx, 6.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fstat, 3.4.0) int pub_glfs_fstat(struct glfs_fd *glfd, struct stat *stat) { @@ -754,8 +750,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fstat, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_creat, 3.4.0) struct glfs_fd * pub_glfs_creat(struct glfs *fs, const char *path, int flags, mode_t mode) { @@ -902,8 +897,6 @@ invalid_fs: return glfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_creat, 3.4.0); - #ifdef HAVE_SEEK_HOLE static int glfs_seek(struct glfs_fd *glfd, off_t offset, int whence) @@ -957,6 +950,7 @@ out: } #endif +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lseek, 3.4.0) off_t pub_glfs_lseek(struct glfs_fd *glfd, off_t offset, int whence) { @@ -1012,8 +1006,6 @@ invalid_fs: return -1; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lseek, 3.4.0); - static ssize_t glfs_preadv_common(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, off_t offset, int flags, struct glfs_stat *poststat) @@ -1091,6 +1083,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv, 3.4.0) ssize_t pub_glfs_preadv(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, off_t offset, int flags) @@ -1098,8 +1091,7 @@ pub_glfs_preadv(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, return glfs_preadv_common(glfd, iovec, iovcnt, offset, flags, NULL); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read, 3.4.0) ssize_t pub_glfs_read(struct glfs_fd *glfd, void *buf, size_t count, int flags) { @@ -1108,6 +1100,11 @@ pub_glfs_read(struct glfs_fd *glfd, void *buf, size_t count, int flags) }; ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + iov.iov_base = buf; iov.iov_len = count; @@ -1116,8 +1113,7 @@ pub_glfs_read(struct glfs_fd *glfd, void *buf, size_t count, int flags) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read, 3.4.0); - +GFAPI_SYMVER_PUBLIC(glfs_pread34, glfs_pread, 3.4.0) ssize_t pub_glfs_pread34(struct glfs_fd *glfd, void *buf, size_t count, off_t offset, int flags) @@ -1135,8 +1131,7 @@ pub_glfs_pread34(struct glfs_fd *glfd, void *buf, size_t count, off_t offset, return ret; } -GFAPI_SYMVER_PUBLIC(glfs_pread34, glfs_pread, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread, 6.0) ssize_t pub_glfs_pread(struct glfs_fd *glfd, void *buf, size_t count, off_t offset, int flags, struct glfs_stat *poststat) @@ -1154,21 +1149,23 @@ pub_glfs_pread(struct glfs_fd *glfd, void *buf, size_t count, off_t offset, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread, 6.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv, 3.4.0) ssize_t pub_glfs_readv(struct glfs_fd *glfd, const struct iovec *iov, int count, int flags) { ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + ret = pub_glfs_preadv(glfd, iov, count, glfd->offset, flags); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv, 3.4.0); - struct glfs_io { struct glfs_fd *glfd; int op; @@ -1370,6 +1367,7 @@ invalid_fs: return -1; } +GFAPI_SYMVER_PUBLIC(glfs_preadv_async34, glfs_preadv_async, 3.4.0) int pub_glfs_preadv_async34(struct glfs_fd *glfd, const struct iovec *iovec, int count, off_t offset, int flags, glfs_io_cbk34 fn, @@ -1379,8 +1377,7 @@ pub_glfs_preadv_async34(struct glfs_fd *glfd, const struct iovec *iovec, (void *)fn, data); } -GFAPI_SYMVER_PUBLIC(glfs_preadv_async34, glfs_preadv_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv_async, 6.0) int pub_glfs_preadv_async(struct glfs_fd *glfd, const struct iovec *iovec, int count, off_t offset, int flags, glfs_io_cbk fn, @@ -1390,8 +1387,7 @@ pub_glfs_preadv_async(struct glfs_fd *glfd, const struct iovec *iovec, _gf_false, fn, data); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv_async, 6.0); - +GFAPI_SYMVER_PUBLIC(glfs_read_async34, glfs_read_async, 3.4.0) int pub_glfs_read_async34(struct glfs_fd *glfd, void *buf, size_t count, int flags, glfs_io_cbk34 fn, void *data) @@ -1401,6 +1397,11 @@ pub_glfs_read_async34(struct glfs_fd *glfd, void *buf, size_t count, int flags, }; ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + iov.iov_base = buf; iov.iov_len = count; @@ -1410,8 +1411,7 @@ pub_glfs_read_async34(struct glfs_fd *glfd, void *buf, size_t count, int flags, return ret; } -GFAPI_SYMVER_PUBLIC(glfs_read_async34, glfs_read_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read_async, 6.0) int pub_glfs_read_async(struct glfs_fd *glfd, void *buf, size_t count, int flags, glfs_io_cbk fn, void *data) @@ -1421,6 +1421,11 @@ pub_glfs_read_async(struct glfs_fd *glfd, void *buf, size_t count, int flags, }; ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + iov.iov_base = buf; iov.iov_len = count; @@ -1430,8 +1435,7 @@ pub_glfs_read_async(struct glfs_fd *glfd, void *buf, size_t count, int flags, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read_async, 6.0); - +GFAPI_SYMVER_PUBLIC(glfs_pread_async34, glfs_pread_async, 3.4.0) int pub_glfs_pread_async34(struct glfs_fd *glfd, void *buf, size_t count, off_t offset, int flags, glfs_io_cbk34 fn, void *data) @@ -1450,8 +1454,7 @@ pub_glfs_pread_async34(struct glfs_fd *glfd, void *buf, size_t count, return ret; } -GFAPI_SYMVER_PUBLIC(glfs_pread_async34, glfs_pread_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread_async, 6.0) int pub_glfs_pread_async(struct glfs_fd *glfd, void *buf, size_t count, off_t offset, int flags, glfs_io_cbk fn, void *data) @@ -1470,34 +1473,40 @@ pub_glfs_pread_async(struct glfs_fd *glfd, void *buf, size_t count, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread_async, 6.0); - +GFAPI_SYMVER_PUBLIC(glfs_readv_async34, glfs_readv_async, 3.4.0) int pub_glfs_readv_async34(struct glfs_fd *glfd, const struct iovec *iov, int count, int flags, glfs_io_cbk34 fn, void *data) { ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + ret = glfs_preadv_async_common(glfd, iov, count, glfd->offset, flags, _gf_true, (void *)fn, data); return ret; } -GFAPI_SYMVER_PUBLIC(glfs_readv_async34, glfs_readv_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv_async, 6.0) int pub_glfs_readv_async(struct glfs_fd *glfd, const struct iovec *iov, int count, int flags, glfs_io_cbk fn, void *data) { ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + ret = glfs_preadv_async_common(glfd, iov, count, glfd->offset, flags, _gf_false, fn, data); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv_async, 6.0); - static ssize_t glfs_pwritev_common(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, off_t offset, int flags, struct glfs_stat *prestat, @@ -1583,6 +1592,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_copy_file_range, 6.0) ssize_t pub_glfs_copy_file_range(struct glfs_fd *glfd_in, off64_t *off_in, struct glfs_fd *glfd_out, off64_t *off_out, size_t len, @@ -1736,8 +1746,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_copy_file_range, 6.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev, 3.4.0) ssize_t pub_glfs_pwritev(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, off_t offset, int flags) @@ -1745,8 +1754,7 @@ pub_glfs_pwritev(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt, return glfs_pwritev_common(glfd, iovec, iovcnt, offset, flags, NULL, NULL); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write, 3.4.0) ssize_t pub_glfs_write(struct glfs_fd *glfd, const void *buf, size_t count, int flags) { @@ -1755,6 +1763,11 @@ pub_glfs_write(struct glfs_fd *glfd, const void *buf, size_t count, int flags) }; ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + iov.iov_base = (void *)buf; iov.iov_len = count; @@ -1763,21 +1776,24 @@ pub_glfs_write(struct glfs_fd *glfd, const void *buf, size_t count, int flags) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev, 3.4.0) ssize_t pub_glfs_writev(struct glfs_fd *glfd, const struct iovec *iov, int count, int flags) { ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + ret = pub_glfs_pwritev(glfd, iov, count, glfd->offset, flags); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev, 3.4.0); - +GFAPI_SYMVER_PUBLIC(glfs_pwrite34, glfs_pwrite, 3.4.0) ssize_t pub_glfs_pwrite34(struct glfs_fd *glfd, const void *buf, size_t count, off_t offset, int flags) @@ -1795,8 +1811,7 @@ pub_glfs_pwrite34(struct glfs_fd *glfd, const void *buf, size_t count, return ret; } -GFAPI_SYMVER_PUBLIC(glfs_pwrite34, glfs_pwrite, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite, 6.0) ssize_t pub_glfs_pwrite(struct glfs_fd *glfd, const void *buf, size_t count, off_t offset, int flags, struct glfs_stat *prestat, @@ -1815,8 +1830,6 @@ pub_glfs_pwrite(struct glfs_fd *glfd, const void *buf, size_t count, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite, 6.0); - extern glfs_t * pub_glfs_from_glfd(glfs_fd_t *); @@ -1935,6 +1948,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC(glfs_pwritev_async34, glfs_pwritev_async, 3.4.0) int pub_glfs_pwritev_async34(struct glfs_fd *glfd, const struct iovec *iovec, int count, off_t offset, int flags, glfs_io_cbk34 fn, @@ -1944,8 +1958,7 @@ pub_glfs_pwritev_async34(struct glfs_fd *glfd, const struct iovec *iovec, _gf_true, (void *)fn, data); } -GFAPI_SYMVER_PUBLIC(glfs_pwritev_async34, glfs_pwritev_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev_async, 6.0) int pub_glfs_pwritev_async(struct glfs_fd *glfd, const struct iovec *iovec, int count, off_t offset, int flags, glfs_io_cbk fn, @@ -1955,8 +1968,7 @@ pub_glfs_pwritev_async(struct glfs_fd *glfd, const struct iovec *iovec, _gf_false, fn, data); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev_async, 6.0); - +GFAPI_SYMVER_PUBLIC(glfs_write_async34, glfs_write_async, 3.4.0) int pub_glfs_write_async34(struct glfs_fd *glfd, const void *buf, size_t count, int flags, glfs_io_cbk34 fn, void *data) @@ -1966,6 +1978,11 @@ pub_glfs_write_async34(struct glfs_fd *glfd, const void *buf, size_t count, }; ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + iov.iov_base = (void *)buf; iov.iov_len = count; @@ -1975,8 +1992,7 @@ pub_glfs_write_async34(struct glfs_fd *glfd, const void *buf, size_t count, return ret; } -GFAPI_SYMVER_PUBLIC(glfs_write_async34, glfs_write_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write_async, 6.0) int pub_glfs_write_async(struct glfs_fd *glfd, const void *buf, size_t count, int flags, glfs_io_cbk fn, void *data) @@ -1986,6 +2002,11 @@ pub_glfs_write_async(struct glfs_fd *glfd, const void *buf, size_t count, }; ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + iov.iov_base = (void *)buf; iov.iov_len = count; @@ -1995,8 +2016,7 @@ pub_glfs_write_async(struct glfs_fd *glfd, const void *buf, size_t count, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write_async, 6.0); - +GFAPI_SYMVER_PUBLIC(glfs_pwrite_async34, glfs_pwrite_async, 3.4.0) int pub_glfs_pwrite_async34(struct glfs_fd *glfd, const void *buf, int count, off_t offset, int flags, glfs_io_cbk34 fn, void *data) @@ -2015,8 +2035,7 @@ pub_glfs_pwrite_async34(struct glfs_fd *glfd, const void *buf, int count, return ret; } -GFAPI_SYMVER_PUBLIC(glfs_pwrite_async34, glfs_pwrite_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite_async, 6.0) int pub_glfs_pwrite_async(struct glfs_fd *glfd, const void *buf, int count, off_t offset, int flags, glfs_io_cbk fn, void *data) @@ -2035,34 +2054,40 @@ pub_glfs_pwrite_async(struct glfs_fd *glfd, const void *buf, int count, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite_async, 6.0); - +GFAPI_SYMVER_PUBLIC(glfs_writev_async34, glfs_writev_async, 3.4.0) int pub_glfs_writev_async34(struct glfs_fd *glfd, const struct iovec *iov, int count, int flags, glfs_io_cbk34 fn, void *data) { ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + ret = glfs_pwritev_async_common(glfd, iov, count, glfd->offset, flags, _gf_true, (void *)fn, data); return ret; } -GFAPI_SYMVER_PUBLIC(glfs_writev_async34, glfs_writev_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev_async, 6.0) int pub_glfs_writev_async(struct glfs_fd *glfd, const struct iovec *iov, int count, int flags, glfs_io_cbk fn, void *data) { ssize_t ret = 0; + if (glfd == NULL) { + errno = EBADF; + return -1; + } + ret = glfs_pwritev_async_common(glfd, iov, count, glfd->offset, flags, _gf_false, fn, data); return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev_async, 6.0); - static int glfs_fsync_common(struct glfs_fd *glfd, struct glfs_stat *prestat, struct glfs_stat *poststat) @@ -2127,14 +2152,14 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC(glfs_fsync34, glfs_fsync, 3.4.0) int pub_glfs_fsync34(struct glfs_fd *glfd) { return glfs_fsync_common(glfd, NULL, NULL); } -GFAPI_SYMVER_PUBLIC(glfs_fsync34, glfs_fsync, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync, 6.0) int pub_glfs_fsync(struct glfs_fd *glfd, struct glfs_stat *prestat, struct glfs_stat *poststat) @@ -2142,8 +2167,6 @@ pub_glfs_fsync(struct glfs_fd *glfd, struct glfs_stat *prestat, return glfs_fsync_common(glfd, prestat, poststat); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync, 6.0); - static int glfs_fsync_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, @@ -2224,6 +2247,7 @@ out: return ret; } +GFAPI_SYMVER_PUBLIC(glfs_fsync_async34, glfs_fsync_async, 3.4.0) int pub_glfs_fsync_async34(struct glfs_fd *glfd, glfs_io_cbk34 fn, void *data) { @@ -2240,8 +2264,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC(glfs_fsync_async34, glfs_fsync_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync_async, 6.0) int pub_glfs_fsync_async(struct glfs_fd *glfd, glfs_io_cbk fn, void *data) { @@ -2258,8 +2281,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync_async, 6.0); - static int glfs_fdatasync_common(struct glfs_fd *glfd, struct glfs_stat *prestat, struct glfs_stat *poststat) @@ -2324,14 +2345,14 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC(glfs_fdatasync34, glfs_fdatasync, 3.4.0) int pub_glfs_fdatasync34(struct glfs_fd *glfd) { return glfs_fdatasync_common(glfd, NULL, NULL); } -GFAPI_SYMVER_PUBLIC(glfs_fdatasync34, glfs_fdatasync, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync, 6.0) int pub_glfs_fdatasync(struct glfs_fd *glfd, struct glfs_stat *prestat, struct glfs_stat *poststat) @@ -2339,8 +2360,7 @@ pub_glfs_fdatasync(struct glfs_fd *glfd, struct glfs_stat *prestat, return glfs_fdatasync_common(glfd, prestat, poststat); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync, 6.0); - +GFAPI_SYMVER_PUBLIC(glfs_fdatasync_async34, glfs_fdatasync_async, 3.4.0) int pub_glfs_fdatasync_async34(struct glfs_fd *glfd, glfs_io_cbk34 fn, void *data) { @@ -2357,8 +2377,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC(glfs_fdatasync_async34, glfs_fdatasync_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync_async, 6.0) int pub_glfs_fdatasync_async(struct glfs_fd *glfd, glfs_io_cbk fn, void *data) { @@ -2375,8 +2394,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync_async, 6.0); - static int glfs_ftruncate_common(struct glfs_fd *glfd, off_t offset, struct glfs_stat *prestat, struct glfs_stat *poststat) @@ -2442,14 +2459,14 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC(glfs_ftruncate34, glfs_ftruncate, 3.4.0) int pub_glfs_ftruncate34(struct glfs_fd *glfd, off_t offset) { return glfs_ftruncate_common(glfd, offset, NULL, NULL); } -GFAPI_SYMVER_PUBLIC(glfs_ftruncate34, glfs_ftruncate, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate, 6.0) int pub_glfs_ftruncate(struct glfs_fd *glfd, off_t offset, struct glfs_stat *prestat, struct glfs_stat *poststat) @@ -2457,8 +2474,7 @@ pub_glfs_ftruncate(struct glfs_fd *glfd, off_t offset, return glfs_ftruncate_common(glfd, offset, prestat, poststat); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate, 6.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_truncate, 3.7.15) int pub_glfs_truncate(struct glfs *fs, const char *path, off_t length) { @@ -2504,8 +2520,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_truncate, 3.7.15); - static int glfs_ftruncate_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, @@ -2598,6 +2612,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC(glfs_ftruncate_async34, glfs_ftruncate_async, 3.4.0) int pub_glfs_ftruncate_async34(struct glfs_fd *glfd, off_t offset, glfs_io_cbk34 fn, void *data) @@ -2606,8 +2621,7 @@ pub_glfs_ftruncate_async34(struct glfs_fd *glfd, off_t offset, glfs_io_cbk34 fn, data); } -GFAPI_SYMVER_PUBLIC(glfs_ftruncate_async34, glfs_ftruncate_async, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate_async, 6.0) int pub_glfs_ftruncate_async(struct glfs_fd *glfd, off_t offset, glfs_io_cbk fn, void *data) @@ -2615,8 +2629,7 @@ pub_glfs_ftruncate_async(struct glfs_fd *glfd, off_t offset, glfs_io_cbk fn, return glfs_ftruncate_async_common(glfd, offset, _gf_false, fn, data); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate_async, 6.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_access, 3.4.0) int pub_glfs_access(struct glfs *fs, const char *path, int mode) { @@ -2662,8 +2675,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_access, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_symlink, 3.4.0) int pub_glfs_symlink(struct glfs *fs, const char *data, const char *path) { @@ -2753,8 +2765,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_symlink, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readlink, 3.4.0) int pub_glfs_readlink(struct glfs *fs, const char *path, char *buf, size_t bufsiz) { @@ -2811,8 +2822,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readlink, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mknod, 3.4.0) int pub_glfs_mknod(struct glfs *fs, const char *path, mode_t mode, dev_t dev) { @@ -2902,8 +2912,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mknod, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mkdir, 3.4.0) int pub_glfs_mkdir(struct glfs *fs, const char *path, mode_t mode) { @@ -2993,8 +3002,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mkdir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unlink, 3.4.0) int pub_glfs_unlink(struct glfs *fs, const char *path) { @@ -3050,8 +3058,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unlink, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rmdir, 3.4.0) int pub_glfs_rmdir(struct glfs *fs, const char *path) { @@ -3106,8 +3113,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rmdir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rename, 3.4.0) int pub_glfs_rename(struct glfs *fs, const char *oldpath, const char *newpath) { @@ -3196,8 +3202,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rename, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_link, 3.4.0) int pub_glfs_link(struct glfs *fs, const char *oldpath, const char *newpath) { @@ -3283,8 +3288,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_link, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_opendir, 3.4.0) struct glfs_fd * pub_glfs_opendir(struct glfs *fs, const char *path) { @@ -3365,8 +3369,7 @@ invalid_fs: return glfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_opendir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_closedir, 3.4.0) int pub_glfs_closedir(struct glfs_fd *glfd) { @@ -3387,22 +3390,30 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_closedir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_telldir, 3.4.0) long pub_glfs_telldir(struct glfs_fd *fd) { + if (fd == NULL) { + errno = EBADF; + return -1; + } + return fd->offset; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_telldir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_seekdir, 3.4.0) void pub_glfs_seekdir(struct glfs_fd *fd, long offset) { gf_dirent_t *entry = NULL; gf_dirent_t *tmp = NULL; + if (fd == NULL) { + errno = EBADF; + return; + } + if (fd->offset == offset) return; @@ -3425,8 +3436,6 @@ pub_glfs_seekdir(struct glfs_fd *fd, long offset) */ } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_seekdir, 3.4.0); - static int glfs_discard_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, @@ -3517,6 +3526,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC(glfs_discard_async35, glfs_discard_async, 3.5.0) int pub_glfs_discard_async35(struct glfs_fd *glfd, off_t offset, size_t len, glfs_io_cbk34 fn, void *data) @@ -3525,8 +3535,7 @@ pub_glfs_discard_async35(struct glfs_fd *glfd, off_t offset, size_t len, data); } -GFAPI_SYMVER_PUBLIC(glfs_discard_async35, glfs_discard_async, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard_async, 6.0) int pub_glfs_discard_async(struct glfs_fd *glfd, off_t offset, size_t len, glfs_io_cbk fn, void *data) @@ -3534,8 +3543,6 @@ pub_glfs_discard_async(struct glfs_fd *glfd, off_t offset, size_t len, return glfs_discard_async_common(glfd, offset, len, _gf_false, fn, data); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard_async, 6.0); - static int glfs_zerofill_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, @@ -3628,6 +3635,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC(glfs_zerofill_async35, glfs_zerofill_async, 3.5.0) int pub_glfs_zerofill_async35(struct glfs_fd *glfd, off_t offset, off_t len, glfs_io_cbk34 fn, void *data) @@ -3636,8 +3644,7 @@ pub_glfs_zerofill_async35(struct glfs_fd *glfd, off_t offset, off_t len, data); } -GFAPI_SYMVER_PUBLIC(glfs_zerofill_async35, glfs_zerofill_async, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill_async, 6.0) int pub_glfs_zerofill_async(struct glfs_fd *glfd, off_t offset, off_t len, glfs_io_cbk fn, void *data) @@ -3645,8 +3652,6 @@ pub_glfs_zerofill_async(struct glfs_fd *glfd, off_t offset, off_t len, return glfs_zerofill_async_common(glfd, offset, len, _gf_false, fn, data); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill_async, 6.0); - void gf_dirent_to_dirent(gf_dirent_t *gf_dirent, struct dirent *dirent) { @@ -3806,6 +3811,7 @@ unlock: return buf; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus_r, 3.4.0) int pub_glfs_readdirplus_r(struct glfs_fd *glfd, struct stat *stat, struct dirent *ext, struct dirent **res) @@ -3861,8 +3867,7 @@ invalid_fs: return -1; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus_r, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir_r, 3.4.0) int pub_glfs_readdir_r(struct glfs_fd *glfd, struct dirent *buf, struct dirent **res) @@ -3870,8 +3875,7 @@ pub_glfs_readdir_r(struct glfs_fd *glfd, struct dirent *buf, return pub_glfs_readdirplus_r(glfd, 0, buf, res); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir_r, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus, 3.5.0) struct dirent * pub_glfs_readdirplus(struct glfs_fd *glfd, struct stat *stat) { @@ -3885,16 +3889,14 @@ pub_glfs_readdirplus(struct glfs_fd *glfd, struct stat *stat) return res; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir, 3.5.0) struct dirent * pub_glfs_readdir(struct glfs_fd *glfd) { return pub_glfs_readdirplus(glfd, NULL); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_statvfs, 3.4.0) int pub_glfs_statvfs(struct glfs *fs, const char *path, struct statvfs *buf) { @@ -3940,8 +3942,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_statvfs, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setattr, 6.0) int pub_glfs_setattr(struct glfs *fs, const char *path, struct glfs_stat *stat, int follow) @@ -4001,8 +4002,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setattr, 6.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsetattr, 6.0) int pub_glfs_fsetattr(struct glfs_fd *glfd, struct glfs_stat *stat) { @@ -4055,8 +4055,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsetattr, 6.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chmod, 3.4.0) int pub_glfs_chmod(struct glfs *fs, const char *path, mode_t mode) { @@ -4073,8 +4072,7 @@ pub_glfs_chmod(struct glfs *fs, const char *path, mode_t mode) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chmod, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchmod, 3.4.0) int pub_glfs_fchmod(struct glfs_fd *glfd, mode_t mode) { @@ -4091,8 +4089,7 @@ pub_glfs_fchmod(struct glfs_fd *glfd, mode_t mode) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchmod, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chown, 3.4.0) int pub_glfs_chown(struct glfs *fs, const char *path, uid_t uid, gid_t gid) { @@ -4117,8 +4114,7 @@ pub_glfs_chown(struct glfs *fs, const char *path, uid_t uid, gid_t gid) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chown, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lchown, 3.4.0) int pub_glfs_lchown(struct glfs *fs, const char *path, uid_t uid, gid_t gid) { @@ -4143,8 +4139,7 @@ pub_glfs_lchown(struct glfs *fs, const char *path, uid_t uid, gid_t gid) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lchown, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchown, 3.4.0) int pub_glfs_fchown(struct glfs_fd *glfd, uid_t uid, gid_t gid) { @@ -4169,8 +4164,7 @@ pub_glfs_fchown(struct glfs_fd *glfd, uid_t uid, gid_t gid) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchown, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_utimens, 3.4.0) int pub_glfs_utimens(struct glfs *fs, const char *path, const struct timespec times[2]) @@ -4190,8 +4184,7 @@ pub_glfs_utimens(struct glfs *fs, const char *path, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_utimens, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lutimens, 3.4.0) int pub_glfs_lutimens(struct glfs *fs, const char *path, const struct timespec times[2]) @@ -4211,8 +4204,7 @@ pub_glfs_lutimens(struct glfs *fs, const char *path, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lutimens, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_futimens, 3.4.0) int pub_glfs_futimens(struct glfs_fd *glfd, const struct timespec times[2]) { @@ -4231,8 +4223,6 @@ pub_glfs_futimens(struct glfs_fd *glfd, const struct timespec times[2]) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_futimens, 3.4.0); - int glfs_getxattr_process(void *value, size_t size, dict_t *xattr, const char *name) { @@ -4332,6 +4322,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getxattr, 3.4.0) ssize_t pub_glfs_getxattr(struct glfs *fs, const char *path, const char *name, void *value, size_t size) @@ -4339,8 +4330,7 @@ pub_glfs_getxattr(struct glfs *fs, const char *path, const char *name, return glfs_getxattr_common(fs, path, name, value, size, 1); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lgetxattr, 3.4.0) ssize_t pub_glfs_lgetxattr(struct glfs *fs, const char *path, const char *name, void *value, size_t size) @@ -4348,8 +4338,7 @@ pub_glfs_lgetxattr(struct glfs *fs, const char *path, const char *name, return glfs_getxattr_common(fs, path, name, value, size, 0); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lgetxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fgetxattr, 3.4.0) ssize_t pub_glfs_fgetxattr(struct glfs_fd *glfd, const char *name, void *value, size_t size) @@ -4412,8 +4401,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fgetxattr, 3.4.0); - int glfs_listxattr_process(void *value, size_t size, dict_t *xattr) { @@ -4497,22 +4484,21 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_listxattr, 3.4.0) ssize_t pub_glfs_listxattr(struct glfs *fs, const char *path, void *value, size_t size) { return glfs_listxattr_common(fs, path, value, size, 1); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_listxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_llistxattr, 3.4.0) ssize_t pub_glfs_llistxattr(struct glfs *fs, const char *path, void *value, size_t size) { return glfs_listxattr_common(fs, path, value, size, 0); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_llistxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_flistxattr, 3.4.0) ssize_t pub_glfs_flistxattr(struct glfs_fd *glfd, void *value, size_t size) { @@ -4562,8 +4548,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_flistxattr, 3.4.0); - int glfs_setxattr_common(struct glfs *fs, const char *path, const char *name, const void *value, size_t size, int flags, int follow) @@ -4643,6 +4627,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setxattr, 3.4.0) int pub_glfs_setxattr(struct glfs *fs, const char *path, const char *name, const void *value, size_t size, int flags) @@ -4650,8 +4635,7 @@ pub_glfs_setxattr(struct glfs *fs, const char *path, const char *name, return glfs_setxattr_common(fs, path, name, value, size, flags, 1); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lsetxattr, 3.4.0) int pub_glfs_lsetxattr(struct glfs *fs, const char *path, const char *name, const void *value, size_t size, int flags) @@ -4659,8 +4643,7 @@ pub_glfs_lsetxattr(struct glfs *fs, const char *path, const char *name, return glfs_setxattr_common(fs, path, name, value, size, flags, 0); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lsetxattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsetxattr, 3.4.0) int pub_glfs_fsetxattr(struct glfs_fd *glfd, const char *name, const void *value, size_t size, int flags) @@ -4735,8 +4718,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsetxattr, 3.4.0); - int glfs_removexattr_common(struct glfs *fs, const char *path, const char *name, int follow) @@ -4787,22 +4768,21 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_removexattr, 3.4.0) int pub_glfs_removexattr(struct glfs *fs, const char *path, const char *name) { return glfs_removexattr_common(fs, path, name, 1); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_removexattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lremovexattr, 3.4.0) int pub_glfs_lremovexattr(struct glfs *fs, const char *path, const char *name) { return glfs_removexattr_common(fs, path, name, 0); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lremovexattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fremovexattr, 3.4.0) int pub_glfs_fremovexattr(struct glfs_fd *glfd, const char *name) { @@ -4845,8 +4825,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fremovexattr, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fallocate, 3.5.0) int pub_glfs_fallocate(struct glfs_fd *glfd, int keep_size, off_t offset, size_t len) @@ -4897,8 +4876,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fallocate, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard, 3.5.0) int pub_glfs_discard(struct glfs_fd *glfd, off_t offset, size_t len) { @@ -4948,8 +4926,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill, 3.5.0) int pub_glfs_zerofill(struct glfs_fd *glfd, off_t offset, off_t len) { @@ -4997,8 +4974,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chdir, 3.4.0) int pub_glfs_chdir(struct glfs *fs, const char *path) { @@ -5048,8 +5024,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chdir, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchdir, 3.4.0) int pub_glfs_fchdir(struct glfs_fd *glfd) { @@ -5101,8 +5076,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchdir, 3.4.0); - static gf_boolean_t warn_realpath = _gf_true; /* log once */ static char * @@ -5185,22 +5158,21 @@ invalid_fs: return retpath; } +GFAPI_SYMVER_PUBLIC(glfs_realpath34, glfs_realpath, 3.4.0) char * pub_glfs_realpath34(struct glfs *fs, const char *path, char *resolved_path) { return glfs_realpath_common(fs, path, resolved_path, _gf_true); } -GFAPI_SYMVER_PUBLIC(glfs_realpath34, glfs_realpath, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_realpath, 3.7.17) char * pub_glfs_realpath(struct glfs *fs, const char *path, char *resolved_path) { return glfs_realpath_common(fs, path, resolved_path, _gf_false); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_realpath, 3.7.17); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getcwd, 3.4.0) char * pub_glfs_getcwd(struct glfs *fs, char *buf, size_t n) { @@ -5249,8 +5221,6 @@ invalid_fs: return buf; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getcwd, 3.4.0); - static void gf_flock_to_flock(struct gf_flock *gf_flock, struct flock *flock) { @@ -5357,6 +5327,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_file_lock, 4.0.0) int pub_glfs_file_lock(struct glfs_fd *glfd, int cmd, struct flock *flock, glfs_lock_mode_t lk_mode) @@ -5393,16 +5364,14 @@ out: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_file_lock, 4.0.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_posix_lock, 3.4.0) int pub_glfs_posix_lock(struct glfs_fd *glfd, int cmd, struct flock *flock) { return glfs_lock_common(glfd, cmd, flock, NULL); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_posix_lock, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fd_set_lkowner, 3.10.7) int pub_glfs_fd_set_lkowner(struct glfs_fd *glfd, void *data, int len) { @@ -5438,8 +5407,8 @@ out: invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fd_set_lkowner, 3.10.7); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_dup, 3.4.0) struct glfs_fd * pub_glfs_dup(struct glfs_fd *glfd) { @@ -5490,8 +5459,6 @@ invalid_fs: return dupfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_dup, 3.4.0); - static void glfs_enqueue_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data) { @@ -5797,6 +5764,7 @@ glfs_cbk_upcall_syncop(void *opaque) goto out; } else if (ret) { gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ENTRY, NULL); + GLFS_FREE(up_arg); goto out; } @@ -5975,6 +5943,7 @@ out: * Otherwise all the upcall events are queued up in a list * to be read/polled by the applications. */ +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_process_upcall_event, 3.7.0) void priv_glfs_process_upcall_event(struct glfs *fs, void *data) { @@ -6042,7 +6011,6 @@ out: err: return; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_process_upcall_event, 3.7.0); ssize_t glfs_anonymous_pwritev(struct glfs *fs, struct glfs_object *object, @@ -6228,6 +6196,7 @@ glfs_release_xreaddirp_stat(void *ptr) * Given glfd of a directory, this function does readdirp and returns * xstat along with dirents. */ +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_r, 3.11.0) int pub_glfs_xreaddirplus_r(struct glfs_fd *glfd, uint32_t flags, struct glfs_xreaddirp_stat **xstat_p, @@ -6336,8 +6305,8 @@ out: invalid_fs: return -1; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_r, 3.11.0); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_stat, 3.11.0) struct stat * pub_glfs_xreaddirplus_get_stat(struct glfs_xreaddirp_stat *xstat) { @@ -6353,7 +6322,6 @@ pub_glfs_xreaddirplus_get_stat(struct glfs_xreaddirp_stat *xstat) out: return NULL; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_stat, 3.11.0); void gf_lease_to_glfs_lease(struct gf_lease *gf_lease, struct glfs_lease *lease) @@ -6373,6 +6341,7 @@ glfs_lease_to_gf_lease(struct glfs_lease *lease, struct gf_lease *gf_lease) memcpy(gf_lease->lease_id, lease->lease_id, LEASE_ID_SIZE); } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lease, 4.0.0) int pub_glfs_lease(struct glfs_fd *glfd, struct glfs_lease *lease, glfs_recall_cbk fn, void *data) @@ -6474,5 +6443,3 @@ out: invalid_fs: return ret; } - -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lease, 4.0.0); diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c index cdac07124a5..53c2ee896f9 100644 --- a/api/src/glfs-handleops.c +++ b/api/src/glfs-handleops.c @@ -60,6 +60,7 @@ glfs_iatt_from_stat(struct stat *stat, int valid, struct iatt *iatt, return; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lookupat, 3.7.4) struct glfs_object * pub_glfs_h_lookupat(struct glfs *fs, struct glfs_object *parent, const char *path, struct stat *stat, int follow) @@ -126,8 +127,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lookupat, 3.7.4); - +GFAPI_SYMVER_PUBLIC(glfs_h_lookupat34, glfs_h_lookupat, 3.4.2) struct glfs_object * pub_glfs_h_lookupat34(struct glfs *fs, struct glfs_object *parent, const char *path, struct stat *stat) @@ -135,8 +135,7 @@ pub_glfs_h_lookupat34(struct glfs *fs, struct glfs_object *parent, return pub_glfs_h_lookupat(fs, parent, path, stat, 0); } -GFAPI_SYMVER_PUBLIC(glfs_h_lookupat34, glfs_h_lookupat, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_statfs, 3.7.0) int pub_glfs_h_statfs(struct glfs *fs, struct glfs_object *object, struct statvfs *statvfs) @@ -194,8 +193,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_statfs, 3.7.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_stat, 3.4.2) int pub_glfs_h_stat(struct glfs *fs, struct glfs_object *object, struct stat *stat) { @@ -259,8 +257,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_stat, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getattrs, 3.4.2) int pub_glfs_h_getattrs(struct glfs *fs, struct glfs_object *object, struct stat *stat) @@ -317,8 +314,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getattrs, 3.4.2); - int glfs_h_getxattrs_common(struct glfs *fs, struct glfs_object *object, dict_t **xattr, const char *name, @@ -380,6 +375,7 @@ out: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getxattrs, 3.5.1) int pub_glfs_h_getxattrs(struct glfs *fs, struct glfs_object *object, const char *name, void *value, size_t size) @@ -416,8 +412,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getxattrs, 3.5.1); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setattrs, 3.4.2) int pub_glfs_h_setattrs(struct glfs *fs, struct glfs_object *object, struct stat *stat, int valid) @@ -480,8 +475,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setattrs, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setxattrs, 3.5.0) int pub_glfs_h_setxattrs(struct glfs *fs, struct glfs_object *object, const char *name, const void *value, size_t size, @@ -568,8 +562,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setxattrs, 3.5.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_removexattrs, 3.5.1) int pub_glfs_h_removexattrs(struct glfs *fs, struct glfs_object *object, const char *name) @@ -626,8 +619,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_removexattrs, 3.5.1); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_open, 3.4.2) struct glfs_fd * pub_glfs_h_open(struct glfs *fs, struct glfs_object *object, int flags) { @@ -727,8 +719,7 @@ invalid_fs: return glfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_open, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat, 3.4.2) struct glfs_object * pub_glfs_h_creat(struct glfs *fs, struct glfs_object *parent, const char *path, int flags, mode_t mode, struct stat *stat) @@ -840,8 +831,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat_open, 6.6) struct glfs_object * pub_glfs_h_creat_open(struct glfs *fs, struct glfs_object *parent, const char *path, int flags, mode_t mode, @@ -975,8 +965,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat_open, 6.6); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mkdir, 3.4.2) struct glfs_object * pub_glfs_h_mkdir(struct glfs *fs, struct glfs_object *parent, const char *path, mode_t mode, struct stat *stat) @@ -1074,8 +1063,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mkdir, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mknod, 3.4.2) struct glfs_object * pub_glfs_h_mknod(struct glfs *fs, struct glfs_object *parent, const char *path, mode_t mode, dev_t dev, struct stat *stat) @@ -1172,8 +1160,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mknod, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_unlink, 3.4.2) int pub_glfs_h_unlink(struct glfs *fs, struct glfs_object *parent, const char *path) { @@ -1244,8 +1231,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_unlink, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_opendir, 3.4.2) struct glfs_fd * pub_glfs_h_opendir(struct glfs *fs, struct glfs_object *object) { @@ -1327,8 +1313,7 @@ invalid_fs: return glfd; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_opendir, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_access, 3.6.0) int pub_glfs_h_access(struct glfs *fs, struct glfs_object *object, int mask) { @@ -1385,8 +1370,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_access, 3.6.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_extract_handle, 3.4.2) ssize_t pub_glfs_h_extract_handle(struct glfs_object *object, unsigned char *handle, int len) @@ -1417,8 +1401,7 @@ out: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_extract_handle, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_create_from_handle, 3.4.2) struct glfs_object * pub_glfs_h_create_from_handle(struct glfs *fs, unsigned char *handle, int len, struct stat *stat) @@ -1541,8 +1524,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_create_from_handle, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_close, 3.4.2) int pub_glfs_h_close(struct glfs_object *object) { @@ -1555,8 +1537,7 @@ pub_glfs_h_close(struct glfs_object *object) return 0; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_close, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_truncate, 3.4.2) int pub_glfs_h_truncate(struct glfs *fs, struct glfs_object *object, off_t offset) { @@ -1616,8 +1597,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_truncate, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_symlink, 3.4.2) struct glfs_object * pub_glfs_h_symlink(struct glfs *fs, struct glfs_object *parent, const char *name, const char *data, struct stat *stat) @@ -1716,8 +1696,7 @@ invalid_fs: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_symlink, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_readlink, 3.4.2) int pub_glfs_h_readlink(struct glfs *fs, struct glfs_object *object, char *buf, size_t bufsiz) @@ -1782,8 +1761,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_readlink, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_link, 3.4.2) int pub_glfs_h_link(struct glfs *fs, struct glfs_object *linksrc, struct glfs_object *parent, const char *name) @@ -1880,8 +1858,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_link, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2) int pub_glfs_h_rename(struct glfs *fs, struct glfs_object *olddir, const char *oldname, struct glfs_object *newdir, @@ -1991,8 +1968,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2); - /* * Given a handle/gfid, find if the corresponding inode is present in * the inode table. If yes create and return the corresponding glfs_object. @@ -2200,6 +2175,7 @@ glfs_release_upcall(void *ptr) * calling glfs_fini(..). Hence making an assumption that 'fs' & ctx structures * cannot be freed while in this routine. */ +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_poll_upcall, 3.7.16) int pub_glfs_h_poll_upcall(struct glfs *fs, struct glfs_upcall **up_arg) { @@ -2317,8 +2293,6 @@ err: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_poll_upcall, 3.7.16); - static gf_boolean_t log_upcall370 = _gf_true; /* log once */ /* The old glfs_h_poll_upcall interface requires intimate knowledge of the @@ -2332,6 +2306,7 @@ static gf_boolean_t log_upcall370 = _gf_true; /* log once */ * * WARNING: this function will be removed in the future. */ +GFAPI_SYMVER_PUBLIC(glfs_h_poll_upcall370, glfs_h_poll_upcall, 3.7.0) int pub_glfs_h_poll_upcall370(struct glfs *fs, struct glfs_callback_arg *up_arg) { @@ -2399,12 +2374,11 @@ out: return ret; } -GFAPI_SYMVER_PUBLIC(glfs_h_poll_upcall370, glfs_h_poll_upcall, 3.7.0); - #ifdef HAVE_ACL_LIBACL_H #include <glusterfs/glusterfs-acl.h> #include <acl/libacl.h> +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0) int pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object, const acl_type_t type, const acl_t acl) @@ -2453,6 +2427,7 @@ invalid_fs: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0) acl_t pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object, const acl_type_t type) @@ -2507,6 +2482,7 @@ invalid_fs: return acl; } #else /* !HAVE_ACL_LIBACL_H */ +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0) acl_t pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object, const acl_type_t type) @@ -2515,6 +2491,7 @@ pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object, return NULL; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0) int pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object, const acl_type_t type, const acl_t acl) @@ -2523,10 +2500,9 @@ pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object, return -1; } #endif -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0); -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0); /* The API to perform read using anonymous fd */ +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_read, 3.7.0) ssize_t pub_glfs_h_anonymous_read(struct glfs *fs, struct glfs_object *object, const void *buf, size_t count, off_t offset) @@ -2550,9 +2526,8 @@ pub_glfs_h_anonymous_read(struct glfs *fs, struct glfs_object *object, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_read, 3.7.0); - /* The API to perform write using anonymous fd */ +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_write, 3.7.0) ssize_t pub_glfs_h_anonymous_write(struct glfs *fs, struct glfs_object *object, const void *buf, size_t count, off_t offset) @@ -2576,8 +2551,7 @@ pub_glfs_h_anonymous_write(struct glfs *fs, struct glfs_object *object, return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_write, 3.7.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_object_copy, 3.11.0) struct glfs_object * pub_glfs_object_copy(struct glfs_object *src) { @@ -2599,8 +2573,8 @@ pub_glfs_object_copy(struct glfs_object *src) out: return object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_object_copy, 3.11.0); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_object, 3.11.0) struct glfs_object * pub_glfs_xreaddirplus_get_object(struct glfs_xreaddirp_stat *xstat) { @@ -2616,8 +2590,8 @@ pub_glfs_xreaddirplus_get_object(struct glfs_xreaddirp_stat *xstat) out: return NULL; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_object, 3.11.0); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lease, 4.0.0) int pub_glfs_h_lease(struct glfs *fs, struct glfs_object *object, struct glfs_lease *lease) @@ -2679,5 +2653,3 @@ out: invalid_fs: return ret; } - -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lease, 4.0.0); diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h index 55401b2910e..7cc3b18a104 100644 --- a/api/src/glfs-internal.h +++ b/api/src/glfs-internal.h @@ -16,6 +16,7 @@ #include <glusterfs/upcall-utils.h> #include "glfs-handles.h" #include <glusterfs/refcount.h> +#include <glusterfs/syncop.h> #define GLFS_SYMLINK_MAX_FOLLOW 2048 @@ -80,25 +81,40 @@ #ifndef GFAPI_PRIVATE #define GFAPI_PRIVATE(sym, ver) /**/ #endif +#if __GNUC__ >= 10 #define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, ver) \ - asm(".symver pub_" STR(fn) ", " STR(fn) "@@GFAPI_" STR(ver)) + __attribute__((__symver__(STR(fn) "@@GFAPI_" STR(ver)))) #define GFAPI_SYMVER_PRIVATE_DEFAULT(fn, ver) \ - asm(".symver priv_" STR(fn) ", " STR(fn) "@@GFAPI_PRIVATE_" STR(ver)) + __attribute__((__symver__(STR(fn) "@@GFAPI_PRIVATE_" STR(ver)))) #define GFAPI_SYMVER_PUBLIC(fn1, fn2, ver) \ - asm(".symver pub_" STR(fn1) ", " STR(fn2) "@GFAPI_" STR(ver)) + __attribute__((__symver__(STR(fn2) "@GFAPI_" STR(ver)))) #define GFAPI_SYMVER_PRIVATE(fn1, fn2, ver) \ - asm(".symver priv_" STR(fn1) ", " STR(fn2) "@GFAPI_PRIVATE_" STR(ver)) + __attribute__((__symver__(STR(fn2) "@GFAPI_PRIVATE_" STR(ver)))) + +#else +#define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, ver) \ + asm(".symver pub_" STR(fn) ", " STR(fn) "@@GFAPI_" STR(ver)); + +#define GFAPI_SYMVER_PRIVATE_DEFAULT(fn, ver) \ + asm(".symver priv_" STR(fn) ", " STR(fn) "@@GFAPI_PRIVATE_" STR(ver)); + +#define GFAPI_SYMVER_PUBLIC(fn1, fn2, ver) \ + asm(".symver pub_" STR(fn1) ", " STR(fn2) "@GFAPI_" STR(ver)); + +#define GFAPI_SYMVER_PRIVATE(fn1, fn2, ver) \ + asm(".symver priv_" STR(fn1) ", " STR(fn2) "@GFAPI_PRIVATE_" STR(ver)); +#endif #define STR(str) #str #else #ifndef GFAPI_PUBLIC -#define GFAPI_PUBLIC(sym, ver) __asm("_" __STRING(sym) "$GFAPI_" __STRING(ver)) +#define GFAPI_PUBLIC(sym, ver) __asm("_" __STRING(sym) "$GFAPI_" __STRING(ver)); #endif #ifndef GFAPI_PRIVATE #define GFAPI_PRIVATE(sym, ver) \ - __asm("_" __STRING(sym) "$GFAPI_PRIVATE_" __STRING(ver)) + __asm("_" __STRING(sym) "$GFAPI_PRIVATE_" __STRING(ver)); #endif #define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, dotver) /**/ #define GFAPI_SYMVER_PRIVATE_DEFAULT(fn, dotver) /**/ @@ -207,6 +223,7 @@ struct glfs { glfs_upcall_cbk up_cbk; /* upcall cbk function to be registered */ void *up_data; /* Opaque data provided by application * during upcall registration */ + struct list_head waitq; /* waiting synctasks */ }; /* This enum is used to maintain the state of glfd. In case of async fops @@ -442,6 +459,34 @@ glfs_process_upcall_event(struct glfs *fs, void *data) THIS = glfd->fd->inode->table->xl->ctx->master; \ } while (0) +#define __GLFS_LOCK_WAIT(fs) \ + do { \ + struct synctask *task = NULL; \ + \ + task = synctask_get(); \ + \ + if (task) { \ + list_add_tail(&task->waitq, &fs->waitq); \ + pthread_mutex_unlock(&fs->mutex); \ + synctask_yield(task, NULL); \ + pthread_mutex_lock(&fs->mutex); \ + } else { \ + /* non-synctask */ \ + pthread_cond_wait(&fs->cond, &fs->mutex); \ + } \ + } while (0) + +#define __GLFS_SYNCTASK_WAKE(fs) \ + do { \ + struct synctask *waittask = NULL; \ + \ + while (!list_empty(&fs->waitq)) { \ + waittask = list_entry(fs->waitq.next, struct synctask, waitq); \ + list_del_init(&waittask->waitq); \ + synctask_wake(waittask); \ + } \ + } while (0) + /* By default all lock attempts from user context must use glfs_lock() and glfs_unlock(). This allows @@ -466,10 +511,10 @@ glfs_lock(struct glfs *fs, gf_boolean_t wait_for_migration) pthread_mutex_lock(&fs->mutex); while (!fs->init) - pthread_cond_wait(&fs->cond, &fs->mutex); + __GLFS_LOCK_WAIT(fs); while (wait_for_migration && fs->migration_in_progress) - pthread_cond_wait(&fs->cond, &fs->mutex); + __GLFS_LOCK_WAIT(fs); return 0; } diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c index 7271e35ec3f..7c82b8cd162 100644 --- a/api/src/glfs-mgmt.c +++ b/api/src/glfs-mgmt.c @@ -364,6 +364,7 @@ out: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volumeid, 3.5.0) int pub_glfs_get_volumeid(struct glfs *fs, char *volid, size_t size) { @@ -418,8 +419,6 @@ invalid_fs: return -1; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volumeid, 3.5.0); - int glfs_get_volume_info(struct glfs *fs) { @@ -1014,11 +1013,6 @@ glfs_mgmt_init(struct glfs *fs) if (ret) goto out; - if (sys_access(SECURE_ACCESS_FILE, F_OK) == 0) { - ctx->secure_mgmt = 1; - ctx->ssl_cert_depth = glusterfs_read_secure_access_file(); - } - rpc = rpc_clnt_new(options, THIS, THIS->name, 8); if (!rpc) { ret = -1; diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c index 4b6f76961ee..8a393ecb464 100644 --- a/api/src/glfs-resolve.c +++ b/api/src/glfs-resolve.c @@ -65,6 +65,9 @@ __glfs_first_lookup(struct glfs *fs, xlator_t *subvol) fs->migration_in_progress = 0; pthread_cond_broadcast(&fs->cond); + /* wake up other waiting tasks */ + __GLFS_SYNCTASK_WAKE(fs); + return ret; } @@ -153,9 +156,13 @@ __glfs_refresh_inode(struct glfs *fs, xlator_t *subvol, inode_t *inode, fs->migration_in_progress = 0; pthread_cond_broadcast(&fs->cond); + /* wake up other waiting tasks */ + __GLFS_SYNCTASK_WAKE(fs); + return newinode; } +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_loc_touchup, 3.4.0) int priv_glfs_loc_touchup(loc_t *loc) { @@ -170,8 +177,6 @@ priv_glfs_loc_touchup(loc_t *loc) return ret; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_loc_touchup, 3.4.0); - int glfs_resolve_symlink(struct glfs *fs, xlator_t *subvol, inode_t *inode, char **lpath) @@ -461,6 +466,7 @@ out: return inode; } +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve_at, 3.4.0) int priv_glfs_resolve_at(struct glfs *fs, xlator_t *subvol, inode_t *at, const char *origpath, loc_t *loc, struct iatt *iatt, @@ -611,8 +617,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve_at, 3.4.0); - int glfs_resolve_path(struct glfs *fs, xlator_t *subvol, const char *origpath, loc_t *loc, struct iatt *iatt, int follow, int reval) @@ -641,6 +645,7 @@ out: return ret; } +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve, 3.7.0) int priv_glfs_resolve(struct glfs *fs, xlator_t *subvol, const char *origpath, loc_t *loc, struct iatt *iatt, int reval) @@ -651,7 +656,6 @@ priv_glfs_resolve(struct glfs *fs, xlator_t *subvol, const char *origpath, return ret; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve, 3.7.0); int glfs_lresolve(struct glfs *fs, xlator_t *subvol, const char *origpath, @@ -722,6 +726,7 @@ glfs_migrate_fd_safe(struct glfs *fs, xlator_t *newsubvol, fd_t *oldfd) 0, }; char uuid1[64]; + dict_t *xdata = NULL; oldinode = oldfd->inode; oldsubvol = oldinode->table->xl; @@ -730,7 +735,16 @@ glfs_migrate_fd_safe(struct glfs *fs, xlator_t *newsubvol, fd_t *oldfd) return fd_ref(oldfd); if (!oldsubvol->switched) { - ret = syncop_fsync(oldsubvol, oldfd, 0, NULL, NULL, NULL, NULL); + xdata = dict_new(); + if (!xdata || dict_set_int8(xdata, "last-fsync", 1)) { + gf_smsg(fs->volname, GF_LOG_WARNING, ENOMEM, API_MSG_FSYNC_FAILED, + "err=%s", "last-fsync set failed", "gfid=%s", + uuid_utoa_r(oldfd->inode->gfid, uuid1), "subvol=%s", + graphid_str(oldsubvol), "id=%d", oldsubvol->graph->id, + NULL); + } + + ret = syncop_fsync(oldsubvol, oldfd, 0, NULL, NULL, xdata, NULL); DECODE_SYNCOP_ERR(ret); if (ret) { gf_smsg(fs->volname, GF_LOG_WARNING, errno, API_MSG_FSYNC_FAILED, @@ -810,6 +824,9 @@ out: newfd = NULL; } + if (xdata) + dict_unref(xdata); + return newfd; } @@ -830,6 +847,9 @@ __glfs_migrate_fd(struct glfs *fs, xlator_t *newsubvol, struct glfs_fd *glfd) fs->migration_in_progress = 0; pthread_cond_broadcast(&fs->cond); + /* wake up other waiting tasks */ + __GLFS_SYNCTASK_WAKE(fs); + return newfd; } @@ -956,6 +976,7 @@ __glfs_active_subvol(struct glfs *fs) return new_subvol; } +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_subvol_done, 3.4.0) void priv_glfs_subvol_done(struct glfs *fs, xlator_t *subvol) { @@ -983,8 +1004,7 @@ priv_glfs_subvol_done(struct glfs *fs, xlator_t *subvol) } } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_subvol_done, 3.4.0); - +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_active_subvol, 3.4.0) xlator_t * priv_glfs_active_subvol(struct glfs *fs) { @@ -1012,8 +1032,6 @@ priv_glfs_active_subvol(struct glfs *fs) return subvol; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_active_subvol, 3.4.0); - int __glfs_cwd_set(struct glfs *fs, inode_t *inode) { diff --git a/api/src/glfs.c b/api/src/glfs.c index 5f683451c21..b4bf1423f6d 100644 --- a/api/src/glfs.c +++ b/api/src/glfs.c @@ -251,6 +251,11 @@ glfs_volumes_init(struct glfs *fs) if (!vol_assigned(cmd_args)) return -1; + if (sys_access(SECURE_ACCESS_FILE, F_OK) == 0) { + fs->ctx->secure_mgmt = 1; + fs->ctx->ssl_cert_depth = glusterfs_read_secure_access_file(); + } + if (cmd_args->volfile_server) { ret = glfs_mgmt_init(fs); goto out; @@ -275,6 +280,7 @@ out: /////////////////////////////////////////////////////////////////////////////// +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_xlator_option, 3.4.0) int pub_glfs_set_xlator_option(struct glfs *fs, const char *xlator, const char *key, const char *value) @@ -324,8 +330,7 @@ invalid_fs: return -1; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_xlator_option, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unset_volfile_server, 3.5.1) int pub_glfs_unset_volfile_server(struct glfs *fs, const char *transport, const char *host, const int port) @@ -385,8 +390,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unset_volfile_server, 3.5.1); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile_server, 3.4.0) int pub_glfs_set_volfile_server(struct glfs *fs, const char *transport, const char *host, int port) @@ -465,8 +469,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile_server, 3.4.0); - /* * * Used to free the arguments allocated by glfs_set_volfile_server() */ @@ -509,6 +511,7 @@ glfs_free_xlator_options(cmd_args_t *cmd_args) } } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsuid, 3.4.2) int pub_glfs_setfsuid(uid_t fsuid) { @@ -518,8 +521,7 @@ pub_glfs_setfsuid(uid_t fsuid) return syncopctx_setfsuid(&fsuid); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsuid, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgid, 3.4.2) int pub_glfs_setfsgid(gid_t fsgid) { @@ -529,8 +531,7 @@ pub_glfs_setfsgid(gid_t fsgid) return syncopctx_setfsgid(&fsgid); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgid, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgroups, 3.4.2) int pub_glfs_setfsgroups(size_t size, const gid_t *list) { @@ -540,8 +541,7 @@ pub_glfs_setfsgroups(size_t size, const gid_t *list) return syncopctx_setfsgroups(size, list); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgroups, 3.4.2); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsleaseid, 4.0.0) int pub_glfs_setfsleaseid(glfs_leaseid_t leaseid) { @@ -563,8 +563,6 @@ pub_glfs_setfsleaseid(glfs_leaseid_t leaseid) return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsleaseid, 4.0.0); - int get_fop_attr_glfd(dict_t **fop_attr, struct glfs_fd *glfd) { @@ -652,14 +650,19 @@ unset_fop_attr(dict_t **fop_attr) *fop_attr = NULL; } } + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_from_glfd, 3.4.0) struct glfs * pub_glfs_from_glfd(struct glfs_fd *glfd) { + if (glfd == NULL) { + errno = EBADF; + return NULL; + } + return glfd->fs; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_from_glfd, 3.4.0); - static void glfs_fd_destroy(struct glfs_fd *glfd) { @@ -737,6 +740,7 @@ glfs_new_fs(const char *volname) INIT_LIST_HEAD(&fs->openfds); INIT_LIST_HEAD(&fs->upcall_list); + INIT_LIST_HEAD(&fs->waitq); PTHREAD_MUTEX_INIT(&fs->mutex, NULL, fs->pthread_flags, GLFS_INIT_MUTEX, err); @@ -807,6 +811,7 @@ unlock: return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_new, 3.4.0) struct glfs * pub_glfs_new(const char *volname) { @@ -913,8 +918,7 @@ out: return fs; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_new, 3.4.0); - +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_new_from_ctx, 3.7.0) struct glfs * priv_glfs_new_from_ctx(glusterfs_ctx_t *ctx) { @@ -933,8 +937,7 @@ out: return fs; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_new_from_ctx, 3.7.0); - +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_free_from_ctx, 3.7.0) void priv_glfs_free_from_ctx(struct glfs *fs) { @@ -970,8 +973,7 @@ priv_glfs_free_from_ctx(struct glfs *fs) FREE(fs); } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_free_from_ctx, 3.7.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile, 3.4.0) int pub_glfs_set_volfile(struct glfs *fs, const char *volfile) { @@ -988,8 +990,7 @@ pub_glfs_set_volfile(struct glfs *fs, const char *volfile) return 0; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_logging, 3.4.0) int pub_glfs_set_logging(struct glfs *fs, const char *logfile, int loglevel) { @@ -1027,8 +1028,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_logging, 3.4.0); - int glfs_init_wait(struct glfs *fs) { @@ -1047,6 +1046,7 @@ glfs_init_wait(struct glfs *fs) return ret; } +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_init_done, 3.4.0) void priv_glfs_init_done(struct glfs *fs, int ret) { @@ -1077,8 +1077,6 @@ out: return; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_init_done, 3.4.0); - int glfs_init_common(struct glfs *fs) { @@ -1118,6 +1116,7 @@ glfs_init_async(struct glfs *fs, glfs_init_cbk cbk) return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_init, 3.4.0) int pub_glfs_init(struct glfs *fs) { @@ -1150,8 +1149,6 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_init, 3.4.0); - static int glusterfs_ctx_destroy(glusterfs_ctx_t *ctx) { @@ -1229,6 +1226,7 @@ glusterfs_ctx_destroy(glusterfs_ctx_t *ctx) return ret; } +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fini, 3.4.0) int pub_glfs_fini(struct glfs *fs) { @@ -1240,6 +1238,7 @@ pub_glfs_fini(struct glfs *fs) call_pool_t *call_pool = NULL; int fs_init = 0; int err = -1; + struct synctask *waittask = NULL; DECLARE_OLD_THIS; @@ -1261,6 +1260,13 @@ pub_glfs_fini(struct glfs *fs) call_pool = fs->ctx->pool; + /* Wake up any suspended synctasks */ + while (!list_empty(&fs->waitq)) { + waittask = list_entry(fs->waitq.next, struct synctask, waitq); + list_del_init(&waittask->waitq); + synctask_wake(waittask); + } + while (countdown--) { /* give some time for background frames to finish */ pthread_mutex_lock(&fs->mutex); @@ -1411,8 +1417,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fini, 3.4.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volfile, 3.6.0) ssize_t pub_glfs_get_volfile(struct glfs *fs, void *buf, size_t len) { @@ -1438,8 +1443,7 @@ invalid_fs: return res; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volfile, 3.6.0); - +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_ipc, 3.12.0) int priv_glfs_ipc(struct glfs *fs, int opcode, void *xd_in, void **xd_out) { @@ -1467,8 +1471,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_ipc, 3.12.0); - +GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_setfspid, 6.1) int priv_glfs_setfspid(struct glfs *fs, pid_t pid) { @@ -1482,107 +1485,104 @@ priv_glfs_setfspid(struct glfs *fs, pid_t pid) return ret; } -GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_setfspid, 6.1); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_free, 3.7.16) void pub_glfs_free(void *ptr) { GLFS_FREE(ptr); } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_free, 3.7.16); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_fs, 3.7.16) struct glfs * pub_glfs_upcall_get_fs(struct glfs_upcall *arg) { return arg->fs; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_fs, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_reason, 3.7.16) enum glfs_upcall_reason pub_glfs_upcall_get_reason(struct glfs_upcall *arg) { return arg->reason; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_reason, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_event, 3.7.16) void * pub_glfs_upcall_get_event(struct glfs_upcall *arg) { return arg->event; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_event, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_object, 3.7.16) struct glfs_object * pub_glfs_upcall_inode_get_object(struct glfs_upcall_inode *arg) { return arg->object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_object, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_flags, 3.7.16) uint64_t pub_glfs_upcall_inode_get_flags(struct glfs_upcall_inode *arg) { return arg->flags; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_flags, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_stat, 3.7.16) struct stat * pub_glfs_upcall_inode_get_stat(struct glfs_upcall_inode *arg) { return &arg->buf; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_stat, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_expire, 3.7.16) uint64_t pub_glfs_upcall_inode_get_expire(struct glfs_upcall_inode *arg) { return arg->expire_time_attr; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_expire, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pobject, 3.7.16) struct glfs_object * pub_glfs_upcall_inode_get_pobject(struct glfs_upcall_inode *arg) { return arg->p_object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pobject, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pstat, 3.7.16) struct stat * pub_glfs_upcall_inode_get_pstat(struct glfs_upcall_inode *arg) { return &arg->p_buf; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pstat, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpobject, 3.7.16) struct glfs_object * pub_glfs_upcall_inode_get_oldpobject(struct glfs_upcall_inode *arg) { return arg->oldp_object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpobject, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpstat, 3.7.16) struct stat * pub_glfs_upcall_inode_get_oldpstat(struct glfs_upcall_inode *arg) { return &arg->oldp_buf; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpstat, 3.7.16); +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_object, 4.1.6) struct glfs_object * pub_glfs_upcall_lease_get_object(struct glfs_upcall_lease *arg) { return arg->object; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_object, 4.1.6); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_lease_type, 4.1.6) uint32_t pub_glfs_upcall_lease_get_lease_type(struct glfs_upcall_lease *arg) { return arg->lease_type; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_lease_type, 4.1.6); /* definitions of the GLFS_SYSRQ_* chars are in glfs.h */ static struct glfs_sysrq_help { @@ -1592,6 +1592,7 @@ static struct glfs_sysrq_help { {GLFS_SYSRQ_STATEDUMP, "(S)tatedump"}, {0, NULL}}; +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_sysrq, 3.10.0) int pub_glfs_sysrq(struct glfs *fs, char sysrq) { @@ -1640,8 +1641,7 @@ out: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_sysrq, 3.10.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_register, 3.13.0) int pub_glfs_upcall_register(struct glfs *fs, uint32_t event_list, glfs_upcall_cbk cbk, void *data) @@ -1697,8 +1697,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_register, 3.13.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_unregister, 3.13.0) int pub_glfs_upcall_unregister(struct glfs *fs, uint32_t event_list) { @@ -1745,8 +1744,7 @@ invalid_fs: return ret; } -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_unregister, 3.13.0); - +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_statedump_path, 7.0) int pub_glfs_set_statedump_path(struct glfs *fs, const char *path) { @@ -1806,5 +1804,3 @@ err: invalid_fs: return -1; } - -GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_statedump_path, 7.0); diff --git a/cli/src/cli-cmd-global.c b/cli/src/cli-cmd-global.c index ba3c1ea6446..2c9a5f01bb1 100644 --- a/cli/src/cli-cmd-global.c +++ b/cli/src/cli-cmd-global.c @@ -27,8 +27,6 @@ #include <glusterfs/syscall.h> #include <glusterfs/common-utils.h> -extern rpc_clnt_prog_t *cli_rpc_prog; - int cli_cmd_global_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word, const char **words, int wordcount); diff --git a/cli/src/cli-cmd-misc.c b/cli/src/cli-cmd-misc.c index 658677bbca3..e961d88da86 100644 --- a/cli/src/cli-cmd-misc.c +++ b/cli/src/cli-cmd-misc.c @@ -18,10 +18,6 @@ #include "cli-mem-types.h" #include "protocol-common.h" -extern struct rpc_clnt *global_rpc; - -extern rpc_clnt_prog_t *cli_rpc_prog; - extern struct cli_cmd volume_cmds[]; extern struct cli_cmd bitrot_cmds[]; extern struct cli_cmd quota_cmds[]; diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index aeac4c7c697..34620b4a31b 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -3906,8 +3906,6 @@ heal_command_type_get(const char *command) [GF_SHD_OP_HEAL_INDEX] = NULL, [GF_SHD_OP_HEAL_FULL] = "full", [GF_SHD_OP_INDEX_SUMMARY] = "info", - [GF_SHD_OP_HEALED_FILES] = NULL, - [GF_SHD_OP_HEAL_FAILED_FILES] = NULL, [GF_SHD_OP_SPLIT_BRAIN_FILES] = NULL, [GF_SHD_OP_STATISTICS] = "statistics", [GF_SHD_OP_STATISTICS_HEAL_COUNT] = NULL, @@ -5587,9 +5585,9 @@ cli_cmd_bitrot_parse(const char **words, int wordcount, dict_t **options) int32_t ret = -1; char *w = NULL; char *volname = NULL; - static char *opwords[] = { - "enable", "disable", "scrub-throttle", "scrub-frequency", "scrub", - "signing-time", NULL}; + static char *opwords[] = {"enable", "disable", "scrub-throttle", + "scrub-frequency", "scrub", "signing-time", + "signer-threads", NULL}; static char *scrub_throt_values[] = {"lazy", "normal", "aggressive", NULL}; static char *scrub_freq_values[] = { "hourly", "daily", "weekly", "biweekly", "monthly", "minute", NULL}; @@ -5598,6 +5596,7 @@ cli_cmd_bitrot_parse(const char **words, int wordcount, dict_t **options) dict_t *dict = NULL; gf_bitrot_type type = GF_BITROT_OPTION_TYPE_NONE; int32_t expiry_time = 0; + int32_t signer_th_count = 0; GF_ASSERT(words); GF_ASSERT(options); @@ -5778,6 +5777,31 @@ cli_cmd_bitrot_parse(const char **words, int wordcount, dict_t **options) } goto set_type; } + } else if (!strcmp(words[3], "signer-threads")) { + if (!words[4]) { + cli_err( + "Missing signer-thread value for bitrot " + "option"); + ret = -1; + goto out; + } else { + type = GF_BITROT_OPTION_TYPE_SIGNER_THREADS; + + signer_th_count = strtol(words[4], NULL, 0); + if (signer_th_count < 1) { + cli_err("signer-thread count should not be less than 1"); + ret = -1; + goto out; + } + + ret = dict_set_uint32(dict, "signer-threads", + (unsigned int)signer_th_count); + if (ret) { + cli_out("Failed to set dict for bitrot"); + goto out; + } + goto set_type; + } } else { cli_err( "Invalid option %s for bitrot. Please enter valid " @@ -5786,7 +5810,6 @@ cli_cmd_bitrot_parse(const char **words, int wordcount, dict_t **options) ret = -1; goto out; } - set_type: ret = dict_set_int32(dict, "type", type); if (ret < 0) diff --git a/cli/src/cli-cmd-peer.c b/cli/src/cli-cmd-peer.c index 342b1d67aaa..084998701d8 100644 --- a/cli/src/cli-cmd-peer.c +++ b/cli/src/cli-cmd-peer.c @@ -20,10 +20,6 @@ #include "protocol-common.h" #include <glusterfs/events.h> -extern struct rpc_clnt *global_rpc; - -extern rpc_clnt_prog_t *cli_rpc_prog; - int cli_cmd_peer_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word, const char **words, int wordcount); diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c index 176c6d745b5..859d6b2e40d 100644 --- a/cli/src/cli-cmd-snapshot.c +++ b/cli/src/cli-cmd-snapshot.c @@ -17,8 +17,6 @@ #include "cli-cmd.h" #include "cli-mem-types.h" -extern rpc_clnt_prog_t *cli_rpc_prog; - int cli_cmd_snapshot_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word, const char **words, int wordcount); diff --git a/cli/src/cli-cmd-system.c b/cli/src/cli-cmd-system.c index d5732630582..801e8f4efed 100644 --- a/cli/src/cli-cmd-system.c +++ b/cli/src/cli-cmd-system.c @@ -18,10 +18,6 @@ #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); diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index e6144932144..f238851586e 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -28,10 +28,6 @@ #include <glusterfs/common-utils.h> #include <glusterfs/events.h> -extern struct rpc_clnt *global_rpc; -extern struct rpc_clnt *global_quotad_rpc; - -extern rpc_clnt_prog_t *cli_rpc_prog; extern rpc_clnt_prog_t cli_quotad_clnt; static int @@ -2967,6 +2963,16 @@ struct cli_cmd bitrot_cmds[] = { {"volume bitrot <VOLNAME> {enable|disable}", NULL, /*cli_cmd_bitrot_cbk,*/ "Enable/disable bitrot for volume <VOLNAME>"}, + {"volume bitrot <VOLNAME> signing-time <time-in-secs>", + NULL, /*cli_cmd_bitrot_cbk,*/ + "Waiting time for an object after last fd is closed to start signing " + "process"}, + + {"volume bitrot <VOLNAME> signer-threads <count>", + NULL, /*cli_cmd_bitrot_cbk,*/ + "Number of signing process threads. Usually set to number of available " + "cores"}, + {"volume bitrot <VOLNAME> scrub-throttle {lazy|normal|aggressive}", NULL, /*cli_cmd_bitrot_cbk,*/ "Set the speed of the scrubber for volume <VOLNAME>"}, @@ -2982,6 +2988,8 @@ struct cli_cmd bitrot_cmds[] = { "the scrubber. ondemand starts the scrubber immediately."}, {"volume bitrot <VOLNAME> {enable|disable}\n" + "volume bitrot <VOLNAME> signing-time <time-in-secs>\n" + "volume bitrot <VOLNAME> signer-threads <count>\n" "volume bitrot <volname> scrub-throttle {lazy|normal|aggressive}\n" "volume bitrot <volname> scrub-frequency {hourly|daily|weekly|biweekly" "|monthly}\n" diff --git a/cli/src/cli-cmd.c b/cli/src/cli-cmd.c index af009757e93..2d458b16a56 100644 --- a/cli/src/cli-cmd.c +++ b/cli/src/cli-cmd.c @@ -28,7 +28,7 @@ static pthread_cond_t conn = PTHREAD_COND_INITIALIZER; static pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER; int cli_op_ret = 0; -int connected = 0; +static gf_boolean_t connected = _gf_false; static unsigned cli_cmd_needs_connection(struct cli_cmd_word *word) @@ -328,19 +328,32 @@ cli_cmd_await_connected(unsigned conn_timo) } int32_t -cli_cmd_broadcast_connected() +cli_cmd_broadcast_connected(gf_boolean_t status) { pthread_mutex_lock(&conn_mutex); { - connected = 1; + connected = status; pthread_cond_broadcast(&conn); } - pthread_mutex_unlock(&conn_mutex); return 0; } +gf_boolean_t +cli_cmd_connected(void) +{ + gf_boolean_t status; + + pthread_mutex_lock(&conn_mutex); + { + status = connected; + } + pthread_mutex_unlock(&conn_mutex); + + return status; +} + int cli_cmd_submit(struct rpc_clnt *rpc, void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref, diff --git a/cli/src/cli-quotad-client.c b/cli/src/cli-quotad-client.c index 52ab97ee815..772b8f75bd9 100644 --- a/cli/src/cli-quotad-client.c +++ b/cli/src/cli-quotad-client.c @@ -10,9 +10,6 @@ #include "cli-quotad-client.h" -extern struct rpc_clnt global_quotad_rpc; -extern struct rpc_clnt_program cli_quotad_clnt; - int cli_quotad_submit_request(void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref, xlator_t *this, @@ -60,7 +57,7 @@ cli_quotad_submit_request(void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, } /* Send the msg */ - ret = rpc_clnt_submit(&global_quotad_rpc, prog, procnum, cbkfn, &iov, count, + ret = rpc_clnt_submit(global_quotad_rpc, prog, procnum, cbkfn, &iov, count, NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL); ret = 0; diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 0f57d94b506..9b6b0c7fa50 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -47,10 +47,7 @@ enum gf_task_types { GF_TASK_TYPE_REBALANCE, GF_TASK_TYPE_REMOVE_BRICK }; -extern struct rpc_clnt *global_quotad_rpc; rpc_clnt_prog_t cli_quotad_clnt; -extern rpc_clnt_prog_t *cli_rpc_prog; -extern int connected; static int32_t gf_cli_remove_brick(call_frame_t *frame, xlator_t *this, void *data); @@ -158,9 +155,9 @@ gf_cli_probe_cbk(struct rpc_req *req, struct iovec *iov, int count, gf_log("cli", GF_LOG_INFO, "Received resp to probe"); - if (rsp.op_ret) { - if (rsp.op_errstr && rsp.op_errstr[0] != '\0') { - snprintf(msg, sizeof(msg), "%s", rsp.op_errstr); + if (rsp.op_errstr && rsp.op_errstr[0] != '\0') { + snprintf(msg, sizeof(msg), "%s", rsp.op_errstr); + if (rsp.op_ret) { gf_log("cli", GF_LOG_ERROR, "%s", msg); } } @@ -3406,7 +3403,7 @@ gf_cli_quota_list(cli_local_t *local, char *volname, dict_t *dict, char *default_sl, int count, int op_ret, int op_errno, char *op_errstr) { - if (!connected) + if (!cli_cmd_connected()) goto out; if (count > 0) { @@ -4875,14 +4872,6 @@ gf_cli_gsync_status_output(dict_t *dict, gf_boolean_t is_detail) ret = -1; goto out; } - for (i = 0; i < gsync_count; i++) { - sts_vals[i] = GF_CALLOC(1, sizeof(gf_gsync_status_t), - gf_common_mt_char); - if (!sts_vals[i]) { - ret = -1; - goto out; - } - } ret = gf_cli_read_status_data(dict, sts_vals, spacing, gsync_count, num_of_fields); @@ -5352,7 +5341,8 @@ cmd_profile_volume_brick_out(dict_t *dict, int count, int interval) double total_percentage_latency = 0; for (i = 0; i < 32; i++) { - snprintf(key, sizeof(key), "%d-%d-read-%d", count, interval, (1 << i)); + snprintf(key, sizeof(key), "%d-%d-read-%" PRIu32, count, interval, + (1U << i)); ret = dict_get_uint64(dict, key, &rb_counts[i]); if (ret) { gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key); @@ -5360,7 +5350,8 @@ cmd_profile_volume_brick_out(dict_t *dict, int count, int interval) } for (i = 0; i < 32; i++) { - snprintf(key, sizeof(key), "%d-%d-write-%d", count, interval, (1 << i)); + snprintf(key, sizeof(key), "%d-%d-write-%" PRIu32, count, interval, + (1U << i)); ret = dict_get_uint64(dict, key, &wb_counts[i]); if (ret) { gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key); @@ -5446,7 +5437,8 @@ cmd_profile_volume_brick_out(dict_t *dict, int count, int interval) if ((rb_counts[i] == 0) && (wb_counts[i] == 0)) continue; per_line++; - snprintf(output + index, sizeof(output) - index, "%19db+ ", (1 << i)); + snprintf(output + index, sizeof(output) - index, "%19" PRIu32 "b+ ", + (1U << i)); if (rb_counts[i]) { snprintf(read_blocks + index, sizeof(read_blocks) - index, "%21" PRId64 " ", rb_counts[i]); @@ -5733,7 +5725,7 @@ gf_cli_top_volume_cbk(struct rpc_req *req, struct iovec *iov, int count, double time = 0; int32_t time_sec = 0; long int time_usec = 0; - char timestr[256] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; char *openfd_str = NULL; @@ -7823,7 +7815,7 @@ cmd_heal_volume_brick_out(dict_t *dict, int brick) char *status = NULL; uint64_t i = 0; uint32_t time = 0; - char timestr[32] = {0}; + char timestr[GF_TIMESTR_SIZE] = {0}; char *shd_status = NULL; snprintf(key, sizeof key, "%d-hostname", brick); @@ -7926,8 +7918,6 @@ gf_is_cli_heal_get_command(gf_xl_afr_op_t heal_op) [GF_SHD_OP_HEAL_INDEX] = 0, [GF_SHD_OP_HEAL_FULL] = 0, [GF_SHD_OP_INDEX_SUMMARY] = 1, - [GF_SHD_OP_HEALED_FILES] = 1, - [GF_SHD_OP_HEAL_FAILED_FILES] = 1, [GF_SHD_OP_SPLIT_BRAIN_FILES] = 1, [GF_SHD_OP_STATISTICS] = 1, [GF_SHD_OP_STATISTICS_HEAL_COUNT] = 1, @@ -8014,12 +8004,6 @@ gf_cli_heal_volume_cbk(struct rpc_req *req, struct iovec *iov, int count, case GF_SHD_OP_INDEX_SUMMARY: heal_op_str = "list of entries to be healed"; break; - case GF_SHD_OP_HEALED_FILES: - heal_op_str = "list of healed entries"; - break; - case GF_SHD_OP_HEAL_FAILED_FILES: - heal_op_str = "list of heal failed entries"; - break; case GF_SHD_OP_SPLIT_BRAIN_FILES: heal_op_str = "list of split brain entries"; break; @@ -8032,12 +8016,14 @@ gf_cli_heal_volume_cbk(struct rpc_req *req, struct iovec *iov, int count, case GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA: heal_op_str = "count of entries to be healed per replica"; break; - /* The below 4 cases are never hit; they're coded only to make - * compiler warnings go away.*/ case GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE: case GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME: case GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK: case GF_SHD_OP_HEAL_SUMMARY: + case GF_SHD_OP_HEALED_FILES: + case GF_SHD_OP_HEAL_FAILED_FILES: + /* These cases are never hit; they're coded just to silence the + * compiler warnings.*/ break; case GF_SHD_OP_INVALID: @@ -8112,8 +8098,6 @@ gf_cli_heal_volume_cbk(struct rpc_req *req, struct iovec *iov, int count, cmd_heal_volume_statistics_heal_count_out(dict, i); break; case GF_SHD_OP_INDEX_SUMMARY: - case GF_SHD_OP_HEALED_FILES: - case GF_SHD_OP_HEAL_FAILED_FILES: case GF_SHD_OP_SPLIT_BRAIN_FILES: for (i = 0; i < brick_count; i++) cmd_heal_volume_brick_out(dict, i); diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 5f33aa9e0a3..069de75801c 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -1661,15 +1661,15 @@ cli_xml_output_vol_top_rw_perf(xmlTextWriterPtr writer, dict_t *dict, int ret = -1; char *filename = NULL; uint64_t throughput = 0; - long int time_sec = 0; - long int time_usec = 0; - char timestr[256] = { + struct timeval tv = { + 0, + }; + char timestr[GF_TIMESTR_SIZE] = { 0, }; char key[1024] = { 0, }; - int len; /* <file> */ ret = xmlTextWriterStartElement(writer, (xmlChar *)"file"); @@ -1692,19 +1692,16 @@ cli_xml_output_vol_top_rw_perf(xmlTextWriterPtr writer, dict_t *dict, XML_RET_CHECK_AND_GOTO(ret, out); snprintf(key, sizeof(key), "%d-time-sec-%d", brick_index, member_index); - ret = dict_get_int32(dict, key, (int32_t *)&time_sec); + ret = dict_get_int32(dict, key, (int32_t *)&tv.tv_sec); if (ret) goto out; snprintf(key, sizeof(key), "%d-time-usec-%d", brick_index, member_index); - ret = dict_get_int32(dict, key, (int32_t *)&time_usec); + ret = dict_get_int32(dict, key, (int32_t *)&tv.tv_usec); if (ret) goto out; - gf_time_fmt(timestr, sizeof timestr, time_sec, gf_timefmt_FT); - len = strlen(timestr); - snprintf(timestr + len, sizeof(timestr) - len, ".%" GF_PRI_SUSECONDS, - time_usec); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"time", "%s", timestr); XML_RET_CHECK_AND_GOTO(ret, out); @@ -1953,11 +1950,11 @@ cli_xml_output_vol_profile_stats(xmlTextWriterPtr writer, dict_t *dict, XML_RET_CHECK_AND_GOTO(ret, out); ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"size", - "%" PRIu32, (1 << i)); + "%" PRIu32, (1U << i)); XML_RET_CHECK_AND_GOTO(ret, out); - snprintf(key, sizeof(key), "%d-%d-read-%d", brick_index, interval, - (1 << i)); + snprintf(key, sizeof(key), "%d-%d-read-%" PRIu32, brick_index, interval, + (1U << i)); ret = dict_get_uint64(dict, key, &read_count); if (ret) read_count = 0; @@ -1965,8 +1962,8 @@ cli_xml_output_vol_profile_stats(xmlTextWriterPtr writer, dict_t *dict, "%" PRIu64, read_count); XML_RET_CHECK_AND_GOTO(ret, out); - snprintf(key, sizeof(key), "%d-%d-write-%d", brick_index, interval, - (1 << i)); + snprintf(key, sizeof(key), "%d-%d-write-%" PRIu32, brick_index, + interval, (1U << i)); ret = dict_get_uint64(dict, key, &write_count); if (ret) write_count = 0; diff --git a/cli/src/cli.c b/cli/src/cli.c index 2c96b7ae6e6..a52b39c5fb8 100644 --- a/cli/src/cli.c +++ b/cli/src/cli.c @@ -33,12 +33,6 @@ #include <malloc.h> #endif -#ifdef HAVE_MALLOC_STATS -#ifdef DEBUG -#include <mcheck.h> -#endif -#endif - #include "cli.h" #include "cli-quotad-client.h" #include "cli-cmd.h" @@ -61,7 +55,6 @@ #include "xdr-generic.h" -extern int connected; /* using argp for command line parsing */ const char *argp_program_version = @@ -78,6 +71,7 @@ const char *argp_program_version = const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">"; struct rpc_clnt *global_quotad_rpc; + struct rpc_clnt *global_rpc; rpc_clnt_prog_t *cli_rpc_prog; @@ -309,14 +303,14 @@ cli_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, switch (event) { case RPC_CLNT_CONNECT: { - cli_cmd_broadcast_connected(); + cli_cmd_broadcast_connected(_gf_true); gf_log(this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT"); break; } case RPC_CLNT_DISCONNECT: { + cli_cmd_broadcast_connected(_gf_false); 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( diff --git a/cli/src/cli.h b/cli/src/cli.h index cd4db3dac2c..c0d933e8f8a 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -189,6 +189,12 @@ typedef ssize_t (*cli_serialize_t)(struct iovec outmsg, void *args); extern struct cli_state *global_state; /* use only in readline callback */ +extern struct rpc_clnt *global_quotad_rpc; + +extern struct rpc_clnt *global_rpc; + +extern rpc_clnt_prog_t *cli_rpc_prog; + typedef const char *(*cli_selector_t)(void *wcon); char * @@ -329,11 +335,14 @@ cli_local_get(); void cli_local_wipe(cli_local_t *local); +gf_boolean_t +cli_cmd_connected(); + int32_t -cli_cmd_await_connected(); +cli_cmd_await_connected(unsigned timeout); int32_t -cli_cmd_broadcast_connected(); +cli_cmd_broadcast_connected(gf_boolean_t status); int cli_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, diff --git a/configure.ac b/configure.ac index d9af961edf1..e2d6fd66cec 100644 --- a/configure.ac +++ b/configure.ac @@ -164,6 +164,8 @@ AC_CONFIG_FILES([Makefile xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/Makefile xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/Makefile xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/Makefile + xlators/features/metadisp/Makefile + xlators/features/metadisp/src/Makefile xlators/playground/Makefile xlators/playground/template/Makefile xlators/playground/template/src/Makefile @@ -273,36 +275,78 @@ AC_ARG_ENABLE([debug], [Enable debug build options.])) if test "x$enable_debug" = "xyes"; then BUILD_DEBUG=yes - GF_CFLAGS="${GF_CFLAGS} -g -rdynamic -O0 -DDEBUG" + GF_CFLAGS="${GF_CFLAGS} -g -O0 -DDEBUG" else BUILD_DEBUG=no fi +SANITIZER=none + AC_ARG_ENABLE([asan], AC_HELP_STRING([--enable-asan], [Enable Address Sanitizer support])) if test "x$enable_asan" = "xyes"; then - BUILD_ASAN=yes - AC_CHECK_LIB([asan], [__asan_report_error], , - [AC_MSG_ERROR([libasan.so not found, this is required for --enable-asan])]) - GF_CFLAGS="${GF_CFLAGS} -O1 -g -fsanitize=address -fno-omit-frame-pointer" - dnl -lasan always need to be the first library, otherwise libxml complains - GF_LDFLAGS="-lasan ${GF_LDFLAGS}" -else - BUILD_ASAN=no + SANITIZER=asan + AC_CHECK_LIB([asan], [__asan_init], , + [AC_MSG_ERROR([--enable-asan requires libasan.so, exiting])]) + GF_CFLAGS="${GF_CFLAGS} -O2 -g -fsanitize=address -fno-omit-frame-pointer" + GF_LDFLAGS="${GF_LDFLAGS} -lasan" fi -AC_ARG_ENABLE([atan], +AC_ARG_ENABLE([tsan], AC_HELP_STRING([--enable-tsan], - [Enable ThreadSanitizer support])) + [Enable Thread Sanitizer support])) if test "x$enable_tsan" = "xyes"; then - BUILD_TSAN=yes + if test "x$SANITIZER" != "xnone"; then + AC_MSG_ERROR([only one sanitizer can be enabled at once]) + fi + SANITIZER=tsan AC_CHECK_LIB([tsan], [__tsan_init], , - [AC_MSG_ERROR([libtsan.so not found, this is required for --enable-tsan])]) - GF_CFLAGS="${GF_CFLAGS} -O2 -g -fsanitize=thread" + [AC_MSG_ERROR([--enable-tsan requires libtsan.so, exiting])]) + if test "x$ac_cv_lib_tsan___tsan_init" = xyes; then + AC_MSG_CHECKING([whether tsan API can be used]) + saved_CFLAGS=${CFLAGS} + CFLAGS="${CFLAGS} -fsanitize=thread" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([ + [#include <sanitizer/tsan_interface.h>]], + [[__tsan_create_fiber(0)]])], + [TSAN_API=yes], [TSAN_API=no]) + AC_MSG_RESULT([$TSAN_API]) + if test x$TSAN_API = "xyes"; then + AC_DEFINE(HAVE_TSAN_API, 1, [Define if tsan API can be used.]) + fi + CFLAGS=${saved_CFLAGS} + fi + GF_CFLAGS="${GF_CFLAGS} -O2 -g -fsanitize=thread -fno-omit-frame-pointer" GF_LDFLAGS="${GF_LDFLAGS} -ltsan" -else - BUILD_TSAN=no +fi + +AC_ARG_ENABLE([ubsan], + AC_HELP_STRING([--enable-ubsan], + [Enable Undefined Behavior Sanitizer support])) +if test "x$enable_ubsan" = "xyes"; then + if test "x$SANITIZER" != "xnone"; then + AC_MSG_ERROR([only one sanitizer can be enabled at once]) + fi + SANITIZER=ubsan + AC_CHECK_LIB([ubsan], [__ubsan_default_options], , + [AC_MSG_ERROR([--enable-ubsan requires libubsan.so, exiting])]) + GF_CFLAGS="${GF_CFLAGS} -O2 -g -fsanitize=undefined -fno-omit-frame-pointer" + GF_LDFLAGS="${GF_LDFLAGS} -lubsan" +fi + +# Initialize CFLAGS before usage +BUILD_TCMALLOC=no +AC_ARG_ENABLE([tcmalloc], + AC_HELP_STRING([--enable-tcmalloc], + [Enable linking with tcmalloc library.])) +if test "x$enable_tcmalloc" = "xyes"; then + BUILD_TCMALLOC=yes + GF_CFLAGS="${GF_CFLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" + AC_CHECK_LIB([tcmalloc], [malloc], [], + [AC_MSG_ERROR([when --enable-tcmalloc is used, tcmalloc library needs to be present])]) + GF_LDFLAGS="-ltcmalloc ${GF_LDFLAGS}" fi @@ -365,12 +409,27 @@ esac # --enable-valgrind prevents calling dlclose(), this leaks memory AC_ARG_ENABLE([valgrind], - AC_HELP_STRING([--enable-valgrind], - [Enable valgrind for resource leak debugging.])) -if test "x$enable_valgrind" = "xyes"; then - AC_DEFINE(RUN_WITH_VALGRIND, 1, [define if all processes should run under valgrind]) -fi - + AC_HELP_STRING([--enable-valgrind@<:@=memcheck,drd@:>@], + [Enable valgrind for resource leak (memcheck, which is + the default) or thread synchronization (drd) debugging.])) +case x$enable_valgrind in + xmemcheck|xyes) + AC_DEFINE(RUN_WITH_MEMCHECK, 1, + [Define if all processes should run under 'valgrind --tool=memcheck'.]) + VALGRIND_TOOL=memcheck + ;; + xdrd) + AC_DEFINE(RUN_WITH_DRD, 1, + [Define if all processes should run under 'valgrind --tool=drd'.]) + VALGRIND_TOOL=drd + ;; + x|xno) + VALGRIND_TOOL=no + ;; + *) + AC_MSG_ERROR([Please specify --enable-valgrind@<:@=memcheck,drd@:>@]) + ;; +esac AC_ARG_WITH([previous-options], [AS_HELP_STRING([--with-previous-options], @@ -671,6 +730,14 @@ if test "x$enable_fuse_client" != "xno"; then fi AC_SUBST(FUSE_CLIENT_SUBDIR) + +AC_ARG_ENABLE([fuse-notifications], + AS_HELP_STRING([--disable-fuse-notifications], [Disable FUSE notifications])) + +AS_IF([test "x$enable_fuse_notifications" != "xno"], [ + AC_DEFINE([HAVE_FUSE_NOTIFICATIONS], [1], [Use FUSE notifications]) +]) + # end FUSE section @@ -718,6 +785,9 @@ AC_ARG_ENABLE([georeplication], BUILD_SYNCDAEMON=no case $host_os in + freebsd*) +#do nothing + ;; linux*) #do nothing ;; @@ -757,6 +827,17 @@ fi AC_SUBST(GEOREP_EXTRAS_SUBDIR) AM_CONDITIONAL(USE_GEOREP, test "x$enable_georeplication" != "xno") +# METADISP section +AC_ARG_ENABLE([metadisp], + AC_HELP_STRING([--enable-metadisp], + [Enable the metadata dispersal xlator])) +BUILD_METADISP=no +if test "x${enable_metadisp}" = "xyes"; then + BUILD_METADISP=yes +fi +AM_CONDITIONAL([BUILD_METADISP], [test "x$BUILD_METADISP" = "xyes"]) +# end METADISP section + # Events section AC_ARG_ENABLE([events], AC_HELP_STRING([--disable-events], @@ -895,6 +976,25 @@ if test "x${have_backtrace}" = "xyes"; then fi AC_SUBST(HAVE_BACKTRACE) +dnl Old (before C11) compiler can compile (but not link) this: +dnl +dnl int main () { +dnl _Static_assert(1, "True"); +dnl return 0; +dnl } +dnl +dnl assuming that _Static_assert is an implicitly declared function. So +dnl we're trying to link just to make sure that this is not the case. + +AC_MSG_CHECKING([whether $CC supports C11 _Static_assert]) +AC_TRY_LINK([], [_Static_assert(1, "True");], + [STATIC_ASSERT=yes], [STATIC_ASSERT=no]) + +AC_MSG_RESULT([$STATIC_ASSERT]) +if test x$STATIC_ASSERT = "xyes"; then + AC_DEFINE(HAVE_STATIC_ASSERT, 1, [Define if C11 _Static_assert is supported.]) +fi + if test "x${have_backtrace}" != "xyes"; then AC_TRY_COMPILE([#include <math.h>], [double x=0.0; x=ceil(0.0);], [], @@ -902,11 +1002,11 @@ AC_TRY_COMPILE([#include <math.h>], [double x=0.0; x=ceil(0.0);], fi 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]) +AC_CHECK_FUNC([mallinfo], [have_mallinfo=yes]) +if test "x${have_mallinfo}" = "xyes"; then + AC_DEFINE(HAVE_MALLINFO, 1, [define if found mallinfo]) fi -AC_SUBST(HAVE_MALLOC_STATS) +AC_SUBST(HAVE_MALLINFO) dnl Linux, Solaris, Cygwin AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec]) @@ -933,6 +1033,9 @@ case $host_os in CFLAGS="${CFLAGS} -isystem /usr/local/include" ARGP_LDADD=-largp ;; + *netbsd*) + ARGP_LDADD=-largp + ;; esac dnl argp-standalone does not provide a pkg-config file AC_CHECK_HEADER([argp.h], AC_DEFINE(HAVE_ARGP, 1, [have argp])) @@ -1002,6 +1105,19 @@ else CFLAGS=${OLD_CFLAGS} fi +AC_CHECK_FUNC([syncfs], [have_syncfs=yes]) +if test "x${have_syncfs}" = "xyes"; then + AC_DEFINE(HAVE_SYNCFS, 1, [define if syncfs exists]) +else + OLD_CFLAGS=${CFLAGS} + CFLAGS="-D_GNU_SOURCE" + AC_CHECK_DECL([SYS_syncfs], , , [#include <sys/syscall.h>]) + if test "x${ac_cv_have_decl_SYS_syncfs}" = "xyes"; then + AC_DEFINE(HAVE_SYNCFS_SYS, 1, [define if SYS_syncfs is available]) + fi + CFLAGS=${OLD_CFLAGS} +fi + BUILD_NANOSECOND_TIMESTAMPS=no AC_CHECK_FUNC([utimensat], [have_utimensat=yes]) if test "x${have_utimensat}" = "xyes"; then @@ -1194,10 +1310,6 @@ case $host_os in ;; *freebsd*) GF_HOST_OS="GF_BSD_HOST_OS" - GF_CFLAGS="${GF_CFLAGS} -O0" - GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_BASENAME" - GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_DIRNAME" - GF_CFLAGS="${GF_CFLAGS} -D_LIBGEN_H_" GF_CFLAGS="${GF_CFLAGS} -DO_DSYNC=0" GF_CFLAGS="${GF_CFLAGS} -Dxdr_quad_t=xdr_longlong_t" GF_CFLAGS="${GF_CFLAGS} -Dxdr_u_quad_t=xdr_u_longlong_t" @@ -1478,9 +1590,9 @@ case $host_os in ;; esac dnl GF_XLATOR_DEFAULT_LDFLAGS is for most xlators that expose a common set of symbols -GF_XLATOR_DEFAULT_LDFLAGS='-avoid-version -export-symbols $(top_srcdir)/xlators/xlator.sym $(UUID_LIBS) $(GF_NO_UNDEFINED)' +GF_XLATOR_DEFAULT_LDFLAGS='-avoid-version -export-symbols $(top_srcdir)/xlators/xlator.sym $(UUID_LIBS) $(GF_NO_UNDEFINED) $(TIRPC_LIBS)' dnl GF_XLATOR_LDFLAGS is for xlators that expose extra symbols, e.g. dht -GF_XLATOR_LDFLAGS='-avoid-version $(UUID_LIBS) $(GF_NO_UNDEFINED)' +GF_XLATOR_LDFLAGS='-avoid-version $(UUID_LIBS) $(GF_NO_UNDEFINED) $(TIRPC_LIBS)' AC_SUBST(GF_HOST_OS) AC_SUBST(GF_CFLAGS) @@ -1495,6 +1607,13 @@ AC_SUBST(AM_LIBTOOLFLAGS) AC_SUBST(GF_NO_UNDEFINED) AC_SUBST(GF_XLATOR_DEFAULT_LDFLAGS) AC_SUBST(GF_XLATOR_LDFLAGS) +AC_SUBST(GF_XLATOR_MGNT_LIBADD) + +case $host_os in + *freebsd*) + GF_XLATOR_MGNT_LIBADD="-lutil -lprocstat" + ;; +esac CONTRIBDIR='$(top_srcdir)/contrib' AC_SUBST(CONTRIBDIR) @@ -1566,8 +1685,8 @@ echo "readline : $BUILD_READLINE" echo "georeplication : $BUILD_SYNCDAEMON" echo "Linux-AIO : $BUILD_LIBAIO" echo "Enable Debug : $BUILD_DEBUG" -echo "Enable ASAN : $BUILD_ASAN" -echo "Enable TSAN : $BUILD_TSAN" +echo "Run with Valgrind : $VALGRIND_TOOL" +echo "Sanitizer enabled : $SANITIZER" echo "Use syslog : $USE_SYSLOG" echo "XML output : $BUILD_XML_OUTPUT" echo "Unit Tests : $BUILD_UNITTEST" @@ -1585,16 +1704,14 @@ echo "IPV6 default : $with_ipv6_default" echo "Use TIRPC : $with_libtirpc" echo "With Python : ${PYTHON_VERSION}" echo "Cloudsync : $BUILD_CLOUDSYNC" +echo "Metadata dispersal : $BUILD_METADISP" +echo "Link with TCMALLOC : $BUILD_TCMALLOC" echo -if test "x$BUILD_ASAN" = "xyes"; then - echo "### Run below command before executing your tests if your system" - echo "### has 'gcc --version' above 7.x (works on Fedora 27 and Above)" - echo "export ASAN_OPTIONS=log_path=/var/log/glusterfs/asan-output.log" - echo "" - echo "### Above is required to get details of asan run, as glusterfs" - echo "### processes are daemon processes. Further details and more" - echo "### options can be found under 'Run-time flags' at" - echo "### https://github.com/google/sanitizers/wiki/AddressSanitizerFlags" - echo +# dnl Note: ${X^^} capitalization assumes bash >= 4.x +if test "x$SANITIZER" != "xnone"; then + echo "Note: since glusterfs processes are daemon processes, use" + echo "'export ${SANITIZER^^}_OPTIONS=log_path=/path/to/xxx.log' to collect" + echo "sanitizer output. Further details and more options can be" + echo "found at https://github.com/google/sanitizers." fi diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c index ffa0a4b6316..06ff191f542 100644 --- a/contrib/fuse-lib/mount.c +++ b/contrib/fuse-lib/mount.c @@ -52,12 +52,16 @@ gf_fuse_unmount (const char *mountpoint, int fd) if (geteuid () == 0) { fuse_mnt_umount ("fuse", mountpoint, mountpoint, 1); return; + } else { + GFFUSE_LOGERR ("fuse: Effective-uid: %d", geteuid()); } res = umount2 (mountpoint, 2); if (res == 0) return; + GFFUSE_LOGERR ("fuse: failed to unmount %s: %s", + mountpoint, strerror (errno)); pid = fork (); if (pid == -1) return; @@ -67,6 +71,8 @@ gf_fuse_unmount (const char *mountpoint, int fd) "--", mountpoint, NULL }; execvp (FUSERMOUNT_PROG, (char **)argv); + GFFUSE_LOGERR ("fuse: failed to execute fuserumount: %s", + strerror (errno)); _exit (1); } waitpid (pid, NULL, 0); @@ -384,6 +390,7 @@ fuse_mount_sys (const char *mountpoint, char *fsname, build_iovec (&iov, &iovlen, "from", "/dev/fuse", -1); build_iovec (&iov, &iovlen, "volname", source, -1); build_iovec (&iov, &iovlen, "fd", fdstr, -1); + build_iovec (&iov, &iovlen, "allow_other", NULL, -1); ret = nmount (iov, iovlen, mountflags); #else ret = mount (source, mountpoint, fstype, mountflags, diff --git a/contrib/sunrpc/xdr_sizeof.c b/contrib/sunrpc/xdr_sizeof.c deleted file mode 100644 index ca1f7bf0a5e..00000000000 --- a/contrib/sunrpc/xdr_sizeof.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.1 (the "License"). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -/* - * xdr_sizeof.c - * - * Copyright 1990 Sun Microsystems, Inc. - * - * General purpose routine to see how much space something will use - * when serialized using XDR. - */ - -#ifdef GF_DARWIN_HOST_OS - -#include <rpc/types.h> -#include <rpc/xdr.h> -#include <sys/types.h> -#include <sys/cdefs.h> - -#include <stdlib.h> - -/* ARGSUSED */ -#ifdef GF_DARWIN_HOST_OS -static bool_t -x_putlong (XDR *xdrs, const int *longp) -{ - xdrs->x_handy += BYTES_PER_XDR_UNIT; - return TRUE; -} - -#else -static bool_t -x_putlong (XDR *xdrs, const long *longp) -{ - xdrs->x_handy += BYTES_PER_XDR_UNIT; - return TRUE; -} -#endif - -/* ARGSUSED */ -static bool_t -x_putbytes (XDR *xdrs, const char *bp, u_int len) -{ - xdrs->x_handy += len; - return TRUE; -} - -#ifdef GF_DARWIN_HOST_OS -static u_int -x_getpostn (XDR *xdrs) -{ - return xdrs->x_handy; -} -#else -static u_int -x_getpostn (const XDR *xdrs) -{ - return xdrs->x_handy; -} -#endif - -/* ARGSUSED */ -static bool_t -x_setpostn (XDR *xdrs, u_int len) -{ - /* This is not allowed */ - return FALSE; -} - -static int32_t * -x_inline (XDR *xdrs, u_int len) -{ - if (len == 0) - return NULL; - if (xdrs->x_op != XDR_ENCODE) - return NULL; - if (len < (u_int) (long int) xdrs->x_base) - { - /* x_private was already allocated */ - xdrs->x_handy += len; - return (int32_t *) xdrs->x_private; - } - else - { - /* Free the earlier space and allocate new area */ - free (xdrs->x_private); - if ((xdrs->x_private = (caddr_t) malloc (len)) == NULL) - { - xdrs->x_base = 0; - return NULL; - } - xdrs->x_base = (void *) (long) len; - xdrs->x_handy += len; - return (int32_t *) xdrs->x_private; - } -} - -static int -harmless (void) -{ - /* Always return FALSE/NULL, as the case may be */ - return 0; -} - -static void -x_destroy (XDR *xdrs) -{ - xdrs->x_handy = 0; - xdrs->x_base = 0; - if (xdrs->x_private) - { - free (xdrs->x_private); - xdrs->x_private = NULL; - } - return; -} - -unsigned long -xdr_sizeof (xdrproc_t func, void *data) -{ - XDR x; - struct xdr_ops ops; - bool_t stat; - -#ifdef GF_DARWIN_HOST_OS - typedef bool_t (*dummyfunc1) (XDR *, int *); -#else - typedef bool_t (*dummyfunc1) (XDR *, long *); -#endif - typedef bool_t (*dummyfunc2) (XDR *, caddr_t, u_int); - - ops.x_putlong = x_putlong; - ops.x_putbytes = x_putbytes; - ops.x_inline = x_inline; - ops.x_getpostn = x_getpostn; - ops.x_setpostn = x_setpostn; - ops.x_destroy = x_destroy; - - /* the other harmless ones */ - ops.x_getlong = (dummyfunc1) harmless; - ops.x_getbytes = (dummyfunc2) harmless; - - x.x_op = XDR_ENCODE; - x.x_ops = &ops; - x.x_handy = 0; - x.x_private = (caddr_t) NULL; - x.x_base = (caddr_t) 0; - - stat = func (&x, data, 0); - if (x.x_private) - free (x.x_private); - return (stat == TRUE ? (unsigned) x.x_handy : 0); -} -#endif /* GF_DARWIN_HOST_OS */ diff --git a/doc/developer-guide/fuse-interrupt.md b/doc/developer-guide/fuse-interrupt.md index f92b5532eaf..ec991b81ec5 100644 --- a/doc/developer-guide/fuse-interrupt.md +++ b/doc/developer-guide/fuse-interrupt.md @@ -23,9 +23,10 @@ not exported to a header file). ``` enum fuse_interrupt_state { - INTERRUPT_NONE, + /* ... */ INTERRUPT_SQUELCHED, INTERRUPT_HANDLED, + /* ... */ }; typedef enum fuse_interrupt_state fuse_interrupt_state_t; struct fuse_interrupt_record; @@ -62,8 +63,58 @@ dummy implementation only for demonstration purposes.) Flush is chosen because a `FLUSH` interrupt is easy to trigger (see *tests/features/interrupt.t*). Interrupt handling for flush is switched on by `--fuse-flush-handle-interrupt` (a hidden glusterfs command line flag). -The flush interrupt handling code is guarded by the -`flush_handle_interrupt` Boolean member of `fuse_private_t`. +The implementation of flush interrupt is contained in the +`fuse_flush_interrupt_handler()` function and blocks guarded by the + +``` +if (priv->flush_handle_interrupt) { ... +``` + +conditional (where `priv` is a `*fuse_private_t`). + +### Overview + +"Regular" fuse fops and interrupt handlers interact via a list containing +interrupt records. + +If a fop wishes to have its interrupts handled, it needs to set up an +interrupt record and insert it into the list; also when it's to finish +(ie. in its "cbk" stage) it needs to delete the record from the list. + +If no interrupt happens, basically that's all to it - a list insertion +and deletion. + +However, if an interrupt comes for the fop, the interrupt FUSE request +will carry the data identifying an ongoing fop (that is, its `unique`), +and based on that, the interrupt record will be looked up in the list, and +the specific interrupt handler (a member of the interrupt record) will be +called. + +Usually the fop needs to share some data with the interrupt handler to +enable it to perform its task (also shared via the interrupt record). +The interrupt API offers two approaches to manage shared data: +- _Async or reference-counting strategy_: from the point on when the interrupt + record is inserted to the list, it's owned jointly by the regular fop and + the prospective interrupt handler. Both of them need to check before they + return if the other is still holding a reference; if not, then they are + responsible for reclaiming the shared data. +- _Sync or borrow strategy_: the interrupt handler is considered a borrower + of the shared data. The interrupt handler should not reclaim the shared + data. The fop will wait for the interrupt handler to finish (ie., the borrow + to be returned), then it has to reclaim the shared data. + +The user of the interrupt API need to call the following functions to +instrument this control flow: +- `fuse_interrupt_record_insert()` in the fop to insert the interrupt record to + the list; +- `fuse_interrupt_finish_fop()`in the fop (cbk) and +- `fuse_interrupt_finish_interrupt()`in the interrupt handler + +to perform needed synchronization at the end their tenure. The data management +strategies are implemented by the `fuse_interrupt_finish_*()` functions (which +have an argument to specify which strategy to use); these routines take care +of freeing the interrupt record itself, while the reclamation of the shared data +is left to the API user. ### Usage @@ -75,12 +126,15 @@ steps: call (directly or as async callback) `fuse_interrupt_finish_interrupt()`. The `intstat` argument to `fuse_interrupt_finish_interrupt` should be either `INTERRUPT_SQUELCHED` or `INTERRUPT_HANDLED`. - - `INTERRUPT_SQUELCHED` means that we choose not to handle the interrupt + - `INTERRUPT_SQUELCHED` means that the interrupt could not be delivered and the fop is going on uninterrupted. - `INTERRUPT_HANDLED` means that the interrupt was actually handled. In this case the fop will be answered from interrupt context with errno `EINTR` (that is, the fop should not send a response to the kernel). + (the enum `fuse_interrupt_state` includes further members, which are reserved + for internal use). + We return to the `sync` and `datap` arguments later. - In the `fuse_<FOP>` function create an interrupt record using `fuse_interrupt_record_new()`, passing the incoming `fuse_in_header` and @@ -92,10 +146,10 @@ steps: `fuse_interrupt_record_insert()`. - In `fuse_<FOP>_cbk` call `fuse_interrupt_finish_fop()`. - `fuse_interrupt_finish_fop()` returns a Boolean according to whether the - interrupt was handled. If it was, then the fuse request is already + interrupt was handled. If it was, then the FUSE request is already answered and the stack gets destroyed in `fuse_interrupt_finish_fop` so - `fuse_<FOP>_cbk` can just return (zero). Otherwise follow the standard - cbk logic (answer the fuse request and destroy the stack -- these are + `fuse_<FOP>_cbk()` can just return (zero). Otherwise follow the standard + cbk logic (answer the FUSE request and destroy the stack -- these are typically accomplished by `fuse_err_cbk()`). - The last two argument of `fuse_interrupt_finish_fop()` and `fuse_interrupt_finish_interrupt()` are `gf_boolean_t sync` and @@ -124,7 +178,34 @@ steps: then that pointer will be directed to the `data` member of the interrupt record and it's up to the caller what it's doing with it. - If `sync` is true, interrupt handler can use `datap = NULL`, and - fop handler will have `datap` set. + fop handler will have `datap` point to a valid pointer. - If `sync` is false, and handlers pass a pointer to a pointer for `datap`, they should check if the pointed pointer is NULL before attempting to deal with the data. + +### FUSE answer for the interrupted fop + +The kernel acknowledges a successful interruption for a given FUSE request +if the filesystem daemon answers it with errno EINTR; upon that, the syscall +which induced the request will be abruptly terminated with an interrupt, rather +than returning a value. + +In glusterfs, this can be arranged in two ways. + +- If the interrupt handler wins the race for the interrupt record, ie. + `fuse_interrupt_finish_fop()` returns true to `fuse_<FOP>_cbk()`, then, as + said above, `fuse_<FOP>_cbk()` does not need to answer the FUSE request. + That's because then the interrupt handler will take care about answering + it (with errno EINTR). +- If `fuse_interrupt_finish_fop()` returns false to `fuse_<FOP>_cbk()`, then + this return value does not inform the fop handler whether there was an interrupt + or not. This return value occurs both when fop handler won the race for the + interrupt record against the interrupt handler, and when there was no interrupt + at all. + + However, the internal logic of the fop handler might detect from other + circumstances that an interrupt was delivered. For example, the fop handler + might be sleeping, waiting for some data to arrive, so that a premature + wakeup (with no data present) occurs if the interrupt handler intervenes. In + such cases it's the responsibility of the fop handler to reply the FUSE + request with errro EINTR. diff --git a/doc/developer-guide/identifying-resource-leaks.md b/doc/developer-guide/identifying-resource-leaks.md index 851fc4424bc..950cae79b0a 100644 --- a/doc/developer-guide/identifying-resource-leaks.md +++ b/doc/developer-guide/identifying-resource-leaks.md @@ -174,3 +174,27 @@ In this case, the resource leak can be addressed by adding a single line to the Running the same Valgrind command and comparing the output will show that the memory leak in `xlators/meta/src/meta.c:init` is not reported anymore. + +### Running DRD, the Valgrind thread error detector + +When configuring GlusterFS with: + +```shell +./configure --enable-valgrind +``` + +the default Valgrind tool (Memcheck) is enabled. But it's also possble to select +one of Memcheck or DRD by using: + +```shell +./configure --enable-valgrind=memcheck +``` + +or: + +```shell +./configure --enable-valgrind=drd +``` + +respectively. When using DRD, it's recommended to consult +https://valgrind.org/docs/manual/drd-manual.html before running. diff --git a/doc/developer-guide/thread-naming.md b/doc/developer-guide/thread-naming.md index 74efba28e45..513140d4437 100644 --- a/doc/developer-guide/thread-naming.md +++ b/doc/developer-guide/thread-naming.md @@ -29,10 +29,10 @@ gf_thread_create_detached (pthread_t *thread, As max name length for a thread in POSIX is only 16 characters including the '\0' character, you have to be a little creative with naming. Also, it is important that all Gluster threads have common prefix. Considering these -conditions, we have "gluster" as prefix for all the threads created by these +conditions, we have "glfs_" as prefix for all the threads created by these wrapper functions. It is responsibility of the owner of thread to provide the suffix part of the name. It does not have to be a descriptive name, as it has -only 8 letters to work with. However, it should be unique enough such that it +only 10 letters to work with. However, it should be unique enough such that it can be matched with a table which describes it. If n number of threads are spwaned to perform same function, it is must that the @@ -87,6 +87,7 @@ such that it can be matched with a table below without ambiguity. - posixfsy - posix fsync - posixhc - posix heal - posixjan - posix janitor +- posixrsv - posix reserve - quiesce - quiesce dequeue - rdmaAsyn - rdma async event handler - rdmaehan - rdma completion handler diff --git a/doc/gluster.8 b/doc/gluster.8 index f9f7d400663..ba595edca15 100644 --- a/doc/gluster.8 +++ b/doc/gluster.8 @@ -41,7 +41,7 @@ List all volumes in cluster \fB\ volume status [all | <VOLNAME> [nfs|shd|<BRICK>|quotad]] [detail|clients|mem|inode|fd|callpool|tasks|client-list] \fR Display status of all or specified volume(s)/brick .TP -\fB\ volume create <NEW-VOLNAME> [stripe <COUNT>] [[replica <COUNT> [arbiter <COUNT>]]|[replica 2 thin-arbiter 1]] [disperse [<COUNT>]] [redundancy <COUNT>] [transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ... <TA-BRICK> \fR +\fB\ volume create <NEW-VOLNAME> [stripe <COUNT>] [[replica <COUNT> [arbiter <COUNT>]]|[replica 2 thin-arbiter 1]] [disperse [<COUNT>]] [disperse-data <COUNT>] [redundancy <COUNT>] [transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ... <TA-BRICK> \fR Create a new volume of the specified type using the specified bricks and transport type (the default transport type is tcp). To create a volume with both transports (tcp and rdma), give 'transport tcp,rdma' as an option. .TP @@ -218,6 +218,12 @@ Use "!<OPTION>" to reset option <OPTION> to default value. \fB\ volume bitrot <VOLNAME> {enable|disable} \fR Enable/disable bitrot for volume <VOLNAME> .TP +\fB\ volume bitrot <VOLNAME> signing-time <time-in-secs> \fR +Waiting time for an object after last fd is closed to start signing process. +.TP +\fB\ volume bitrot <VOLNAME> signer-threads <count> \fR +Number of signing process threads. Usually set to number of available cores. +.TP \fB\ volume bitrot <VOLNAME> scrub-throttle {lazy|normal|aggressive} \fR Scrub-throttle value is a measure of how fast or slow the scrubber scrubs the filesystem for volume <VOLNAME> .TP diff --git a/events/src/eventsapiconf.py.in b/events/src/eventsapiconf.py.in index 76b5954d325..700093bee60 100644 --- a/events/src/eventsapiconf.py.in +++ b/events/src/eventsapiconf.py.in @@ -28,6 +28,8 @@ def get_glusterd_workdir(): return glusterd_workdir SERVER_ADDRESS = "0.0.0.0" +SERVER_ADDRESSv4 = "0.0.0.0" +SERVER_ADDRESSv6 = "::1" DEFAULT_CONFIG_FILE = "@SYSCONF_DIR@/glusterfs/eventsconfig.json" CUSTOM_CONFIG_FILE_TO_SYNC = "/events/config.json" CUSTOM_CONFIG_FILE = get_glusterd_workdir() + CUSTOM_CONFIG_FILE_TO_SYNC diff --git a/events/src/glustereventsd.py b/events/src/glustereventsd.py index c4c7b65e332..341a3b60947 100644 --- a/events/src/glustereventsd.py +++ b/events/src/glustereventsd.py @@ -13,6 +13,7 @@ from __future__ import print_function import sys import signal +import threading try: import socketserver except ImportError: @@ -23,10 +24,17 @@ from argparse import ArgumentParser, RawDescriptionHelpFormatter from eventtypes import all_events import handlers import utils -from eventsapiconf import SERVER_ADDRESS, PID_FILE +from eventsapiconf import SERVER_ADDRESSv4, SERVER_ADDRESSv6, PID_FILE from eventsapiconf import AUTO_BOOL_ATTRIBUTES, AUTO_INT_ATTRIBUTES from utils import logger, PidFile, PidFileLockFailed, boolify +# Subclass so that specifically IPv4 packets are captured +class UDPServerv4(socketserver.ThreadingUDPServer): + address_family = socket.AF_INET + +# Subclass so that specifically IPv6 packets are captured +class UDPServerv6(socketserver.ThreadingUDPServer): + address_family = socket.AF_INET6 class GlusterEventsRequestHandler(socketserver.BaseRequestHandler): @@ -89,6 +97,10 @@ def signal_handler_sigusr2(sig, frame): utils.restart_webhook_pool() +def UDP_server_thread(sock): + sock.serve_forever() + + def init_event_server(): utils.setup_logger() utils.load_all() @@ -99,15 +111,26 @@ def init_event_server(): sys.stderr.write("Unable to get Port details from Config\n") sys.exit(1) - # Start the Eventing Server, UDP Server + # Creating the Eventing Server, UDP Server for IPv4 packets + try: + serverv4 = UDPServerv4((SERVER_ADDRESSv4, port), + GlusterEventsRequestHandler) + except socket.error as e: + sys.stderr.write("Failed to start Eventsd for IPv4: {0}\n".format(e)) + sys.exit(1) + # Creating the Eventing Server, UDP Server for IPv6 packets try: - server = socketserver.ThreadingUDPServer( - (SERVER_ADDRESS, port), - GlusterEventsRequestHandler) + serverv6 = UDPServerv6((SERVER_ADDRESSv6, port), + GlusterEventsRequestHandler) except socket.error as e: - sys.stderr.write("Failed to start Eventsd: {0}\n".format(e)) + sys.stderr.write("Failed to start Eventsd for IPv6: {0}\n".format(e)) sys.exit(1) - server.serve_forever() + server_thread1 = threading.Thread(target=UDP_server_thread, + args=(serverv4,)) + server_thread2 = threading.Thread(target=UDP_server_thread, + args=(serverv6,)) + server_thread1.start() + server_thread2.start() def get_args(): diff --git a/events/src/peer_eventsapi.py b/events/src/peer_eventsapi.py index 26b77a09179..4d2e5f35b1c 100644 --- a/events/src/peer_eventsapi.py +++ b/events/src/peer_eventsapi.py @@ -353,8 +353,7 @@ class WebhookModCmd(Cmd): errcode=ERROR_WEBHOOK_NOT_EXISTS, json_output=args.json) - if isinstance(data[args.url], str) or \ - isinstance(data[args.url], unicode): + if isinstance(data[args.url], str): data[args.url]["token"] = data[args.url] if args.bearer_token != "": diff --git a/events/src/utils.py b/events/src/utils.py index 38b707a1b28..6d4e0791a2b 100644 --- a/events/src/utils.py +++ b/events/src/utils.py @@ -13,6 +13,7 @@ import sys import json import os import logging +import logging.handlers import fcntl from errno import EBADF from threading import Thread @@ -98,7 +99,7 @@ def setup_logger(): logger.setLevel(logging.INFO) # create the logging file handler - fh = logging.FileHandler(LOG_FILE) + fh = logging.handlers.WatchedFileHandler(LOG_FILE) formatter = logging.Formatter("[%(asctime)s] %(levelname)s " "[%(module)s - %(lineno)s:%(funcName)s] " diff --git a/extras/distributed-testing/distributed-test-runner.py b/extras/distributed-testing/distributed-test-runner.py index 7bfb6c9652a..5a07e2feab1 100755 --- a/extras/distributed-testing/distributed-test-runner.py +++ b/extras/distributed-testing/distributed-test-runner.py @@ -383,14 +383,17 @@ class Handlers: return self.shell.call("make install") == 0 @synchronized - def prove(self, id, test, timeout, valgrind=False, asan_noleaks=True): + def prove(self, id, test, timeout, valgrind="no", asan_noleaks=True): assert id == self.client_id self.shell.cd(self.gluster_root) env = "DEBUG=1 " - if valgrind: + if valgrind == "memcheck" or valgrind == "yes": cmd = "valgrind" cmd += " --tool=memcheck --leak-check=full --track-origins=yes" cmd += " --show-leak-kinds=all -v prove -v" + elif valgrind == "drd": + cmd = "valgrind" + cmd += " --tool=drd -v prove -v" elif asan_noleaks: cmd = "prove -v" env += "ASAN_OPTIONS=detect_leaks=0 " @@ -827,8 +830,9 @@ parser.add_argument("--port", help="server port to listen", type=int, default=DEFAULT_PORT) # test role parser.add_argument("--tester", help="start tester", action="store_true") -parser.add_argument("--valgrind", help="run tests under valgrind", - action="store_true") +parser.add_argument("--valgrind[=memcheck,drd]", + help="run tests with valgrind tool 'memcheck' or 'drd'", + default="no") parser.add_argument("--asan", help="test with asan enabled", action="store_true") parser.add_argument("--asan-noleaks", help="test with asan but no mem leaks", diff --git a/extras/ganesha/ocf/ganesha_nfsd b/extras/ganesha/ocf/ganesha_nfsd index 93fc8be5136..f91e8b6b8f7 100644 --- a/extras/ganesha/ocf/ganesha_nfsd +++ b/extras/ganesha/ocf/ganesha_nfsd @@ -36,7 +36,7 @@ else . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs fi -OCF_RESKEY_ha_vol_mnt_default="/var/run/gluster/shared_storage" +OCF_RESKEY_ha_vol_mnt_default="/run/gluster/shared_storage" : ${OCF_RESKEY_ha_vol_mnt=${OCF_RESKEY_ha_vol_mnt_default}} ganesha_meta_data() { diff --git a/extras/ganesha/scripts/create-export-ganesha.sh b/extras/ganesha/scripts/create-export-ganesha.sh index 1ffba427457..3040e8138b0 100755 --- a/extras/ganesha/scripts/create-export-ganesha.sh +++ b/extras/ganesha/scripts/create-export-ganesha.sh @@ -64,6 +64,7 @@ echo " Pseudo=\"/$VOL\";" echo ' Protocols = "3", "4" ;' echo ' Transports = "UDP","TCP";' echo ' SecType = "sys";' +echo ' Security_Label = False;' echo " }" } if [ "$OPTION" = "on" ]; diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh index 32af1cab10e..9790a719e10 100644 --- a/extras/ganesha/scripts/ganesha-ha.sh +++ b/extras/ganesha/scripts/ganesha-ha.sh @@ -24,11 +24,16 @@ GANESHA_HA_SH=$(realpath $0) HA_NUM_SERVERS=0 HA_SERVERS="" HA_VOL_NAME="gluster_shared_storage" -HA_VOL_MNT="/var/run/gluster/shared_storage" +HA_VOL_MNT="/run/gluster/shared_storage" HA_CONFDIR=$HA_VOL_MNT"/nfs-ganesha" SERVICE_MAN="DISTRO_NOT_FOUND" -RHEL6_PCS_CNAME_OPTION="--name" +# rhel, fedora id, version +ID="" +VERSION_ID="" + +PCS9OR10_PCS_CNAME_OPTION="" +PCS9OR10_PCS_CLONE_OPTION="clone" SECRET_PEM="/var/lib/glusterd/nfs/secret.pem" # UNBLOCK RA uses shared_storage which may become unavailable @@ -101,9 +106,9 @@ determine_service_manager () { then SERVICE_MAN="/sbin/service" fi - if [ "${SERVICE_MAN}" == "DISTRO_NOT_FOUND" ] + if [[ "${SERVICE_MAN}X" == "DISTRO_NOT_FOUNDX" ]] then - echo "Service manager not recognized, exiting" + logger "Service manager not recognized, exiting" exit 1 fi } @@ -114,7 +119,7 @@ manage_service () local new_node=${2} local option= - if [ "${action}" == "start" ]; then + if [[ "${action}" == "start" ]]; then option="yes" else option="no" @@ -122,7 +127,7 @@ manage_service () ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ ${SECRET_PEM} root@${new_node} "${GANESHA_HA_SH} --setup-ganesha-conf-files $HA_CONFDIR $option" - if [ "${SERVICE_MAN}" == "/bin/systemctl" ] + if [[ "${SERVICE_MAN}" == "/bin/systemctl" ]] then ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ ${SECRET_PEM} root@${new_node} "${SERVICE_MAN} ${action} nfs-ganesha" @@ -140,7 +145,7 @@ check_cluster_exists() if [ -e /var/run/corosync.pid ]; then cluster_name=$(pcs status | grep "Cluster name:" | cut -d ' ' -f 3) - if [ ${cluster_name} -a ${cluster_name} = ${name} ]; then + if [[ "${cluster_name}X" == "${name}X" ]]; then logger "$name already exists, exiting" exit 0 fi @@ -155,7 +160,7 @@ determine_servers() local tmp_ifs=${IFS} local ha_servers="" - if [ "X${cmd}X" != "XsetupX" -a "X${cmd}X" != "XstatusX" ]; then + if [ "${cmd}X" != "setupX" -a "${cmd}X" != "statusX" ]; then ha_servers=$(pcs status | grep "Online:" | grep -o '\[.*\]' | sed -e 's/\[//' | sed -e 's/\]//') IFS=$' ' for server in ${ha_servers} ; do @@ -193,15 +198,21 @@ setup_cluster() logger "setting up cluster ${name} with the following ${servers}" - pcs cluster auth ${servers} - # pcs cluster setup --name ${name} ${servers} - pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} --enable --transport udpu ${servers} + # pcs cluster setup --force ${PCS9OR10_PCS_CNAME_OPTION} ${name} ${servers} + pcs cluster setup --force ${PCS9OR10_PCS_CNAME_OPTION} ${name} --enable ${servers} if [ $? -ne 0 ]; then - logger "pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} --enable --transport udpu ${servers} failed" + logger "pcs cluster setup ${PCS9OR10_PCS_CNAME_OPTION} ${name} --enable ${servers} failed, shutting down ganesha and bailing out" #set up failed stop all ganesha process and clean up symlinks in cluster stop_ganesha_all "${servers}" exit 1; fi + + # pcs cluster auth ${servers} + pcs cluster auth + if [ $? -ne 0 ]; then + logger "pcs cluster auth failed" + fi + pcs cluster start --all if [ $? -ne 0 ]; then logger "pcs cluster start failed" @@ -217,7 +228,7 @@ setup_cluster() done unclean=$(pcs status | grep -u "UNCLEAN") - while [[ "${unclean}X" = "UNCLEANX" ]]; do + while [[ "${unclean}X" == "UNCLEANX" ]]; do sleep 1 unclean=$(pcs status | grep -u "UNCLEAN") done @@ -244,7 +255,7 @@ setup_finalize_ha() local stopped="" stopped=$(pcs status | grep -u "Stopped") - while [[ "${stopped}X" = "StoppedX" ]]; do + while [[ "${stopped}X" == "StoppedX" ]]; do sleep 1 stopped=$(pcs status | grep -u "Stopped") done @@ -265,7 +276,7 @@ refresh_config () if [ -e ${SECRET_PEM} ]; then while [[ ${3} ]]; do current_host=`echo ${3} | cut -d "." -f 1` - if [ ${short_host} != ${current_host} ]; then + if [[ ${short_host} != ${current_host} ]]; then output=$(ssh -oPasswordAuthentication=no \ -oStrictHostKeyChecking=no -i ${SECRET_PEM} root@${current_host} \ "dbus-send --print-reply --system --dest=org.ganesha.nfsd \ @@ -398,7 +409,7 @@ wrap_create_virt_ip_constraints() # the result is "node2 node3 node4"; for node2, "node3 node4 node1" # and so on. while [[ ${1} ]]; do - if [ "${1}" = "${primary}" ]; then + if [[ ${1} == ${primary} ]]; then shift while [[ ${1} ]]; do tail=${tail}" "${1} @@ -429,15 +440,15 @@ setup_create_resources() local cibfile=$(mktemp -u) # fixup /var/lib/nfs - logger "pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} --clone" - pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} --clone + logger "pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} ${PCS9OR10_PCS_CLONE_OPTION}" + pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} ${PCS9OR10_PCS_CLONE_OPTION} if [ $? -ne 0 ]; then - logger "warning: pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} --clone failed" + logger "warning: pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} ${PCS9OR10_PCS_CLONE_OPTION} failed" fi - pcs resource create nfs-mon ocf:heartbeat:ganesha_mon --clone + pcs resource create nfs-mon ocf:heartbeat:ganesha_mon ${PCS9OR10_PCS_CLONE_OPTION} if [ $? -ne 0 ]; then - logger "warning: pcs resource create nfs-mon ocf:heartbeat:ganesha_mon --clone failed" + logger "warning: pcs resource create nfs-mon ocf:heartbeat:ganesha_mon ${PCS9OR10_PCS_CLONE_OPTION} failed" fi # see comment in (/usr/lib/ocf/resource.d/heartbeat/ganesha_grace @@ -445,9 +456,9 @@ setup_create_resources() # ganesha-active crm_attribute sleep 5 - pcs resource create nfs-grace ocf:heartbeat:ganesha_grace --clone notify=true + pcs resource create nfs-grace ocf:heartbeat:ganesha_grace ${PCS9OR10_PCS_CLONE_OPTION} notify=true if [ $? -ne 0 ]; then - logger "warning: pcs resource create nfs-grace ocf:heartbeat:ganesha_grace --clone failed" + logger "warning: pcs resource create nfs-grace ocf:heartbeat:ganesha_grace ${PCS9OR10_PCS_CLONE_OPTION} failed" fi pcs constraint location nfs-grace-clone rule score=-INFINITY grace-active ne 1 @@ -616,7 +627,7 @@ addnode_recreate_resources() --after ${add_node}-nfs_block if [ $? -ne 0 ]; then logger "warning pcs resource create ${add_node}-cluster_ip-1 ocf:heartbeat:IPaddr \ - ip=${add_vip} cidr_netmask=32 op monitor interval=15s failed" + ip=${add_vip} cidr_netmask=32 op monitor interval=15s failed" fi pcs -f ${cibfile} constraint order nfs-grace-clone then ${add_node}-cluster_ip-1 @@ -780,7 +791,7 @@ setup_state_volume() touch ${mnt}/nfs-ganesha/${dirname}/nfs/statd/state fi for server in ${HA_SERVERS} ; do - if [ ${server} != ${dirname} ]; then + if [[ ${server} != ${dirname} ]]; then ln -s ${mnt}/nfs-ganesha/${server}/nfs/ganesha ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/${server} ln -s ${mnt}/nfs-ganesha/${server}/nfs/statd ${mnt}/nfs-ganesha/${dirname}/nfs/statd/${server} fi @@ -794,7 +805,7 @@ setup_state_volume() enable_pacemaker() { while [[ ${1} ]]; do - if [ "${SERVICE_MAN}" == "/usr/bin/systemctl" ]; then + if [[ "${SERVICE_MAN}" == "/bin/systemctl" ]]; then ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ ${SECRET_PEM} root@${1} "${SERVICE_MAN} enable pacemaker" else @@ -892,7 +903,7 @@ delnode_state_volume() rm -rf ${mnt}/nfs-ganesha/${dirname} for server in ${HA_SERVERS} ; do - if [[ "${server}" != "${dirname}" ]]; then + if [[ ${server} != ${dirname} ]]; then rm -f ${mnt}/nfs-ganesha/${server}/nfs/ganesha/${dirname} rm -f ${mnt}/nfs-ganesha/${server}/nfs/statd/${dirname} fi @@ -908,8 +919,9 @@ status() local index=1 local nodes - # change tabs to spaces, strip leading spaces - pcs status | sed -e "s/\t/ /g" -e "s/^[ ]*//" > ${scratch} + # change tabs to spaces, strip leading spaces, including any + # new '*' at the beginning of a line introduced in pcs-0.10.x + pcs status | sed -e "s/\t/ /g" -e "s/^[ ]*\*//" -e "s/^[ ]*//" > ${scratch} nodes[0]=${1}; shift @@ -924,7 +936,7 @@ status() done # print the nodes that are expected to be online - grep -E "^Online:" ${scratch} + grep -E "Online:" ${scratch} echo @@ -963,7 +975,7 @@ status() create_ganesha_conf_file() { - if [ $1 == "yes" ]; + if [[ "$1" == "yes" ]]; then if [ -e $GANESHA_CONF ]; then @@ -1012,6 +1024,13 @@ main() semanage boolean -m gluster_use_execmem --on fi + local osid="" + + osid=$(grep ^ID= /etc/os-release) + eval $(echo ${osid} | grep -F ID=) + osid=$(grep ^VERSION_ID= /etc/os-release) + eval $(echo ${osid} | grep -F VERSION_ID=) + HA_CONFDIR=${1%/}; shift local ha_conf=${HA_CONFDIR}/ganesha-ha.conf local node="" @@ -1032,7 +1051,17 @@ main() determine_servers "setup" - if [ "X${HA_NUM_SERVERS}X" != "X1X" ]; then + # Fedora 29+ and rhel/centos 8 has PCS-0.10.x + # default is pcs-0.10.x options but check for + # rhel/centos 7 (pcs-0.9.x) and adjust accordingly + if [[ ! ${ID} =~ {rhel,centos} ]]; then + if [[ ${VERSION_ID} == 7.* ]]; then + PCS9OR10_PCS_CNAME_OPTION="--name" + PCS9OR10_PCS_CLONE_OPTION="--clone" + fi + fi + + if [[ "${HA_NUM_SERVERS}X" != "1X" ]]; then determine_service_manager diff --git a/extras/glusterfs-georep-upgrade.py b/extras/glusterfs-georep-upgrade.py new file mode 100755 index 00000000000..634576058d6 --- /dev/null +++ b/extras/glusterfs-georep-upgrade.py @@ -0,0 +1,77 @@ +#!/usr/bin/python3 +""" + +Copyright (c) 2020 Red Hat, Inc. <http://www.redhat.com> +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. + +""" + +import argparse +import errno +import os, sys +import shutil +from datetime import datetime + +def find_htime_path(brick_path): + dirs = [] + htime_dir = os.path.join(brick_path, '.glusterfs/changelogs/htime') + for file in os.listdir(htime_dir): + if os.path.isfile(os.path.join(htime_dir,file)) and file.startswith("HTIME"): + dirs.append(os.path.join(htime_dir, file)) + else: + raise FileNotFoundError("%s unavailable" % (os.path.join(htime_dir, file))) + return dirs + +def modify_htime_file(brick_path): + htime_file_path_list = find_htime_path(brick_path) + + for htime_file_path in htime_file_path_list: + changelog_path = os.path.join(brick_path, '.glusterfs/changelogs') + temp_htime_path = os.path.join(changelog_path, 'htime/temp_htime_file') + with open(htime_file_path, 'r') as htime_file, open(temp_htime_path, 'w') as temp_htime_file: + #extract epoch times from htime file + paths = htime_file.read().split("\x00") + + for pth in paths: + epoch_no = pth.split(".")[-1] + changelog = os.path.basename(pth) + #convert epoch time to year, month and day + if epoch_no != '': + date=(datetime.fromtimestamp(float(int(epoch_no))).strftime("%Y/%m/%d")) + #update paths in temp htime file + temp_htime_file.write("%s/%s/%s\x00" % (changelog_path, date, changelog)) + #create directory in the format year/month/days + path = os.path.join(changelog_path, date) + + if changelog.startswith("CHANGELOG."): + try: + os.makedirs(path, mode = 0o600); + except OSError as exc: + if exc.errno == errno.EEXIST: + pass + else: + raise + + #copy existing changelogs to new directory structure, delete old changelog files + shutil.copyfile(pth, os.path.join(path, changelog)) + os.remove(pth) + + #rename temp_htime_file with htime file + os.rename(htime_file_path, os.path.join('%s.bak'%htime_file_path)) + os.rename(temp_htime_path, htime_file_path) + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('brick_path', help="This upgrade script, which is to be run on\ + server side, takes brick path as the argument, \ + updates paths inside htime file and alters the directory structure \ + above the changelog files inorder to support new optimised format \ + of the directory structure as per \ + https://review.gluster.org/#/c/glusterfs/+/23733/") + args = parser.parse_args() + modify_htime_file(args.brick_path) diff --git a/extras/group-virt.example b/extras/group-virt.example index 6a66f977b2f..cc37c98a25c 100644 --- a/extras/group-virt.example +++ b/extras/group-virt.example @@ -17,3 +17,8 @@ cluster.choose-local=off client.event-threads=4 server.event-threads=4 performance.client-io-threads=on +network.ping-timeout=20 +server.tcp-user-timeout=20 +server.keepalive-time=10 +server.keepalive-interval=2 +server.keepalive-count=5 diff --git a/extras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh b/extras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh index 885ed03ad5b..1f2564b44ff 100755 --- a/extras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh +++ b/extras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh @@ -79,9 +79,9 @@ done if [ "$option" == "disable" ]; then # Unmount the volume on all the nodes - umount /var/run/gluster/shared_storage - cat /etc/fstab | grep -v "gluster_shared_storage /var/run/gluster/shared_storage/" > /var/run/gluster/fstab.tmp - mv /var/run/gluster/fstab.tmp /etc/fstab + umount /run/gluster/shared_storage + cat /etc/fstab | grep -v "gluster_shared_storage /run/gluster/shared_storage/" > /run/gluster/fstab.tmp + mv /run/gluster/fstab.tmp /etc/fstab fi if [ "$is_originator" == 1 ]; then @@ -104,8 +104,15 @@ function check_volume_status() echo $status } -mount_cmd="mount -t glusterfs $local_node_hostname:/gluster_shared_storage \ - /var/run/gluster/shared_storage" +key=`echo $5 | cut -d '=' -f 1` +val=`echo $5 | cut -d '=' -f 2` +if [ "$key" == "transport.address-family" ]; then + mount_cmd="mount -t glusterfs -o xlator-option=transport.address-family=inet6 \ + $local_node_hostname:/gluster_shared_storage /run/gluster/shared_storage" +else + mount_cmd="mount -t glusterfs $local_node_hostname:/gluster_shared_storage \ + /run/gluster/shared_storage" +fi if [ "$option" == "enable" ]; then retry=0; @@ -120,10 +127,10 @@ if [ "$option" == "enable" ]; then status=$(check_volume_status) done # Mount the volume on all the nodes - umount /var/run/gluster/shared_storage - mkdir -p /var/run/gluster/shared_storage + umount /run/gluster/shared_storage + mkdir -p /run/gluster/shared_storage $mount_cmd - cp /etc/fstab /var/run/gluster/fstab.tmp - echo "$local_node_hostname:/gluster_shared_storage /var/run/gluster/shared_storage/ glusterfs defaults 0 0" >> /var/run/gluster/fstab.tmp - mv /var/run/gluster/fstab.tmp /etc/fstab + cp /etc/fstab /run/gluster/fstab.tmp + echo "$local_node_hostname:/gluster_shared_storage /run/gluster/shared_storage/ glusterfs defaults 0 0" >> /run/gluster/fstab.tmp + mv /run/gluster/fstab.tmp /etc/fstab fi diff --git a/extras/hook-scripts/start/post/S31ganesha-start.sh b/extras/hook-scripts/start/post/S31ganesha-start.sh index 90ba6bc73a5..7ad6f23ad06 100755 --- a/extras/hook-scripts/start/post/S31ganesha-start.sh +++ b/extras/hook-scripts/start/post/S31ganesha-start.sh @@ -4,7 +4,7 @@ OPTSPEC="volname:,gd-workdir:" VOL= declare -i EXPORT_ID ganesha_key="ganesha.enable" -GANESHA_DIR="/var/run/gluster/shared_storage/nfs-ganesha" +GANESHA_DIR="/run/gluster/shared_storage/nfs-ganesha" CONF1="$GANESHA_DIR/ganesha.conf" GLUSTERD_WORKDIR= diff --git a/extras/quota/quota_fsck.py b/extras/quota/quota_fsck.py index 174f2a2a44c..e62f7fc52a3 100755 --- a/extras/quota/quota_fsck.py +++ b/extras/quota/quota_fsck.py @@ -156,12 +156,10 @@ def get_quota_xattr_brick(dpath): xattr_dict = {} xattr_dict['parents'] = {} - for xattr in pairs: + for xattr in pairs[1:]: + xattr = xattr.decode("utf-8") xattr_key = xattr.split("=")[0] - if re.search("# file:", xattr_key): - # skip the file comment - continue - elif xattr_key is "": + if xattr_key == "": # skip any empty lines continue elif not re.search("quota", xattr_key): diff --git a/extras/snap_scheduler/gcron.py b/extras/snap_scheduler/gcron.py index 1127be0e976..0e4df77d481 100755 --- a/extras/snap_scheduler/gcron.py +++ b/extras/snap_scheduler/gcron.py @@ -19,10 +19,10 @@ import logging.handlers import fcntl -GCRON_TASKS = "/var/run/gluster/shared_storage/snaps/glusterfs_snap_cron_tasks" +GCRON_TASKS = "/run/gluster/shared_storage/snaps/glusterfs_snap_cron_tasks" GCRON_CROND_TASK = "/etc/cron.d/glusterfs_snap_cron_tasks" GCRON_RELOAD_FLAG = "/var/run/gluster/crond_task_reload_flag" -LOCK_FILE_DIR = "/var/run/gluster/shared_storage/snaps/lock_files/" +LOCK_FILE_DIR = "/run/gluster/shared_storage/snaps/lock_files/" log = logging.getLogger("gcron-logger") start_time = 0.0 @@ -38,7 +38,8 @@ def initLogger(script_name): sh.setFormatter(formatter) process = subprocess.Popen(["gluster", "--print-logdir"], - stdout=subprocess.PIPE) + stdout=subprocess.PIPE, + universal_newlines=True) out, err = process.communicate() if process.returncode == 0: logfile = os.path.join(out.strip(), script_name[:-3]+".log") diff --git a/extras/snap_scheduler/snap_scheduler.py b/extras/snap_scheduler/snap_scheduler.py index a66c5e3d5ce..e8fcc449a9b 100755 --- a/extras/snap_scheduler/snap_scheduler.py +++ b/extras/snap_scheduler/snap_scheduler.py @@ -67,7 +67,7 @@ except ImportError: SCRIPT_NAME = "snap_scheduler" scheduler_enabled = False log = logging.getLogger(SCRIPT_NAME) -SHARED_STORAGE_DIR="/var/run/gluster/shared_storage" +SHARED_STORAGE_DIR="/run/gluster/shared_storage" GCRON_DISABLED = SHARED_STORAGE_DIR+"/snaps/gcron_disabled" GCRON_ENABLED = SHARED_STORAGE_DIR+"/snaps/gcron_enabled" GCRON_TASKS = SHARED_STORAGE_DIR+"/snaps/glusterfs_snap_cron_tasks" @@ -149,7 +149,7 @@ def initLogger(): sh.setFormatter(formatter) process = subprocess.Popen(["gluster", "--print-logdir"], - stdout=subprocess.PIPE) + stdout=subprocess.PIPE, universal_newlines=True) logfile = os.path.join(process.stdout.read()[:-1], SCRIPT_NAME + ".log") fh = logging.FileHandler(logfile) diff --git a/extras/statedumpparse.rb b/extras/statedumpparse.rb index 872f284fcb8..1aff43377db 100755 --- a/extras/statedumpparse.rb +++ b/extras/statedumpparse.rb @@ -17,25 +17,35 @@ end # client.c:client_fd_lk_ctx_dump uses a six-dash record separator. ARRSEP = /^(-{5,6}=-{5,6})?$/ HEAD = /^\[(.*)\]$/ +INPUT_FORMATS = %w[statedump json] format = 'json' +input_format = 'statedump' tz = '+0000' memstat_select,memstat_reject = //,/\Z./ -human = false OptionParser.new do |op| op.banner << " [<] <STATEDUMP>" - op.on("-f", "--format=F", "json/yaml/memstat") { |s| format = s } + op.on("-f", "--format=F", "json/yaml/memstat(-[plain|human|json])") { |s| format = s } + op.on("--input-format=F", INPUT_FORMATS.join(?/)) { |s| input_format = s } op.on("--timezone=T", "time zone to apply to zoneless timestamps [default UTC]") { |s| tz = s } - op.on("--memstat-select=RX", "memstat: select memory types maxtching RX") { |s| + op.on("--memstat-select=RX", "memstat: select memory types matching RX") { |s| memstat_select = Regexp.new s } - op.on("--memstat-reject=RX", "memstat: reject memory types maxtching RX") { |s| + op.on("--memstat-reject=RX", "memstat: reject memory types matching RX") { |s| memstat_reject = Regexp.new s } - op.on("--memstat-human", "memstat: human readable") { human = true } end.parse! + +if format =~ /\Amemstat(?:-(.*))?/ + memstat_type = $1 || 'plain' + unless %w[plain human json].include? memstat_type + raise "unknown memstat type #{memstat_type.dump}" + end + format = 'memstat' +end + repr, logsep = case format when 'yaml' require 'yaml' @@ -50,8 +60,11 @@ else end formatter = proc { |e| puts repr.call(e) } -d1 = {} +INPUT_FORMATS.include? input_format or raise "unkwown input format '#{input_format}'" + +dumpinfo = {} +# parse a statedump entry elem_cbk = proc { |s,&cbk| arraylike = false s.grep(/\S/).empty? and next @@ -74,15 +87,8 @@ elem_cbk = proc { |s,&cbk| body.reject(&:empty?).map { |e| ea = e.map { |l| k,v = l.split("=",2) - [k, begin - Integer v - rescue ArgumentError - begin - Float v - rescue ArgumentError - v - end - end] + m = /\A(0|-?[1-9]\d*)(\.\d+)?\Z/.match v + [k, m ? (m[2] ? Float(v) : Integer(v)) : v] } begin ea.to_h @@ -93,83 +99,110 @@ elem_cbk = proc { |s,&cbk| } if body - cbk.call [head, arraylike ? body : body[0]] + cbk.call [head, arraylike ? body : (body.empty? ? {} : body[0])] else STDERR.puts ["WARNING: failed to parse record:", repr.call(s)].join(logsep) end } +# aggregator routine aggr = case format when 'memstat' - mh = {} + meminfo = {} + # commit memory-related entries to meminfo proc { |k,r| case k when /memusage/ - (mh["GF_MALLOC"]||={})[k] ||= r["size"] if k =~ memstat_select and k !~ memstat_reject + (meminfo["GF_MALLOC"]||={})[k] ||= r["size"] if k =~ memstat_select and k !~ memstat_reject when "mempool" r.each {|e| kk = "mempool:#{e['pool-name']}" - (mh["mempool"]||={})[kk] ||= e["size"] if kk =~ memstat_select and kk !~ memstat_reject + (meminfo["mempool"]||={})[kk] ||= e["size"] if kk =~ memstat_select and kk !~ memstat_reject } end } else + # just format data, don't actually aggregate anything proc { |pair| formatter.call pair } end -acc = [] -$<.each { |l| - l = l.strip - if l =~ /^(DUMP-(?:START|END)-TIME):\s+(.*)/ - d1["_meta"]||={} - (d1["_meta"]["date"]||={})[$1] = Time.parse([$2, tz].join " ") - next - end +# processing the data +case input_format +when 'statedump' + acc = [] + $<.each { |l| + l = l.strip + if l =~ /^(DUMP-(?:START|END)-TIME):\s+(.*)/ + dumpinfo["_meta"]||={} + (dumpinfo["_meta"]["date"]||={})[$1] = Time.parse([$2, tz].join " ") + next + end - if l =~ HEAD - elem_cbk.call(acc, &aggr) - acc = [l] - next - end + if l =~ HEAD + elem_cbk.call(acc, &aggr) + acc = [l] + next + end - acc << l -} -elem_cbk.call(acc, &aggr) + acc << l + } + elem_cbk.call(acc, &aggr) +when 'json' + $<.each { |l| + r = JSON.load l + case r + when Array + aggr[r] + when Hash + dumpinfo.merge! r + end + } +end +# final actions: output aggregated data case format when 'memstat' - hr = proc { |n| - qa = %w[B kB MB GB] - q = ((1...qa.size).find {|i| n < (1 << i*10)} || qa.size) - 1 - [n*100 / (1 << q*10) / 100.0, qa[q]].join - } - - ma = mh.values.map(&:to_a).inject(:+) - totals = mh.map { |coll,h| [coll, h.values.inject(:+)] }.to_h + ma = meminfo.values.map(&:to_a).inject(:+) + totals = meminfo.map { |coll,h| [coll, h.values.inject(:+)] }.to_h tt = ma.transpose[1].inject(:+) - templ = "%{val} %{key}" - tft = proc { |t| t } - nft = if human - nw = [ma.transpose[1], totals.values, tt].flatten.map{|n| hr[n].size}.max - proc { |n| - hn = hr[n] - " " * (nw - hn.size) + hn + summary_sep,showm = case memstat_type + when 'json' + ["", proc { |k,v| puts({type: k, value: v}.to_json) }] + when 'plain', 'human' + # human-friendly number representation + hr = proc { |n| + qa = %w[B kB MB GB] + q = ((1...qa.size).find {|i| n < (1 << i*10)} || qa.size) - 1 + "%.2f%s" % [n.to_f / (1 << q*10), qa[q]] } + + templ = "%{val} %{key}" + tft = proc { |t| t } + nft = if memstat_type == 'human' + nw = [ma.transpose[1], totals.values, tt].flatten.map{|n| hr[n].size}.max + proc { |n| + hn = hr[n] + " " * (nw - hn.size) + hn + } + else + nw = tt.to_s.size + proc { |n| "%#{nw}d" % n } + end + ## Alternative template, key first: + # templ = "%{key} %{val}" + # tw = ma.transpose[0].map(&:size).max + # tft = proc { |t| t + " " * [tw - t.size, 0].max } + # nft = (memstat_type == 'human') ? hr : proc { |n| n } + ["\n", proc { |k,v| puts templ % {key: tft[k], val: nft[v]} }] else - nw = tt.to_s.size - proc { |n| "%#{nw}d" % n } + raise 'this should be impossible' end - # templ = "%{key} %{val}" - # tw = ma.transpose[0].map(&:size).max - # tft = proc { |t| t + " " * [tw - t.size, 0].max } - # nft = human ? hr : proc { |n| n } - showm = proc { |k,v| puts templ % {key: tft[k], val: nft[v]} } ma.sort_by { |k,v| v }.each(&showm) - puts + print summary_sep totals.each { |coll,t| showm.call "Total #{coll}", t } showm.call "TOTAL", tt else - formatter.call d1 + formatter.call dumpinfo end diff --git a/extras/systemd/glusterd.service.in b/extras/systemd/glusterd.service.in index 32542d9f78b..abb0d82911f 100644 --- a/extras/systemd/glusterd.service.in +++ b/extras/systemd/glusterd.service.in @@ -1,6 +1,8 @@ [Unit] Description=GlusterFS, a clustered file-system server Documentation=man:glusterd(8) +StartLimitBurst=6 +StartLimitIntervalSec=3600 Requires=@RPCBIND_SERVICE@ After=network.target @RPCBIND_SERVICE@ Before=network-online.target @@ -10,7 +12,7 @@ Type=forking PIDFile=@localstatedir@/run/glusterd.pid LimitNOFILE=65536 Environment="LOG_LEVEL=INFO" -EnvironmentFile=-@sysconfdir@/sysconfig/glusterd +EnvironmentFile=-@SYSCONF_DIR@/sysconfig/glusterd ExecStart=@prefix@/sbin/glusterd -p @localstatedir@/run/glusterd.pid --log-level $LOG_LEVEL $GLUSTERD_OPTIONS KillMode=process TimeoutSec=300 @@ -18,7 +20,6 @@ SuccessExitStatus=15 Restart=on-abnormal RestartSec=60 StartLimitBurst=6 -StartLimitIntervalSec=3600 StartLimitInterval=3600 [Install] diff --git a/geo-replication/gsyncd.conf.in b/geo-replication/gsyncd.conf.in index 11e57fdf54f..9688c79fab7 100644 --- a/geo-replication/gsyncd.conf.in +++ b/geo-replication/gsyncd.conf.in @@ -123,7 +123,7 @@ type=bool help=Use this to set Active Passive mode to meta-volume. [meta-volume-mnt] -value=/var/run/gluster/shared_storage +value=/run/gluster/shared_storage help=Meta Volume or Shared Volume mount path [allow-network] diff --git a/geo-replication/syncdaemon/gsyncd.py b/geo-replication/syncdaemon/gsyncd.py index 73a91fea0f8..257ed72c6ae 100644 --- a/geo-replication/syncdaemon/gsyncd.py +++ b/geo-replication/syncdaemon/gsyncd.py @@ -22,8 +22,8 @@ import gsyncdconfig as gconf from rconf import rconf import subcmds from conf import GLUSTERD_WORKDIR, GLUSTERFS_CONFDIR, GCONF_VERSION -from syncdutils import set_term_handler, finalize, lf -from syncdutils import log_raise_exception, FreeObject, escape +from syncdutils import (set_term_handler, finalize, lf, + log_raise_exception, FreeObject, escape) import argsupgrade diff --git a/geo-replication/syncdaemon/gsyncdstatus.py b/geo-replication/syncdaemon/gsyncdstatus.py index 72bcb092f01..1a655ff8887 100644 --- a/geo-replication/syncdaemon/gsyncdstatus.py +++ b/geo-replication/syncdaemon/gsyncdstatus.py @@ -23,8 +23,8 @@ from datetime import datetime from errno import EACCES, EAGAIN, ENOENT import logging -from syncdutils import EVENT_GEOREP_ACTIVE, EVENT_GEOREP_PASSIVE, gf_event -from syncdutils import EVENT_GEOREP_CHECKPOINT_COMPLETED, lf +from syncdutils import (EVENT_GEOREP_ACTIVE, EVENT_GEOREP_PASSIVE, gf_event, + EVENT_GEOREP_CHECKPOINT_COMPLETED, lf) DEFAULT_STATUS = "N/A" MONITOR_STATUS = ("Created", "Started", "Paused", "Stopped") diff --git a/geo-replication/syncdaemon/libcxattr.py b/geo-replication/syncdaemon/libcxattr.py index c7d69d7eb2e..e6406c36bd7 100644 --- a/geo-replication/syncdaemon/libcxattr.py +++ b/geo-replication/syncdaemon/libcxattr.py @@ -10,8 +10,8 @@ import os from ctypes import CDLL, get_errno -from py2py3 import bytearray_to_str, gr_create_string_buffer -from py2py3 import gr_query_xattr, gr_lsetxattr, gr_lremovexattr +from py2py3 import (bytearray_to_str, gr_create_string_buffer, + gr_query_xattr, gr_lsetxattr, gr_lremovexattr) class Xattr(object): diff --git a/geo-replication/syncdaemon/libgfchangelog.py b/geo-replication/syncdaemon/libgfchangelog.py index 34beadb3552..a3bda7282c0 100644 --- a/geo-replication/syncdaemon/libgfchangelog.py +++ b/geo-replication/syncdaemon/libgfchangelog.py @@ -12,8 +12,9 @@ import os from ctypes import CDLL, RTLD_GLOBAL, get_errno, byref, c_ulong from ctypes.util import find_library from syncdutils import ChangelogException, ChangelogHistoryNotAvailable -from py2py3 import gr_cl_history_changelog, gr_cl_done, gr_create_string_buffer -from py2py3 import gr_cl_register, gr_cl_history_done, bytearray_to_str +from py2py3 import (gr_cl_history_changelog, gr_cl_done, + gr_create_string_buffer, gr_cl_register, + gr_cl_history_done, bytearray_to_str) libgfc = CDLL( diff --git a/geo-replication/syncdaemon/master.py b/geo-replication/syncdaemon/master.py index 62640d4eaee..9501aeae6b5 100644 --- a/geo-replication/syncdaemon/master.py +++ b/geo-replication/syncdaemon/master.py @@ -24,10 +24,11 @@ from datetime import datetime import gsyncdconfig as gconf import libgfchangelog from rconf import rconf -from syncdutils import Thread, GsyncdError, escape_space_newline -from syncdutils import unescape_space_newline, gauxpfx, escape -from syncdutils import lstat, errno_wrap, FreeObject, lf, matching_disk_gfid -from syncdutils import NoStimeAvailable, PartialHistoryAvailable +from syncdutils import (Thread, GsyncdError, escape_space_newline, + unescape_space_newline, gauxpfx, escape, + lstat, errno_wrap, FreeObject, lf, matching_disk_gfid, + NoStimeAvailable, PartialHistoryAvailable, + host_brick_split) URXTIME = (-1, 0) @@ -1466,7 +1467,7 @@ class GMasterChangelogMixin(GMasterCommon): node = rconf.args.resource_remote node_data = node.split("@") node = node_data[-1] - remote_node_ip = node.split(":")[0] + remote_node_ip, _ = host_brick_split(node) self.status.set_slave_node(remote_node_ip) def changelogs_batch_process(self, changes): diff --git a/geo-replication/syncdaemon/monitor.py b/geo-replication/syncdaemon/monitor.py index 14e77aef27e..6aa7b9dfc99 100644 --- a/geo-replication/syncdaemon/monitor.py +++ b/geo-replication/syncdaemon/monitor.py @@ -22,12 +22,12 @@ from resource import SSH import gsyncdconfig as gconf import libgfchangelog from rconf import rconf -from syncdutils import select, waitpid, errno_wrap, lf, grabpidfile -from syncdutils import set_term_handler, GsyncdError -from syncdutils import Thread, finalize, Volinfo, VolinfoFromGconf -from syncdutils import gf_event, EVENT_GEOREP_FAULTY, get_up_nodes +from syncdutils import (select, waitpid, errno_wrap, lf, grabpidfile, + set_term_handler, GsyncdError, + Thread, finalize, Volinfo, VolinfoFromGconf, + gf_event, EVENT_GEOREP_FAULTY, get_up_nodes, + unshare_propagation_supported) from gsyncdstatus import GeorepStatus, set_monitor_status -from syncdutils import unshare_propagation_supported import py2py3 from py2py3 import pipe diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py index ae5600d1d9a..f12c7ceaa36 100644 --- a/geo-replication/syncdaemon/resource.py +++ b/geo-replication/syncdaemon/resource.py @@ -19,8 +19,8 @@ import struct import logging import tempfile import subprocess -from errno import EEXIST, ENOENT, ENODATA, ENOTDIR, ELOOP, EACCES -from errno import EISDIR, ENOTEMPTY, ESTALE, EINVAL, EBUSY, EPERM +from errno import (EEXIST, ENOENT, ENODATA, ENOTDIR, ELOOP, EACCES, + EISDIR, ENOTEMPTY, ESTALE, EINVAL, EBUSY, EPERM) import errno from rconf import rconf @@ -31,18 +31,19 @@ import repce from repce import RepceServer, RepceClient from master import gmaster_builder import syncdutils -from syncdutils import GsyncdError, select, privileged, funcode -from syncdutils import entry2pb, gauxpfx, errno_wrap, lstat -from syncdutils import NoStimeAvailable, PartialHistoryAvailable -from syncdutils import ChangelogException, ChangelogHistoryNotAvailable -from syncdutils import get_changelog_log_level, get_rsync_version -from syncdutils import GX_GFID_CANONICAL_LEN +from syncdutils import (GsyncdError, select, privileged, funcode, + entry2pb, gauxpfx, errno_wrap, lstat, + NoStimeAvailable, PartialHistoryAvailable, + ChangelogException, ChangelogHistoryNotAvailable, + get_changelog_log_level, get_rsync_version, + GX_GFID_CANONICAL_LEN, + gf_mount_ready, lf, Popen, sup, + Xattr, matching_disk_gfid, get_gfid_from_mnt, + unshare_propagation_supported, get_slv_dir_path) from gsyncdstatus import GeorepStatus -from syncdutils import lf, Popen, sup -from syncdutils import Xattr, matching_disk_gfid, get_gfid_from_mnt -from syncdutils import unshare_propagation_supported, get_slv_dir_path -from py2py3 import pipe, str_to_bytearray, entry_pack_reg -from py2py3 import entry_pack_reg_stat, entry_pack_mkdir, entry_pack_symlink +from py2py3 import (pipe, str_to_bytearray, entry_pack_reg, + entry_pack_reg_stat, entry_pack_mkdir, + entry_pack_symlink) ENOTSUP = getattr(errno, 'ENOTSUP', 'EOPNOTSUPP') @@ -950,6 +951,16 @@ class Mounter(object): logging.exception('mount cleanup failure:') rv = 200 os._exit(rv) + + #Polling the dht.subvol.status value. + RETRIES = 10 + while not gf_mount_ready(): + if RETRIES < 0: + logging.error('Subvols are not up') + break + RETRIES -= 1 + time.sleep(0.2) + logging.debug('auxiliary glusterfs mount prepared') diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py index 4b6f4a265f6..a3df103e76c 100644 --- a/geo-replication/syncdaemon/syncdutils.py +++ b/geo-replication/syncdaemon/syncdutils.py @@ -21,8 +21,8 @@ import subprocess import socket from subprocess import PIPE from threading import Lock, Thread as baseThread -from errno import EACCES, EAGAIN, EPIPE, ENOTCONN, ECONNABORTED -from errno import EINTR, ENOENT, ESTALE, EBUSY, errorcode +from errno import (EACCES, EAGAIN, EPIPE, ENOTCONN, ENOMEM, ECONNABORTED, + EINTR, ENOENT, ESTALE, EBUSY, ENODATA, errorcode, EIO) from signal import signal, SIGTERM import select as oselect from os import waitpid as owaitpid @@ -55,6 +55,8 @@ from rconf import rconf from hashlib import sha256 as sha256 +ENOTSUP = getattr(errno, 'ENOTSUP', 'EOPNOTSUPP') + # auxiliary gfid based access prefix _CL_AUX_GFID_PFX = ".gfid/" ROOT_GFID = "00000000-0000-0000-0000-000000000001" @@ -98,6 +100,19 @@ def unescape_space_newline(s): .replace(NEWLINE_ESCAPE_CHAR, "\n")\ .replace(PERCENTAGE_ESCAPE_CHAR, "%") +# gf_mount_ready() returns 1 if all subvols are up, else 0 +def gf_mount_ready(): + ret = errno_wrap(Xattr.lgetxattr, + ['.', 'dht.subvol.status', 16], + [ENOENT, ENOTSUP, ENODATA], [ENOMEM]) + + if isinstance(ret, int): + logging.error("failed to get the xattr value") + return 1 + ret = ret.rstrip('\x00') + if ret == "1": + return 1 + return 0 def norm(s): if s: @@ -329,6 +344,17 @@ def log_raise_exception(excont): ECONNABORTED): logging.error(lf('Gluster Mount process exited', error=errorcode[exc.errno])) + elif isinstance(exc, OSError) and exc.errno == EIO: + logging.error("Getting \"Input/Output error\" " + "is most likely due to " + "a. Brick is down or " + "b. Split brain issue.") + logging.error("This is expected as per design to " + "keep the consistency of the file system. " + "Once the above issue is resolved " + "geo-replication would automatically " + "proceed further.") + logtag = "FAIL" else: logtag = "FAIL" if not logtag and logging.getLogger().isEnabledFor(logging.DEBUG): @@ -562,7 +588,6 @@ def errno_wrap(call, arg=[], errnos=[], retry_errnos=[]): def lstat(e): return errno_wrap(os.lstat, [e], [ENOENT], [ESTALE, EBUSY]) - def get_gfid_from_mnt(gfidpath): return errno_wrap(Xattr.lgetxattr, [gfidpath, 'glusterfs.gfid.string', @@ -700,11 +725,13 @@ def get_slv_dir_path(slv_host, slv_volume, gfid): if not isinstance(realpath, int): basename = os.path.basename(realpath).rstrip('\x00') dirpath = os.path.dirname(realpath) - if dirpath is "/": + if dirpath == "/": pargfid = ROOT_GFID else: dirpath = dirpath.strip("/") pargfid = get_gfid_from_mnt(dirpath) + if isinstance(pargfid, int): + return None dir_entry = os.path.join(pfx, pargfid, basename) return dir_entry @@ -867,6 +894,19 @@ class Popen(subprocess.Popen): self.errfail() +def host_brick_split(value): + """ + IPv6 compatible way to split and get the host + and brick information. Example inputs: + node1.example.com:/exports/bricks/brick1/brick + fe80::af0f:df82:844f:ef66%utun0:/exports/bricks/brick1/brick + """ + parts = value.split(":") + brick = parts[-1] + hostparts = parts[0:-1] + return (":".join(hostparts), brick) + + class Volinfo(object): def __init__(self, vol, host='localhost', prelude=[], master=True): @@ -909,7 +949,7 @@ class Volinfo(object): @memoize def bricks(self): def bparse(b): - host, dirp = b.find("name").text.split(':', 2) + host, dirp = host_brick_split(b.find("name").text) return {'host': host, 'dir': dirp, 'uuid': b.find("hostUuid").text} return [bparse(b) for b in self.get('brick')] @@ -985,6 +1025,16 @@ class VolinfoFromGconf(object): def is_hot(self, brickpath): return False + def is_uuid(self, value): + try: + uuid.UUID(value) + return True + except ValueError: + return False + + def possible_path(self, value): + return "/" in value + @property @memoize def bricks(self): @@ -998,8 +1048,22 @@ class VolinfoFromGconf(object): out = [] for b in bricks_data: parts = b.split(":") - bpath = parts[2] if len(parts) == 3 else "" - out.append({"host": parts[1], "dir": bpath, "uuid": parts[0]}) + b_uuid = None + if self.is_uuid(parts[0]): + b_uuid = parts[0] + # Set all parts except first + parts = parts[1:] + + if self.possible_path(parts[-1]): + bpath = parts[-1] + # Set all parts except last + parts = parts[0:-1] + + out.append({ + "host": ":".join(parts), # if remaining parts are IPv6 name + "dir": bpath, + "uuid": b_uuid + }) return out diff --git a/geo-replication/tests/unit/test_gsyncdstatus.py b/geo-replication/tests/unit/test_gsyncdstatus.py index 483023dbfe9..9c1aa2ad4ad 100755 --- a/geo-replication/tests/unit/test_gsyncdstatus.py +++ b/geo-replication/tests/unit/test_gsyncdstatus.py @@ -13,11 +13,11 @@ import unittest import os import urllib -from syncdaemon.gstatus import GeorepStatus, set_monitor_status -from syncdaemon.gstatus import get_default_values -from syncdaemon.gstatus import MONITOR_STATUS, DEFAULT_STATUS -from syncdaemon.gstatus import STATUS_VALUES, CRAWL_STATUS_VALUES -from syncdaemon.gstatus import human_time, human_time_utc +from syncdaemon.gstatus import (GeorepStatus, set_monitor_status, + get_default_values, + MONITOR_STATUS, DEFAULT_STATUS, + STATUS_VALUES, CRAWL_STATUS_VALUES, + human_time, human_time_utc) class GeorepStatusTestCase(unittest.TestCase): diff --git a/glusterfs.spec.in b/glusterfs.spec.in index e6cd3636861..b6d63146e14 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in @@ -111,6 +111,12 @@ ## All %%global definitions should be placed here and keep them sorted ## +# selinux booleans whose defalut value needs modification +# these booleans will be consumed by "%%selinux_set_booleans" macro. +%if ( 0%{?rhel} && 0%{?rhel} >= 8 ) +%global selinuxbooleans rsync_full_access=1 rsync_client=1 +%endif + %if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} > 6 ) %global _with_systemd true %endif @@ -231,7 +237,9 @@ Requires(pre): shadow-utils BuildRequires: systemd %endif -Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: libglusterfs0%{?_isa} = %{version}-%{release} +Requires: libgfrpc0%{?_isa} = %{version}-%{release} +Requires: libgfxdr0%{?_isa} = %{version}-%{release} %if ( 0%{?_with_systemd:1} ) %{?systemd_requires} %endif @@ -294,40 +302,10 @@ This package includes the glusterfs binary, the glusterfsd daemon and the libglusterfs and glusterfs translator modules common to both GlusterFS server and client framework. -%package api -Summary: GlusterFS api library -Requires: %{name}%{?_isa} = %{version}-%{release} -Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release} - -%description api -GlusterFS is a distributed file-system capable of scaling to several -petabytes. It aggregates various storage bricks over TCP/IP interconnect -into one large parallel network filesystem. GlusterFS is one of the -most sophisticated file systems in terms of features and extensibility. -It borrows a powerful concept called Translators from GNU Hurd kernel. -Much of the code in GlusterFS is in user space and easily manageable. - -This package provides the glusterfs libgfapi library. - -%package api-devel -Summary: Development Libraries -Requires: %{name}%{?_isa} = %{version}-%{release} -Requires: %{name}-devel%{?_isa} = %{version}-%{release} -Requires: libacl-devel - -%description api-devel -GlusterFS is a distributed file-system capable of scaling to several -petabytes. It aggregates various storage bricks over TCP/IP interconnect -into one large parallel network filesystem. GlusterFS is one of the -most sophisticated file systems in terms of features and extensibility. -It borrows a powerful concept called Translators from GNU Hurd kernel. -Much of the code in GlusterFS is in user space and easily manageable. - -This package provides the api include files. - %package cli Summary: GlusterFS CLI -Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: libglusterfs0%{?_isa} = %{version}-%{release} +Requires: libglusterd0%{?_isa} = %{version}-%{release} %description cli GlusterFS is a distributed file-system capable of scaling to several @@ -353,22 +331,6 @@ Much of the code in GlusterFS is in user space and easily manageable. This package provides cloudsync plugins for archival feature. -%package devel -Summary: Development Libraries -Requires: %{name}%{?_isa} = %{version}-%{release} -# Needed for the Glupy examples to work -Requires: %{name}-extra-xlators%{?_isa} = %{version}-%{release} - -%description devel -GlusterFS is a distributed file-system capable of scaling to several -petabytes. It aggregates various storage bricks over TCP/IP interconnect -into one large parallel network filesystem. GlusterFS is one of the -most sophisticated file systems in terms of features and extensibility. -It borrows a powerful concept called Translators from GNU Hurd kernel. -Much of the code in GlusterFS is in user space and easily manageable. - -This package provides the development libraries and include files. - %package extra-xlators Summary: Extra Gluster filesystem Translators # We need python-gluster rpm for gluster module's __init__.py in Python @@ -416,6 +378,7 @@ Summary: NFS-Ganesha configuration Group: Applications/File Requires: %{name}-server%{?_isa} = %{version}-%{release} +Requires: nfs-ganesha-selinux >= 2.7.6 Requires: nfs-ganesha-gluster >= 2.7.6 Requires: pcs >= 0.10.0 Requires: resource-agents >= 4.2.0 @@ -431,7 +394,7 @@ Requires: net-tools %endif %if ( 0%{?fedora} && 0%{?fedora} > 25 || ( 0%{?rhel} && 0%{?rhel} > 6 ) ) -%if ( 0%{?rhel} ) +%if ( 0%{?rhel} && 0%{?rhel} < 8 ) Requires: selinux-policy >= 3.13.1-160 Requires(post): policycoreutils-python Requires(postun): policycoreutils-python @@ -465,6 +428,14 @@ Requires: python%{_pythonver}-gluster = %{version}-%{release} Requires: rsync Requires: util-linux +# required for setting selinux bools +%if ( 0%{?rhel} && 0%{?rhel} >= 8 ) +Requires(post): policycoreutils-python-utils +Requires(postun): policycoreutils-python-utils +Requires: selinux-policy-targeted +Requires(post): selinux-policy-targeted +BuildRequires: selinux-policy-devel +%endif %description geo-replication GlusterFS is a distributed file-system capable of scaling to several @@ -495,10 +466,80 @@ Much of the code in GlusterFS is in user space and easily manageable. This package provides the glusterfs legacy gNFS server xlator %endif -%package libs -Summary: GlusterFS common libraries +%package -n libglusterfs0 +Summary: GlusterFS libglusterfs library +Requires: libgfrpc0%{?_isa} = %{version}-%{release} +Requires: libgfxdr0%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-libs <= %{version}-%{release} +Provides: %{name}-libs = %{version}-%{release} + +%description -n libglusterfs0 +GlusterFS is a distributed file-system capable of scaling to several +petabytes. It aggregates various storage bricks over TCP/IP interconnect +into one large parallel network filesystem. GlusterFS is one of the +most sophisticated file systems in terms of features and extensibility. +It borrows a powerful concept called Translators from GNU Hurd kernel. +Much of the code in GlusterFS is in user space and easily manageable. + +This package provides the base libglusterfs library + +%package -n libglusterfs-devel +Summary: GlusterFS libglusterfs library +Requires: libgfrpc-devel%{?_isa} = %{version}-%{release} +Requires: libgfxdr-devel%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-devel <= %{version}-%{release} +Provides: %{name}-devel = %{version}-%{release} + +%description -n libglusterfs-devel +GlusterFS is a distributed file-system capable of scaling to several +petabytes. It aggregates various storage bricks over TCP/IP interconnect +into one large parallel network filesystem. GlusterFS is one of the +most sophisticated file systems in terms of features and extensibility. +It borrows a powerful concept called Translators from GNU Hurd kernel. +Much of the code in GlusterFS is in user space and easily manageable. + +This package provides libglusterfs.so and the gluster C header files. + +%package -n libgfapi0 +Summary: GlusterFS api library +Requires: libglusterfs0%{?_isa} = %{version}-%{release} +Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-api <= %{version}-%{release} +Provides: %{name}-api = %{version}-%{release} + +%description -n libgfapi0 +GlusterFS is a distributed file-system capable of scaling to several +petabytes. It aggregates various storage bricks over TCP/IP interconnect +into one large parallel network filesystem. GlusterFS is one of the +most sophisticated file systems in terms of features and extensibility. +It borrows a powerful concept called Translators from GNU Hurd kernel. +Much of the code in GlusterFS is in user space and easily manageable. + +This package provides the glusterfs libgfapi library. + +%package -n libgfapi-devel +Summary: Development Libraries +Requires: libglusterfs-devel%{?_isa} = %{version}-%{release} +Requires: libacl-devel +Obsoletes: %{name}-api-devel <= %{version}-%{release} +Provides: %{name}-api-devel = %{version}-%{release} + +%description -n libgfapi-devel +GlusterFS is a distributed file-system capable of scaling to several +petabytes. It aggregates various storage bricks over TCP/IP interconnect +into one large parallel network filesystem. GlusterFS is one of the +most sophisticated file systems in terms of features and extensibility. +It borrows a powerful concept called Translators from GNU Hurd kernel. +Much of the code in GlusterFS is in user space and easily manageable. + +This package provides libgfapi.so and the api C header files. -%description libs +%package -n libgfchangelog0 +Summary: GlusterFS libchangelog library +Requires: libglusterfs0%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-libs <= %{version}-%{release} + +%description -n libgfchangelog0 GlusterFS is a distributed file-system capable of scaling to several petabytes. It aggregates various storage bricks over TCP/IP interconnect into one large parallel network filesystem. GlusterFS is one of the @@ -506,7 +547,97 @@ most sophisticated file systems in terms of features and extensibility. It borrows a powerful concept called Translators from GNU Hurd kernel. Much of the code in GlusterFS is in user space and easily manageable. -This package provides the base GlusterFS libraries +This package provides the libgfchangelog library + +%package -n libgfchangelog-devel +Summary: GlusterFS libchangelog library +Requires: libglusterfs-devel%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-devel <= %{version}-%{release} + +%description -n libgfchangelog-devel +GlusterFS is a distributed file-system capable of scaling to several +petabytes. It aggregates various storage bricks over TCP/IP interconnect +into one large parallel network filesystem. GlusterFS is one of the +most sophisticated file systems in terms of features and extensibility. +It borrows a powerful concept called Translators from GNU Hurd kernel. +Much of the code in GlusterFS is in user space and easily manageable. + +This package provides libgfchangelog.so and changelog C header files. + +%package -n libgfrpc0 +Summary: GlusterFS libgfrpc0 library +Requires: libglusterfs0%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-libs <= %{version}-%{release} + +%description -n libgfrpc0 +GlusterFS is a distributed file-system capable of scaling to several +petabytes. It aggregates various storage bricks over TCP/IP interconnect +into one large parallel network filesystem. GlusterFS is one of the +most sophisticated file systems in terms of features and extensibility. +It borrows a powerful concept called Translators from GNU Hurd kernel. +Much of the code in GlusterFS is in user space and easily manageable. + +This package provides the libgfrpc library + +%package -n libgfrpc-devel +Summary: GlusterFS libgfrpc library +Requires: libglusterfs0%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-devel <= %{version}-%{release} + +%description -n libgfrpc-devel +GlusterFS is a distributed file-system capable of scaling to several +petabytes. It aggregates various storage bricks over TCP/IP interconnect +into one large parallel network filesystem. GlusterFS is one of the +most sophisticated file systems in terms of features and extensibility. +It borrows a powerful concept called Translators from GNU Hurd kernel. +Much of the code in GlusterFS is in user space and easily manageable. + +This package provides libgfrpc.so and rpc C header files. + +%package -n libgfxdr0 +Summary: GlusterFS libgfxdr0 library +Requires: libglusterfs0%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-libs <= %{version}-%{release} + +%description -n libgfxdr0 +GlusterFS is a distributed file-system capable of scaling to several +petabytes. It aggregates various storage bricks over TCP/IP interconnect +into one large parallel network filesystem. GlusterFS is one of the +most sophisticated file systems in terms of features and extensibility. +It borrows a powerful concept called Translators from GNU Hurd kernel. +Much of the code in GlusterFS is in user space and easily manageable. + +This package provides the libgfxdr library + +%package -n libgfxdr-devel +Summary: GlusterFS libgfxdr library +Requires: libglusterfs0%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-devel <= %{version}-%{release} + +%description -n libgfxdr-devel +GlusterFS is a distributed file-system capable of scaling to several +petabytes. It aggregates various storage bricks over TCP/IP interconnect +into one large parallel network filesystem. GlusterFS is one of the +most sophisticated file systems in terms of features and extensibility. +It borrows a powerful concept called Translators from GNU Hurd kernel. +Much of the code in GlusterFS is in user space and easily manageable. + +This package provides libgfxdr.so. + +%package -n libglusterd0 +Summary: GlusterFS libglusterd library +Requires: libglusterfs0%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-libs <= %{version}-%{release} + +%description -n libglusterd0 +GlusterFS is a distributed file-system capable of scaling to several +petabytes. It aggregates various storage bricks over TCP/IP interconnect +into one large parallel network filesystem. GlusterFS is one of the +most sophisticated file systems in terms of features and extensibility. +It borrows a powerful concept called Translators from GNU Hurd kernel. +Much of the code in GlusterFS is in user space and easily manageable. + +This package provides the libglusterd library %package -n python%{_pythonver}-gluster Summary: GlusterFS python library @@ -573,11 +704,15 @@ like Pacemaker. Summary: Clustered file-system server Requires: %{name}%{?_isa} = %{version}-%{release} Requires: %{name}-cli%{?_isa} = %{version}-%{release} -Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: libglusterfs0%{?_isa} = %{version}-%{release} +Requires: libgfchangelog0%{?_isa} = %{version}-%{release} +%if ( 0%{?fedora} && 0%{?fedora} >= 30 || ( 0%{?rhel} && 0%{?rhel} >= 8 ) ) +Requires: glusterfs-selinux >= 0.1.0-2 +%endif # some daemons (like quota) use a fuse-mount, glusterfsd is part of -fuse Requires: %{name}-fuse%{?_isa} = %{version}-%{release} # self-heal daemon, rebalance, nfs-server etc. are actually clients -Requires: %{name}-api%{?_isa} = %{version}-%{release} +Requires: libgfapi0%{?_isa} = %{version}-%{release} Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release} # lvm2 for snapshot, and nfs-utils and rpcbind/portmap for gnfs server Requires: lvm2 @@ -845,9 +980,6 @@ rm -rf %{buildroot} %endif exit 0 -%post api -/sbin/ldconfig - %if ( 0%{!?_without_events:1} ) %post events %systemd_post glustereventsd @@ -863,13 +995,31 @@ exit 0 %if ( 0%{!?_without_georeplication:1} ) %post geo-replication +%if ( 0%{?rhel} && 0%{?rhel} >= 8 ) +%selinux_set_booleans %{selinuxbooleans} +%endif if [ $1 -ge 1 ]; then %systemd_postun_with_restart glusterd fi exit 0 %endif -%post libs +%post -n libglusterfs0 +/sbin/ldconfig + +%post -n libgfapi0 +/sbin/ldconfig + +%post -n libgfchangelog0 +/sbin/ldconfig + +%post -n libgfrpc0 +/sbin/ldconfig + +%post -n libgfxdr0 +/sbin/ldconfig + +%post -n libglusterd0 /sbin/ldconfig %if ( 0%{!?_without_server:1} ) @@ -1115,21 +1265,6 @@ exit 0 %exclude %{_prefix}/lib/ocf/resource.d/heartbeat/* %endif -%files api -%exclude %{_libdir}/*.so -# libgfapi files -%{_libdir}/libgfapi.* -%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator -%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mount - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mount/api.so - -%files api-devel -%{_libdir}/pkgconfig/glusterfs-api.pc -%{_libdir}/libgfapi.so -%dir %{_includedir}/glusterfs -%dir %{_includedir}/glusterfs/api - %{_includedir}/glusterfs/api/* - %files cli %{_sbindir}/gluster %{_mandir}/man8/gluster.8* @@ -1140,14 +1275,33 @@ exit 0 %{_libdir}/glusterfs/%{version}%{?prereltag}/cloudsync-plugins/cloudsyncs3.so %{_libdir}/glusterfs/%{version}%{?prereltag}/cloudsync-plugins/cloudsynccvlt.so -%files devel +%files -n libglusterfs-devel %dir %{_includedir}/glusterfs - %{_includedir}/glusterfs/* -%exclude %{_includedir}/glusterfs/api -%exclude %{_libdir}/libgfapi.so -%{_libdir}/*.so + %{_includedir}/glusterfs/*.h + %{_includedir}/glusterfs/server/*.h +%{_libdir}/libglusterfs.so + +%files -n libgfapi-devel +%dir %{_includedir}/glusterfs/api + %{_includedir}/glusterfs/api/*.h +%{_libdir}/libgfapi.so +%{_libdir}/pkgconfig/glusterfs-api.pc + + +%files -n libgfchangelog-devel +%dir %{_includedir}/glusterfs/gfchangelog + %{_includedir}/glusterfs/gfchangelog/*.h +%{_libdir}/libgfchangelog.so %{_libdir}/pkgconfig/libgfchangelog.pc +%files -n libgfrpc-devel +%dir %{_includedir}/glusterfs/rpc + %{_includedir}/glusterfs/rpc/*.h +%{_libdir}/libgfrpc.so + +%files -n libgfxdr-devel +%{_libdir}/libgfxdr.so + %files client-xlators %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/cluster @@ -1234,9 +1388,26 @@ exit 0 %endif -%files libs -%{_libdir}/*.so.* -%exclude %{_libdir}/libgfapi.* +%files -n libglusterfs0 +%{_libdir}/libglusterfs.so.* + +%files -n libgfapi0 +%{_libdir}/libgfapi.so.* +%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mount + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mount/api.so + +%files -n libgfchangelog0 +%{_libdir}/libgfchangelog.so.* + +%files -n libgfrpc0 +%{_libdir}/libgfrpc.so.* + +%files -n libgfxdr0 +%{_libdir}/libgfxdr.so.* + +%files -n libglusterd0 +%{_libdir}/libglusterd.so.* +%exclude %{_libdir}/libglusterd.so %files -n python%{_pythonver}-gluster # introducing glusterfs module in site packages. @@ -1450,6 +1621,12 @@ exit 0 %endif %changelog +* Thu May 14 2020 Kaleb S. KEITHLEY <kkeithle@redhat.com> +- refactor, common practice, Issue #1126 + +* Mon May 11 2020 Sunny Kumar <sunkumar@redhat.com> +- added requires policycoreutils-python-utils on rhel8 for geo-replication + * Wed Oct 9 2019 Kaleb S. KEITHLEY <kkeithle@redhat.com> - remove leftover bd xlator cruft diff --git a/glusterfsd/src/Makefile.am b/glusterfsd/src/Makefile.am index 7b8d1dbf1fb..a0a778158d8 100644 --- a/glusterfsd/src/Makefile.am +++ b/glusterfsd/src/Makefile.am @@ -6,14 +6,15 @@ endif glusterfsd_SOURCES = glusterfsd.c glusterfsd-mgmt.c glusterfsd_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ - $(top_builddir)/rpc/xdr/src/libgfxdr.la ${GF_LDADD} -glusterfsd_LDFLAGS = $(GF_LDFLAGS) $(LIB_DL) + $(top_builddir)/rpc/xdr/src/libgfxdr.la $(GF_LDADD) $(LIB_DL) +glusterfsd_LDFLAGS = $(GF_LDFLAGS) gf_attach_SOURCES = gf_attach.c gf_attach_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/api/src/libgfapi.la \ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la +gf_attach_LDFLAGS = $(GF_LDFLAGS) noinst_HEADERS = glusterfsd.h glusterfsd-mem-types.h glusterfsd-messages.h diff --git a/glusterfsd/src/gf_attach.c b/glusterfsd/src/gf_attach.c index cb6c0f59b0b..c553b0b1f61 100644 --- a/glusterfsd/src/gf_attach.c +++ b/glusterfsd/src/gf_attach.c @@ -19,9 +19,16 @@ #include "xdr-generic.h" #include "glusterd1-xdr.h" +/* In seconds */ +#define CONNECT_TIMEOUT 60 +#define REPLY_TIMEOUT 120 + int done = 0; int rpc_status; +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + struct rpc_clnt_procedure gf_attach_actors[GLUSTERD_BRICK_MAXVALUE] = { [GLUSTERD_BRICK_NULL] = {"NULL", NULL}, [GLUSTERD_BRICK_OP] = {"BRICK_OP", NULL}, @@ -38,8 +45,12 @@ struct rpc_clnt_program gf_attach_prog = { int32_t my_callback(struct rpc_req *req, struct iovec *iov, int count, void *frame) { + pthread_mutex_lock(&mutex); rpc_status = req->rpc_status; done = 1; + /* Signal main thread which is the only waiter */ + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); return 0; } @@ -48,6 +59,7 @@ int send_brick_req(xlator_t *this, struct rpc_clnt *rpc, char *path, int op) { int ret = -1; + struct timespec ts; struct iobuf *iobuf = NULL; struct iobref *iobref = NULL; struct iovec iov = { @@ -57,7 +69,6 @@ send_brick_req(xlator_t *this, struct rpc_clnt *rpc, char *path, int op) call_frame_t *frame = NULL; gd1_mgmt_brick_op_req brick_req; void *req = &brick_req; - int i; brick_req.op = op; brick_req.name = path; @@ -87,12 +98,20 @@ send_brick_req(xlator_t *this, struct rpc_clnt *rpc, char *path, int op) iov.iov_len = ret; - for (i = 0; i < 60; ++i) { - if (rpc->conn.connected) { - break; - } - sleep(1); + /* Wait for connection */ + timespec_now_realtime(&ts); + ts.tv_sec += CONNECT_TIMEOUT; + pthread_mutex_lock(&rpc->conn.lock); + { + while (!rpc->conn.connected) + if (pthread_cond_timedwait(&rpc->conn.cond, &rpc->conn.lock, &ts) == + ETIMEDOUT) { + fprintf(stderr, "timeout waiting for RPC connection\n"); + pthread_mutex_unlock(&rpc->conn.lock); + return EXIT_FAILURE; + } } + pthread_mutex_unlock(&rpc->conn.lock); frame = create_frame(this, this->ctx->pool); if (!frame) { @@ -104,9 +123,19 @@ send_brick_req(xlator_t *this, struct rpc_clnt *rpc, char *path, int op) ret = rpc_clnt_submit(rpc, &gf_attach_prog, op, my_callback, &iov, 1, NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL); if (!ret) { - for (i = 0; !done && (i < 120); ++i) { - sleep(1); + /* OK, wait for callback */ + timespec_now_realtime(&ts); + ts.tv_sec += REPLY_TIMEOUT; + pthread_mutex_lock(&mutex); + { + while (!done) + if (pthread_cond_timedwait(&cond, &mutex, &ts) == ETIMEDOUT) { + fprintf(stderr, "timeout waiting for RPC reply\n"); + pthread_mutex_unlock(&mutex); + return EXIT_FAILURE; + } } + pthread_mutex_unlock(&mutex); } out: diff --git a/glusterfsd/src/glusterfsd-messages.h b/glusterfsd/src/glusterfsd-messages.h index 8e824ecc458..0cdbffa71ea 100644 --- a/glusterfsd/src/glusterfsd-messages.h +++ b/glusterfsd/src/glusterfsd-messages.h @@ -34,10 +34,60 @@ GLFS_MSGID( glusterfsd_msg_28, glusterfsd_msg_29, glusterfsd_msg_30, glusterfsd_msg_31, glusterfsd_msg_32, glusterfsd_msg_33, glusterfsd_msg_34, glusterfsd_msg_35, glusterfsd_msg_36, glusterfsd_msg_37, glusterfsd_msg_38, glusterfsd_msg_39, - glusterfsd_msg_40, glusterfsd_msg_41, glusterfsd_msg_42, glusterfsd_msg_43); + glusterfsd_msg_40, glusterfsd_msg_41, glusterfsd_msg_42, glusterfsd_msg_43, + glusterfsd_msg_029, glusterfsd_msg_041, glusterfsd_msg_042); #define glusterfsd_msg_1_STR "Could not create absolute mountpoint path" #define glusterfsd_msg_2_STR "Could not get current working directory" -#define glusterfsd_msg_3_STR "Failed to set dict value for key" +#define glusterfsd_msg_4_STR "failed to set mount-point to options dictionary" +#define glusterfsd_msg_3_STR "failed to set dict value for key" +#define glusterfsd_msg_5_STR "failed to set disable for key" +#define glusterfsd_msg_6_STR "failed to set enable for key" +#define glusterfsd_msg_7_STR \ + "Not a client process, not performing mount operation" +#define glusterfsd_msg_8_STR "MOUNT_POINT initialization failed" +#define glusterfsd_msg_9_STR "loading volume file failed" +#define glusterfsd_msg_10_STR "xlator option is invalid" +#define glusterfsd_msg_11_STR "Fetching the volume file from server..." +#define glusterfsd_msg_12_STR "volume initialization failed" +#define glusterfsd_msg_34_STR "memory init failed" +#define glusterfsd_msg_13_STR "ERROR: glusterfs uuid generation failed" +#define glusterfsd_msg_14_STR "ERROR: glusterfs pool creation failed" +#define glusterfsd_msg_15_STR \ + "ERROR: '--volfile-id' is mandatory if '-s' OR '--volfile-server' option " \ + "is given" +#define glusterfsd_msg_16_STR "ERROR: parsing the volfile failed" +#define glusterfsd_msg_33_STR \ + "obsolete option '--volfile-max-fecth-attempts or fetch-attempts' was " \ + "provided" +#define glusterfsd_msg_17_STR "pidfile open failed" +#define glusterfsd_msg_18_STR "pidfile lock failed" +#define glusterfsd_msg_20_STR "pidfile truncation failed" +#define glusterfsd_msg_21_STR "pidfile write failed" +#define glusterfsd_msg_22_STR "failed to exeute pthread_sigmask" +#define glusterfsd_msg_23_STR "failed to create pthread" +#define glusterfsd_msg_24_STR "daemonization failed" +#define glusterfsd_msg_25_STR "mount failed" +#define glusterfsd_msg_26_STR "failed to construct the graph" +#define glusterfsd_msg_27_STR "fuse xlator cannot be specified in volume file" +#define glusterfsd_msg_28_STR "Cannot reach volume specification file" +#define glusterfsd_msg_29_STR "ERROR: glusterfsd context not initialized" +#define glusterfsd_msg_43_STR \ + "command line argument --brick-mux is valid only for brick process" +#define glusterfsd_msg_029_STR "failed to create command line string" +#define glusterfsd_msg_30_STR "Started running version" +#define glusterfsd_msg_31_STR "Could not create new sync-environment" +#define glusterfsd_msg_40_STR "No change in volfile, countinuing" +#define glusterfsd_msg_39_STR "Unable to create/delete temporary file" +#define glusterfsd_msg_38_STR \ + "Not processing brick-op since volume graph is not yet active" +#define glusterfsd_msg_35_STR "rpc req buffer unserialization failed" +#define glusterfsd_msg_36_STR "problem in xlator loading" +#define glusterfsd_msg_37_STR "failed to get dict value" +#define glusterfsd_msg_41_STR "received attach request for volfile" +#define glusterfsd_msg_42_STR "failed to unserialize xdata to dictionary" +#define glusterfsd_msg_041_STR "can't detach. flie not found" +#define glusterfsd_msg_042_STR \ + "couldnot detach old graph. Aborting the reconfiguration operation" #endif /* !_GLUSTERFSD_MESSAGES_H_ */ diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c index 65446ab05c1..eaf6796e4c3 100644 --- a/glusterfsd/src/glusterfsd-mgmt.c +++ b/glusterfsd/src/glusterfsd-mgmt.c @@ -105,8 +105,8 @@ mgmt_process_volfile(const char *volfile, ssize_t size, char *volfile_id, if (!memcmp(sha256_hash, volfile_obj->volfile_checksum, sizeof(volfile_obj->volfile_checksum))) { UNLOCK(&ctx->volfile_lock); - gf_msg(THIS->name, GF_LOG_INFO, 0, glusterfsd_msg_40, - "No change in volfile, continuing"); + gf_smsg(THIS->name, GF_LOG_INFO, 0, glusterfsd_msg_40, + NULL); goto out; } volfile_tmp = volfile_obj; @@ -118,8 +118,8 @@ mgmt_process_volfile(const char *volfile, ssize_t size, char *volfile_id, tmp_fd = mkstemp(template); if (-1 == tmp_fd) { UNLOCK(&ctx->volfile_lock); - gf_msg(THIS->name, GF_LOG_ERROR, 0, glusterfsd_msg_39, - "Unable to create temporary file: %s", template); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, glusterfsd_msg_39, + "create template=%s", template, NULL); ret = -1; goto out; } @@ -129,8 +129,8 @@ mgmt_process_volfile(const char *volfile, ssize_t size, char *volfile_id, */ ret = sys_unlink(template); if (ret < 0) { - gf_msg(THIS->name, GF_LOG_INFO, 0, glusterfsd_msg_39, - "Unable to delete temporary file: %s", template); + gf_smsg(THIS->name, GF_LOG_INFO, 0, glusterfsd_msg_39, + "delete template=%s", template, NULL); ret = 0; } @@ -205,6 +205,7 @@ glusterfs_serialize_reply(rpcsvc_request_t *req, void *arg, retlen = xdr_serialize_generic(*outmsg, arg, xdrproc); if (retlen == -1) { gf_log(THIS->name, GF_LOG_ERROR, "Failed to encode message"); + GF_FREE(iob); goto ret; } @@ -628,7 +629,7 @@ glusterfs_volume_top_perf(const char *brick_path, dict_t *dict, goto out; } - time = (end.tv_sec - begin.tv_sec) * 1e6 + (end.tv_usec - begin.tv_usec); + time = gf_tvdiff(&begin, &end); throughput = total_blks / time; gf_log("glusterd", GF_LOG_INFO, "Throughput %.2f Mbps time %.2f secs " @@ -684,7 +685,7 @@ glusterfs_volume_top_perf(const char *brick_path, dict_t *dict, goto out; } - time = (end.tv_sec - begin.tv_sec) * 1e6 + (end.tv_usec - begin.tv_usec); + time = gf_tvdiff(&begin, &end); throughput = total_blks / time; gf_log("glusterd", GF_LOG_INFO, "Throughput %.2f Mbps time %.2f secs " @@ -747,10 +748,8 @@ glusterfs_handle_translator_op(rpcsvc_request_t *req) active = ctx->active; if (!active) { ret = -1; - gf_msg(this->name, GF_LOG_ERROR, EAGAIN, glusterfsd_msg_38, - "Not processing brick-op no. %d since volume graph is " - "not yet active.", - xlator_req.op); + gf_smsg(this->name, GF_LOG_ERROR, EAGAIN, glusterfsd_msg_38, + "brick-op_no.=%d", xlator_req.op, NULL); goto out; } any = active->first; @@ -869,8 +868,7 @@ glusterfs_handle_bitrot(rpcsvc_request_t *req) xlator_req.input.input_len, &input); if (ret < 0) { - gf_msg(this->name, GF_LOG_ERROR, 0, glusterfsd_msg_35, - "rpc req buffer unserialization failed."); + gf_smsg(this->name, GF_LOG_ERROR, 0, glusterfsd_msg_35, NULL); goto out; } @@ -879,8 +877,7 @@ glusterfs_handle_bitrot(rpcsvc_request_t *req) xlator = xlator_search_by_name(any, xname); if (!xlator) { snprintf(msg, sizeof(msg), "xlator %s is not loaded", xname); - gf_msg(this->name, GF_LOG_ERROR, 0, glusterfsd_msg_36, - "problem in xlator loading."); + gf_smsg(this->name, GF_LOG_ERROR, 0, glusterfsd_msg_36, NULL); goto out; } @@ -893,8 +890,7 @@ glusterfs_handle_bitrot(rpcsvc_request_t *req) ret = dict_get_str(input, "scrub-value", &scrub_opt); if (ret) { snprintf(msg, sizeof(msg), "Failed to get scrub value"); - gf_msg(this->name, GF_LOG_ERROR, 0, glusterfsd_msg_37, - "failed to get dict value"); + gf_smsg(this->name, GF_LOG_ERROR, 0, glusterfsd_msg_37, NULL); ret = -1; goto out; } @@ -977,10 +973,8 @@ glusterfs_handle_attach(rpcsvc_request_t *req) nextchild = newgraph->first; ret = xlator_notify(nextchild, GF_EVENT_PARENT_UP, nextchild); if (ret) { - gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_EVENT_NOTIFY_FAILED, - "Parent up notification " - "failed for %s ", - nextchild->name); + gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_EVENT_NOTIFY_FAILED, + "event=ParentUp", "name=%s", nextchild->name, NULL); goto unlock; } /* we need a protocol/server xlator as @@ -1037,10 +1031,8 @@ glusterfs_handle_svc_attach(rpcsvc_request_t *req) goto out; } - gf_msg(THIS->name, GF_LOG_INFO, 0, glusterfsd_msg_41, - "received attach " - "request for volfile-id=%s", - xlator_req.name); + gf_smsg(THIS->name, GF_LOG_INFO, 0, glusterfsd_msg_41, "volfile-id=%s", + xlator_req.name, NULL); dict = dict_new(); if (!dict) { @@ -1052,8 +1044,7 @@ glusterfs_handle_svc_attach(rpcsvc_request_t *req) ret = dict_unserialize(xlator_req.dict.dict_val, xlator_req.dict.dict_len, &dict); if (ret) { - gf_msg(this->name, GF_LOG_WARNING, EINVAL, glusterfsd_msg_42, - "failed to unserialize xdata to dictionary"); + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, glusterfsd_msg_42, NULL); goto out; } dict->extra_stdfree = xlator_req.dict.dict_val; @@ -1105,8 +1096,8 @@ glusterfs_handle_svc_detach(rpcsvc_request_t *req) if (!volfile_tmp) { UNLOCK(&ctx->volfile_lock); - gf_msg(THIS->name, GF_LOG_ERROR, 0, glusterfsd_msg_41, - "can't detach %s - not found", xlator_req.name); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, glusterfsd_msg_041, "name=%s", + xlator_req.name, NULL); /* * Used to be -ENOENT. However, the caller asked us to * make sure it's down and if it's already down that's @@ -1119,9 +1110,8 @@ glusterfs_handle_svc_detach(rpcsvc_request_t *req) ret = glusterfs_process_svc_detach(ctx, volfile_tmp); if (ret) { UNLOCK(&ctx->volfile_lock); - gf_msg("glusterfsd-mgmt", GF_LOG_ERROR, EINVAL, glusterfsd_msg_41, - "Could not detach " - "old graph. Aborting the reconfiguration operation"); + gf_smsg("glusterfsd-mgmt", GF_LOG_ERROR, EINVAL, glusterfsd_msg_042, + NULL); goto out; } } @@ -1178,10 +1168,8 @@ glusterfs_handle_dump_metrics(rpcsvc_request_t *req) goto out; if (statbuf.st_size > GF_UNIT_MB) { - gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LG_MSG_NO_MEMORY, - "Allocated size exceeds expectation: " - "reconsider logic (%" PRId64 ")", - statbuf.st_size); + gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, LG_MSG_NO_MEMORY, + "reconsider logic (%" PRId64 ")", statbuf.st_size, NULL); } msg = GF_CALLOC(1, (statbuf.st_size + 1), gf_common_mt_char); if (!msg) @@ -2226,8 +2214,8 @@ volfile: tmp_fd = mkstemp(template); if (-1 == tmp_fd) { UNLOCK(&ctx->volfile_lock); - gf_msg(frame->this->name, GF_LOG_ERROR, 0, glusterfsd_msg_39, - "Unable to create temporary file: %s", template); + gf_smsg(frame->this->name, GF_LOG_ERROR, 0, glusterfsd_msg_39, + "create template=%s", template, NULL); ret = -1; goto post_unlock; } @@ -2237,8 +2225,8 @@ volfile: */ ret = sys_unlink(template); if (ret < 0) { - gf_msg(frame->this->name, GF_LOG_INFO, 0, glusterfsd_msg_39, - "Unable to delete temporary file: %s", template); + gf_smsg(frame->this->name, GF_LOG_INFO, 0, glusterfsd_msg_39, + "delete template=%s", template, NULL); ret = 0; } diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c index 460a48cd542..dae41f33fef 100644 --- a/glusterfsd/src/glusterfsd.c +++ b/glusterfsd/src/glusterfsd.c @@ -47,12 +47,6 @@ #include <malloc.h> #endif -#ifdef HAVE_MALLOC_STATS -#ifdef DEBUG -#include <mcheck.h> -#endif -#endif - #include <glusterfs/xlator.h> #include <glusterfs/glusterfs.h> #include <glusterfs/compat.h> @@ -301,8 +295,7 @@ glusterfs_listener_init(glusterfs_ctx_t *ctx); #define DICT_SET_VAL(method, dict, key, val, msgid) \ if (method(dict, key, val)) { \ - gf_smsg("glusterfsd", GF_LOG_ERROR, 0, msgid, \ - "Failed to set dict value for key %s", key); \ + gf_smsg("glusterfsd", GF_LOG_ERROR, 0, msgid, "key=%s", key); \ goto err; \ } @@ -327,14 +320,15 @@ set_fuse_mount_options(glusterfs_ctx_t *ctx, dict_t *options) cmd_args->mount_point); if (ret == -1) { gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_1, - "gf_asprintf failed"); + "gf_asprintf failed", NULL); goto err; } } else { gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_2, - "getcwd failed"); + "getcwd failed", NULL); goto err; } + } else { mount_point = gf_strdup(cmd_args->mount_point); } @@ -408,6 +402,7 @@ set_fuse_mount_options(glusterfs_ctx_t *ctx, dict_t *options) switch (cmd_args->fopen_keep_cache) { case GF_OPTION_ENABLE: + DICT_SET_VAL(dict_set_static_ptr, options, "fopen-keep-cache", "on", glusterfsd_msg_3); break; @@ -565,8 +560,7 @@ create_fuse_mount(glusterfs_ctx_t *ctx) } if (ctx->process_mode != GF_CLIENT_PROCESS) { - gf_msg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_7, - "Not a client process, not performing mount operation"); + gf_smsg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_7, NULL); return -1; } @@ -579,8 +573,8 @@ create_fuse_mount(glusterfs_ctx_t *ctx) goto err; if (xlator_set_type(master, "mount/fuse") == -1) { - gf_msg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_8, - "MOUNT-POINT %s initialization failed", cmd_args->mount_point); + gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_8, + "MOUNT-POINT=%s", cmd_args->mount_point, NULL); goto err; } @@ -597,8 +591,8 @@ create_fuse_mount(glusterfs_ctx_t *ctx) ret = dict_set_static_ptr(master->options, ZR_FUSE_MOUNTOPTS, cmd_args->fuse_mountopts); if (ret < 0) { - gf_msg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4, - "failed to set dict value for key " ZR_FUSE_MOUNTOPTS); + gf_smsg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_3, + ZR_FUSE_MOUNTOPTS, NULL); goto err; } } @@ -630,8 +624,8 @@ get_volfp(glusterfs_ctx_t *ctx) cmd_args = &ctx->cmd_args; if ((specfp = fopen(cmd_args->volfile, "r")) == NULL) { - gf_msg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_9, - "loading volume file %s failed", cmd_args->volfile); + gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_9, + "volume_file=%s", cmd_args->volfile, NULL); return NULL; } @@ -687,8 +681,7 @@ gf_remember_xlator_option(char *arg) dot = strchr(arg, '.'); if (!dot) { - gf_msg("", GF_LOG_WARNING, 0, glusterfsd_msg_10, - "xlator option %s is invalid", arg); + gf_smsg("", GF_LOG_WARNING, 0, glusterfsd_msg_10, "arg=%s", arg, NULL); goto out; } @@ -701,8 +694,7 @@ gf_remember_xlator_option(char *arg) equals = strchr(arg, '='); if (!equals) { - gf_msg("", GF_LOG_WARNING, 0, glusterfsd_msg_10, - "xlator option %s is invalid", arg); + gf_smsg("", GF_LOG_WARNING, 0, glusterfsd_msg_10, "arg=%s", arg, NULL); goto out; } @@ -714,8 +706,7 @@ gf_remember_xlator_option(char *arg) option->key[(equals - dot - 1)] = '\0'; if (!*(equals + 1)) { - gf_msg("", GF_LOG_WARNING, 0, glusterfsd_msg_10, - "xlator option %s is invalid", arg); + gf_smsg("", GF_LOG_WARNING, 0, glusterfsd_msg_10, "arg=%s", arg, NULL); goto out; } @@ -1521,8 +1512,7 @@ reincarnate(int signum) gf_msg_trace("gluster", 0, "received reincarnate request (sig:HUP)"); if (cmd_args->volfile_server) { - gf_msg("glusterfsd", GF_LOG_INFO, 0, glusterfsd_msg_11, - "Fetching the volume file from server..."); + gf_smsg("glusterfsd", GF_LOG_INFO, 0, glusterfsd_msg_11, NULL); ret = glusterfs_volfile_fetch(ctx); } @@ -1530,8 +1520,7 @@ reincarnate(int signum) gf_log_logrotate(1); if (ret < 0) - gf_msg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_12, - "volume initialization failed."); + gf_smsg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_12, NULL); return; } @@ -1583,8 +1572,7 @@ glusterfs_ctx_defaults_init(glusterfs_ctx_t *ctx) ret = xlator_mem_acct_init(THIS, gfd_mt_end); if (ret != 0) { - gf_msg(THIS->name, GF_LOG_CRITICAL, 0, glusterfsd_msg_34, - "memory accounting init failed."); + gf_smsg(THIS->name, GF_LOG_CRITICAL, 0, glusterfsd_msg_34, NULL); return ret; } @@ -1598,8 +1586,7 @@ glusterfs_ctx_defaults_init(glusterfs_ctx_t *ctx) ctx->process_uuid = generate_glusterfs_ctx_id(); if (!ctx->process_uuid) { - gf_msg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_13, - "ERROR: glusterfs uuid generation failed"); + gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_13, NULL); goto out; } @@ -1607,23 +1594,20 @@ glusterfs_ctx_defaults_init(glusterfs_ctx_t *ctx) ctx->iobuf_pool = iobuf_pool_new(); if (!ctx->iobuf_pool) { - gf_msg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, - "ERROR: glusterfs iobuf pool creation failed"); + gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "iobuf", NULL); goto out; } ctx->event_pool = gf_event_pool_new(DEFAULT_EVENT_POOL_SIZE, STARTING_EVENT_THREADS); if (!ctx->event_pool) { - gf_msg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, - "ERROR: glusterfs event pool creation failed"); + gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "event", NULL); goto out; } ctx->pool = GF_CALLOC(1, sizeof(call_pool_t), gfd_mt_call_pool_t); if (!ctx->pool) { - gf_msg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, - "ERROR: glusterfs call pool creation failed"); + gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "call", NULL); goto out; } @@ -1633,22 +1617,19 @@ glusterfs_ctx_defaults_init(glusterfs_ctx_t *ctx) /* frame_mem_pool size 112 * 4k */ ctx->pool->frame_mem_pool = mem_pool_new(call_frame_t, 4096); if (!ctx->pool->frame_mem_pool) { - gf_msg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, - "ERROR: glusterfs frame pool creation failed"); + gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "frame", NULL); goto out; } /* stack_mem_pool size 256 * 1024 */ ctx->pool->stack_mem_pool = mem_pool_new(call_stack_t, 1024); if (!ctx->pool->stack_mem_pool) { - gf_msg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, - "ERROR: glusterfs stack pool creation failed"); + gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "stack", NULL); goto out; } ctx->stub_mem_pool = mem_pool_new(call_stub_t, 1024); if (!ctx->stub_mem_pool) { - gf_msg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, - "ERROR: glusterfs stub pool creation failed"); + gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "stub", NULL); goto out; } @@ -1706,6 +1687,10 @@ glusterfs_ctx_defaults_init(glusterfs_ctx_t *ctx) INIT_LIST_HEAD(&cmd_args->xlator_options); INIT_LIST_HEAD(&cmd_args->volfile_servers); + ctx->pxl_count = 0; + pthread_mutex_init(&ctx->fd_lock, NULL); + pthread_cond_init(&ctx->fd_cond, NULL); + INIT_LIST_HEAD(&ctx->janitor_fds); lim.rlim_cur = RLIM_INFINITY; lim.rlim_max = RLIM_INFINITY; @@ -1994,7 +1979,7 @@ parse_cmdline(int argc, char *argv[], glusterfs_ctx_t *ctx) struct stat stbuf = { 0, }; - char timestr[32]; + char timestr[GF_TIMESTR_SIZE]; char tmp_logfile[1024] = {0}; char *tmp_logfile_dyn = NULL; char *tmp_logfilebase = NULL; @@ -2056,9 +2041,7 @@ parse_cmdline(int argc, char *argv[], glusterfs_ctx_t *ctx) /* Make sure after the parsing cli, if '--volfile-server' option is given, then '--volfile-id' is mandatory */ if (cmd_args->volfile_server && !cmd_args->volfile_id) { - gf_msg("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_15, - "ERROR: '--volfile-id' is mandatory if '-s' OR " - "'--volfile-server' option is given"); + gf_smsg("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_15, NULL); ret = -1; goto out; } @@ -2075,8 +2058,8 @@ parse_cmdline(int argc, char *argv[], glusterfs_ctx_t *ctx) and exit */ ret = sys_stat(cmd_args->volfile, &stbuf); if (ret) { - gf_msg("glusterfs", GF_LOG_CRITICAL, errno, glusterfsd_msg_16, - "ERROR: parsing the volfile failed"); + gf_smsg("glusterfs", GF_LOG_CRITICAL, errno, glusterfsd_msg_16, + NULL); /* argp_usage (argp.) */ fprintf(stderr, "USAGE: %s [options] [mountpoint]\n", argv[0]); goto out; @@ -2100,8 +2083,8 @@ parse_cmdline(int argc, char *argv[], glusterfs_ctx_t *ctx) if (((ret == 0) && (S_ISREG(stbuf.st_mode) || S_ISLNK(stbuf.st_mode))) || (ret == -1)) { - /* Have separate logfile per run */ - gf_time_fmt(timestr, sizeof timestr, time(NULL), gf_timefmt_FT); + /* Have separate logfile per run. */ + gf_time_fmt(timestr, sizeof timestr, gf_time(), gf_timefmt_FT); sprintf(tmp_logfile, "%s.%s.%d", cmd_args->log_file, timestr, getpid()); @@ -2128,9 +2111,7 @@ parse_cmdline(int argc, char *argv[], glusterfs_ctx_t *ctx) compatibility with third party applications */ if (cmd_args->max_connect_attempts) { - gf_msg("glusterfs", GF_LOG_WARNING, 0, glusterfsd_msg_33, - "obsolete option '--volfile-max-fecth-attempts or " - "fetch-attempts' was provided"); + gf_smsg("glusterfs", GF_LOG_WARNING, 0, glusterfsd_msg_33, NULL); } #ifdef GF_DARWIN_HOST_OS @@ -2157,8 +2138,8 @@ glusterfs_pidfile_setup(glusterfs_ctx_t *ctx) pidfp = fopen(cmd_args->pid_file, "a+"); if (!pidfp) { - gf_msg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_17, - "pidfile %s open failed", cmd_args->pid_file); + gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_17, + "pidfile=%s", cmd_args->pid_file, NULL); goto out; } @@ -2209,29 +2190,29 @@ glusterfs_pidfile_update(glusterfs_ctx_t *ctx, pid_t pid) ret = lockf(fileno(pidfp), F_TLOCK, 0); if (ret) { - gf_msg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_18, - "pidfile %s lock failed", cmd_args->pid_file); + gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_18, + "pidfile=%s", cmd_args->pid_file, NULL); return ret; } ret = sys_ftruncate(fileno(pidfp), 0); if (ret) { - gf_msg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_20, - "pidfile %s truncation failed", cmd_args->pid_file); + gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_20, + "pidfile=%s", cmd_args->pid_file, NULL); return ret; } ret = fprintf(pidfp, "%d\n", pid); if (ret <= 0) { - gf_msg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_21, - "pidfile %s write failed", cmd_args->pid_file); + gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_21, + "pidfile=%s", cmd_args->pid_file, NULL); return ret; } ret = fflush(pidfp); if (ret) { - gf_msg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_21, - "pidfile %s write failed", cmd_args->pid_file); + gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_21, + "pidfile=%s", cmd_args->pid_file, NULL); return ret; } @@ -2324,8 +2305,7 @@ glusterfs_signals_setup(glusterfs_ctx_t *ctx) ret = pthread_sigmask(SIG_BLOCK, &set, NULL); if (ret) { - gf_msg("glusterfsd", GF_LOG_WARNING, errno, glusterfsd_msg_22, - "failed to execute pthread_sigmask"); + gf_smsg("glusterfsd", GF_LOG_WARNING, errno, glusterfsd_msg_22, NULL); return ret; } @@ -2337,8 +2317,7 @@ glusterfs_signals_setup(glusterfs_ctx_t *ctx) fallback to signals getting handled by other threads. setup the signal handlers */ - gf_msg("glusterfsd", GF_LOG_WARNING, errno, glusterfsd_msg_23, - "failed to create pthread"); + gf_smsg("glusterfsd", GF_LOG_WARNING, errno, glusterfsd_msg_23, NULL); return ret; } @@ -2384,8 +2363,7 @@ daemonize(glusterfs_ctx_t *ctx) sys_close(ctx->daemon_pipe[1]); } - gf_msg("daemonize", GF_LOG_ERROR, errno, glusterfsd_msg_24, - "daemonization failed"); + gf_smsg("daemonize", GF_LOG_ERROR, errno, glusterfsd_msg_24, NULL); goto out; case 0: /* child */ @@ -2406,8 +2384,8 @@ daemonize(glusterfs_ctx_t *ctx) } else { err = cstatus; } - gf_msg("daemonize", GF_LOG_ERROR, 0, glusterfsd_msg_25, - "mount failed"); + gf_smsg("daemonize", GF_LOG_ERROR, 0, glusterfsd_msg_25, + NULL); exit(err); } } @@ -2498,16 +2476,13 @@ glusterfs_process_volfp(glusterfs_ctx_t *ctx, FILE *fp) graph = glusterfs_graph_construct(fp); if (!graph) { - gf_msg("", GF_LOG_ERROR, 0, glusterfsd_msg_26, - "failed to construct the graph"); + gf_smsg("", GF_LOG_ERROR, 0, glusterfsd_msg_26, NULL); goto out; } for (trav = graph->first; trav; trav = trav->next) { if (strcmp(trav->type, "mount/fuse") == 0) { - gf_msg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_27, - "fuse xlator cannot be specified in volume " - "file"); + gf_smsg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_27, NULL); goto out; } } @@ -2588,8 +2563,7 @@ glusterfs_volumes_init(glusterfs_ctx_t *ctx) fp = get_volfp(ctx); if (!fp) { - gf_msg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_28, - "Cannot reach volume specification file"); + gf_smsg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_28, NULL); ret = -1; goto out; } @@ -2620,8 +2594,7 @@ main(int argc, char *argv[]) ctx = glusterfs_ctx_new(); if (!ctx) { - gf_msg("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_29, - "ERROR: glusterfs context not initialized"); + gf_smsg("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_29, NULL); return ENOMEM; } glusterfsd_ctx = ctx; @@ -2685,9 +2658,7 @@ main(int argc, char *argv[]) /* set brick_mux mode only for server process */ if ((ctx->process_mode != GF_SERVER_PROCESS) && cmd->brick_mux) { - gf_msg("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_43, - "command line argument --brick-mux is valid only for brick " - "process"); + gf_smsg("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_43, NULL); goto out; } @@ -2702,15 +2673,14 @@ main(int argc, char *argv[]) len = snprintf(cmdlinestr + pos, sizeof(cmdlinestr) - pos, " %s", argv[i]); if ((len <= 0) || (len >= (sizeof(cmdlinestr) - pos))) { - gf_msg("glusterfs", GF_LOG_ERROR, 0, glusterfsd_msg_29, - "failed to create command line string"); + gf_smsg("glusterfs", GF_LOG_ERROR, 0, glusterfsd_msg_029, NULL); ret = -1; goto out; } } - gf_msg(argv[0], GF_LOG_INFO, 0, glusterfsd_msg_30, - "Started running %s version %s (args: %s)", argv[0], - PACKAGE_VERSION, cmdlinestr); + gf_smsg(argv[0], GF_LOG_INFO, 0, glusterfsd_msg_30, "arg=%s", argv[0], + "version=%s", PACKAGE_VERSION, "cmdlinestr=%s", cmdlinestr, + NULL); ctx->cmdlinestr = gf_strdup(cmdlinestr); } @@ -2745,8 +2715,7 @@ main(int argc, char *argv[]) ctx->env = syncenv_new(0, 0, 0); if (!ctx->env) { - gf_msg("", GF_LOG_ERROR, 0, glusterfsd_msg_31, - "Could not create new sync-environment"); + gf_smsg("", GF_LOG_ERROR, 0, glusterfsd_msg_31, NULL); goto out; } diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c index 20372316edd..bf4b47f8760 100644 --- a/heal/src/glfs-heal.c +++ b/heal/src/glfs-heal.c @@ -773,8 +773,7 @@ static int glfsh_process_entries(xlator_t *xl, fd_t *fd, gf_dirent_t *entries, uint64_t *offset, num_entries_t *num_entries, print_status glfsh_print_status, - gf_boolean_t ignore_dirty, glfsh_fail_mode_t mode, - dict_t *xattr_req) + gf_boolean_t ignore_dirty, glfsh_fail_mode_t mode) { gf_dirent_t *entry = NULL; gf_dirent_t *tmp = NULL; @@ -806,7 +805,7 @@ glfsh_process_entries(xlator_t *xl, fd_t *fd, gf_dirent_t *entries, gf_uuid_parse(entry->d_name, gfid); gf_uuid_copy(loc.gfid, gfid); - ret = syncop_getxattr(this, &loc, &dict, GF_HEAL_INFO, xattr_req, NULL); + ret = syncop_getxattr(this, &loc, &dict, GF_HEAL_INFO, NULL, NULL); if (ret) { if ((mode != GLFSH_MODE_CONTINUE_ON_ERROR) && (ret == -ENOTCONN)) goto out; @@ -875,19 +874,19 @@ glfsh_crawl_directory(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc, if (heal_op == GF_SHD_OP_INDEX_SUMMARY) { ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset, num_entries, glfsh_print_heal_status, - ignore, mode, xattr_req); + ignore, mode); if (ret < 0) goto out; } else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) { ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset, num_entries, glfsh_print_spb_status, - ignore, mode, xattr_req); + ignore, mode); if (ret < 0) goto out; } else if (heal_op == GF_SHD_OP_HEAL_SUMMARY) { ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset, num_entries, glfsh_print_summary_status, - ignore, mode, xattr_req); + ignore, mode); if (ret < 0) goto out; } else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) { @@ -896,7 +895,7 @@ glfsh_crawl_directory(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc, } else if (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) { ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset, num_entries, glfsh_heal_status_boolean, - ignore, mode, xattr_req); + ignore, mode); if (ret < 0) goto out; } @@ -950,10 +949,6 @@ glfsh_print_pending_heals_type(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc, int32_t op_errno = 0; gf_boolean_t ignore = _gf_false; - ret = dict_set_str(xattr_req, "index-vgfid", vgfid); - if (ret) - return ret; - if (!strcmp(vgfid, GF_XATTROP_DIRTY_GFID)) ignore = _gf_true; @@ -1060,6 +1055,10 @@ glfsh_set_heal_options(glfs_t *fs, gf_xl_afr_op_t heal_op) if (ret) goto out; + ret = glfs_set_xlator_option(fs, "*-replicate-*", "halo-enabled", "off"); + if (ret) + goto out; + if ((heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE) && (heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) && (heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME)) @@ -1730,14 +1729,19 @@ main(int argc, char **argv) goto out; } + char *var_str = (heal_op == GF_SHD_OP_INDEX_SUMMARY || + heal_op == GF_SHD_OP_HEAL_SUMMARY) + ? "replicate/disperse" + : "replicate"; + ret = glfsh_validate_volume(top_subvol, heal_op); if (ret < 0) { ret = -EINVAL; - gf_asprintf(&op_errstr, "Volume %s is not of type %s", volname, - (heal_op == GF_SHD_OP_INDEX_SUMMARY || - heal_op == GF_SHD_OP_HEAL_SUMMARY) - ? "replicate/disperse" - : "replicate"); + gf_asprintf(&op_errstr, + "This command is supported " + "for only volumes of %s type. Volume %s " + "is not of type %s", + var_str, volname, var_str); goto out; } rootloc.inode = inode_ref(top_subvol->itable->root); diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index cd9d28e3cdc..385e8ef4600 100644 --- a/libglusterfs/src/Makefile.am +++ b/libglusterfs/src/Makefile.am @@ -12,7 +12,8 @@ libglusterfs_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 \ -DSBIN_DIR=\"$(sbindir)\" -I$(CONTRIBDIR)/timer-wheel \ -I$(CONTRIBDIR)/xxhash -libglusterfs_la_LIBADD = $(ZLIB_LIBS) $(MATH_LIB) $(UUID_LIBS) +libglusterfs_la_LIBADD = $(ZLIB_LIBS) $(MATH_LIB) $(UUID_LIBS) $(LIB_DL) \ + $(URCU_LIBS) $(URCU_CDS_LIBS) libglusterfs_la_LDFLAGS = -version-info $(LIBGLUSTERFS_LT_VERSION) $(GF_LDFLAGS) \ -export-symbols $(top_srcdir)/libglusterfs/src/libglusterfs.sym diff --git a/libglusterfs/src/client_t.c b/libglusterfs/src/client_t.c index 4cd22f4920c..9d377c3c2e1 100644 --- a/libglusterfs/src/client_t.c +++ b/libglusterfs/src/client_t.c @@ -314,8 +314,6 @@ client_destroy(client_t *client) clienttable = client->this->ctx->clienttable; - LOCK_DESTROY(&client->scratch_ctx.lock); - LOCK(&clienttable->lock); { clienttable->cliententries[client->tbl_index].client = NULL; @@ -333,6 +331,8 @@ client_destroy(client_t *client) if (client->subdir_inode) inode_unref(client->subdir_inode); + LOCK_DESTROY(&client->scratch_ctx.lock); + GF_FREE(client->auth.data); GF_FREE(client->auth.username); GF_FREE(client->auth.passwd); diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 5814eb90e21..682cbf28055 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -37,6 +37,9 @@ #ifndef GF_LINUX_HOST_OS #include <sys/resource.h> #endif +#ifdef HAVE_SYNCFS_SYS +#include <sys/syscall.h> +#endif #include "glusterfs/compat-errno.h" #include "glusterfs/common-utils.h" @@ -50,6 +53,7 @@ #include "xxhash.h" #include <ifaddrs.h> #include "glusterfs/libglusterfs-messages.h" +#include "glusterfs/glusterfs-acl.h" #ifdef __FreeBSD__ #include <pthread_np.h> #undef BIT_SET @@ -75,6 +79,15 @@ char *vol_type_str[] = { typedef int32_t (*rw_op_t)(int32_t fd, char *buf, int32_t size); typedef int32_t (*rwv_op_t)(int32_t fd, const struct iovec *buf, int32_t size); +char *xattrs_to_heal[] = {"user.", + POSIX_ACL_ACCESS_XATTR, + POSIX_ACL_DEFAULT_XATTR, + QUOTA_LIMIT_KEY, + QUOTA_LIMIT_OBJECTS_KEY, + GF_SELINUX_XATTR_KEY, + GF_XATTR_MDATA_KEY, + NULL}; + void gf_xxh64_wrapper(const unsigned char *data, size_t const len, unsigned long long const seed, char *xxh64) @@ -302,8 +315,7 @@ mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks) dir[i] = '\0'; ret = sys_mkdir(dir, mode); if (ret && errno != EEXIST) { - gf_msg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, - "Failed due to reason"); + gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, NULL); goto out; } @@ -314,10 +326,8 @@ mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks) if (S_ISLNK(stbuf.st_mode)) { ret = -1; - gf_msg("", GF_LOG_ERROR, 0, LG_MSG_DIR_IS_SYMLINK, - "%s is a " - "symlink", - dir); + gf_smsg("", GF_LOG_ERROR, 0, LG_MSG_DIR_IS_SYMLINK, "dir=%s", + dir, NULL); goto out; } } @@ -330,10 +340,10 @@ mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks) if (ret == 0) errno = 0; ret = -1; - gf_msg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, - "Failed" - " to create directory, possibly some of the components" - " were not directories"); + gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, + "possibly some of the components" + " were not directories", + NULL); goto out; } @@ -406,10 +416,8 @@ gf_rev_dns_lookup(const char *ip) /* Get the FQDN */ ret = gf_get_hostname_from_ip((char *)ip, &fqdn); if (ret != 0) { - gf_msg("resolver", GF_LOG_INFO, errno, LG_MSG_RESOLVE_HOSTNAME_FAILED, - "could not resolve " - "hostname for %s", - ip); + gf_smsg("resolver", GF_LOG_INFO, errno, LG_MSG_RESOLVE_HOSTNAME_FAILED, + "hostname=%s", ip, NULL); } out: return fqdn; @@ -430,7 +438,7 @@ gf_resolve_path_parent(const char *path) GF_VALIDATE_OR_GOTO(THIS->name, path, out); - if (strlen(path) <= 0) { + if (0 == strlen(path)) { gf_msg_callingfn(THIS->name, GF_LOG_DEBUG, 0, LG_MSG_INVALID_STRING, "invalid string for 'path'"); goto out; @@ -498,9 +506,8 @@ gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache, } if ((ret = getaddrinfo(hostname, port_str, &hints, &cache->first)) != 0) { - gf_msg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED, - "getaddrinfo failed (family:%d) (%s)", family, - gai_strerror(ret)); + gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED, + "family=%d", family, "ret=%s", gai_strerror(ret), NULL); GF_FREE(*dnscache); *dnscache = NULL; @@ -517,10 +524,8 @@ gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache, cache->next->ai_addrlen, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST); if (ret != 0) { - gf_msg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, - "getnameinfo failed" - " (%s)", - gai_strerror(ret)); + gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto err; } @@ -539,10 +544,8 @@ gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache, cache->next->ai_addrlen, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST); if (ret != 0) { - gf_msg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, - "getnameinfo failed" - " (%s)", - gai_strerror(ret)); + gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto err; } @@ -574,8 +577,14 @@ struct dnscache * gf_dnscache_init(time_t ttl) { struct dnscache *cache = GF_MALLOC(sizeof(*cache), gf_common_mt_dnscache); - if (cache) { - cache->cache_dict = NULL; + if (!cache) + return NULL; + + cache->cache_dict = dict_new(); + if (!cache->cache_dict) { + GF_FREE(cache); + cache = NULL; + } else { cache->ttl = ttl; } @@ -583,6 +592,20 @@ gf_dnscache_init(time_t ttl) } /** + * gf_dnscache_deinit -- cleanup resources used by struct dnscache + */ +void +gf_dnscache_deinit(struct dnscache *cache) +{ + if (!cache) { + gf_msg_plain(GF_LOG_WARNING, "dnscache is NULL"); + return; + } + dict_unref(cache->cache_dict); + GF_FREE(cache); +} + +/** * gf_dnscache_entry_init -- Initialize a dnscache entry * * @return: SUCCESS: Pointer to an allocated dnscache entry struct @@ -630,12 +653,6 @@ gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache) if (!dnscache) goto out; - if (!dnscache->cache_dict) { - dnscache->cache_dict = dict_new(); - if (!dnscache->cache_dict) { - goto out; - } - } cache = dnscache->cache_dict; /* Quick cache lookup to see if we already hold it */ @@ -643,7 +660,7 @@ gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache) if (entrydata) { dnsentry = (struct dnscache_entry *)entrydata->data; /* First check the TTL & timestamp */ - if (time(NULL) - dnsentry->timestamp > dnscache->ttl) { + if (gf_time() - dnsentry->timestamp > dnscache->ttl) { gf_dnscache_entry_deinit(dnsentry); entrydata->data = NULL; /* Mark this as 'null' so * dict_del () doesn't try free @@ -674,23 +691,16 @@ gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache) from_cache = _gf_false; out: /* Insert into the cache */ - if (fqdn && !from_cache) { + if (fqdn && !from_cache && ip) { struct dnscache_entry *entry = gf_dnscache_entry_init(); - if (!entry) { - goto out; - } - entry->fqdn = fqdn; - if (!ip) { - gf_dnscache_entry_deinit(entry); - goto out; + if (entry) { + entry->fqdn = fqdn; + entry->ip = gf_strdup(ip); + entry->timestamp = gf_time(); + entrydata = bin_to_data(entry, sizeof(*entry)); + dict_set(cache, (char *)ip, entrydata); } - - entry->ip = gf_strdup(ip); - entry->timestamp = time(NULL); - - entrydata = bin_to_data(entry, sizeof(*entry)); - dict_set(cache, (char *)ip, entrydata); } return fqdn; } @@ -899,7 +909,7 @@ gf_print_trace(int32_t signum, glusterfs_ctx_t *ctx) char msg[1024] = { 0, }; - char timestr[64] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; call_stack_t *stack = NULL; @@ -939,7 +949,7 @@ gf_print_trace(int32_t signum, glusterfs_ctx_t *ctx) { /* Dump the timestamp of the crash too, so the previous logs can be related */ - gf_time_fmt(timestr, sizeof timestr, time(NULL), gf_timefmt_FT); + gf_time_fmt(timestr, sizeof timestr, gf_time(), gf_timefmt_FT); gf_msg_plain_nomem(GF_LOG_ALERT, "time of crash: "); gf_msg_plain_nomem(GF_LOG_ALERT, timestr); } @@ -2103,8 +2113,8 @@ get_checksum_for_path(char *path, uint32_t *checksum, int op_version) fd = open(path, O_RDWR); if (fd == -1) { - gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_PATH_ERROR, - "Unable to open %s", path); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_PATH_OPEN_FAILED, + "path=%s", path, NULL); goto out; } @@ -2137,8 +2147,8 @@ get_file_mtime(const char *path, time_t *stamp) ret = sys_stat(path, &f_stat); if (ret < 0) { - gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED, - "failed to stat %s", path); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED, + "path=%s", path, NULL); goto out; } @@ -2197,14 +2207,14 @@ gf_is_ip_in_net(const char *network, const char *ip_str) /* Convert IP address to a long */ ret = inet_pton(family, ip_str, &ip_buf); if (ret < 0) - gf_msg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED, - "inet_pton() failed"); + gf_smsg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED, + NULL); /* Convert network IP address to a long */ ret = inet_pton(family, net_ip, &net_ip_buf); if (ret < 0) { - gf_msg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED, - "inet_pton() failed"); + gf_smsg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED, + NULL); goto out; } @@ -2784,8 +2794,8 @@ gf_boolean_t gf_sock_union_equal_addr(union gf_sock_union *a, union gf_sock_union *b) { if (!a || !b) { - gf_msg("common-utils", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, - "Invalid arguments to gf_sock_union_equal_addr"); + gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, + "gf_sock_union_equal_addr", NULL); return _gf_false; } @@ -3013,8 +3023,8 @@ gf_roundup_power_of_two(int32_t nr) int32_t result = 1; if (nr < 0) { - gf_msg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, - "negative number passed"); + gf_smsg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, + NULL); result = -1; goto out; } @@ -3037,8 +3047,8 @@ gf_roundup_next_power_of_two(int32_t nr) int32_t result = 1; if (nr < 0) { - gf_msg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, - "negative number passed"); + gf_smsg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, + NULL); result = -1; goto out; } @@ -3123,7 +3133,7 @@ get_mem_size() memsize = page_size * num_pages; #endif -#if defined GF_DARWIN_HOST_OS +#if defined GF_DARWIN_HOST_OS || defined __FreeBSD__ size_t len = sizeof(memsize); int name[] = {CTL_HW, HW_PHYSMEM}; @@ -3212,8 +3222,7 @@ gf_canonicalize_path(char *path) out: if (ret) - gf_msg("common-utils", GF_LOG_ERROR, 0, LG_MSG_PATH_ERROR, - "Path manipulation failed"); + gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_PATH_ERROR, NULL); GF_FREE(tmppath); @@ -3267,19 +3276,15 @@ gf_get_reserved_ports() * continue with older method of using any of the available * port? For now 2nd option is considered. */ - gf_msg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED, - "could not open the file " - "/proc/sys/net/ipv4/ip_local_reserved_ports for " - "getting reserved ports info"); + gf_smsg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED, + " /proc/sys/net/ipv4/ip_local_reserved_ports", NULL); goto out; } ret = sys_read(proc_fd, buffer, sizeof(buffer) - 1); if (ret < 0) { - gf_msg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED, - "could not read the file %s for" - " getting reserved ports info", - proc_file); + gf_smsg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED, + "file=%s", proc_file, NULL); goto out; } @@ -3307,10 +3312,8 @@ gf_process_reserved_ports(unsigned char *ports, uint32_t ceiling) ports_info = gf_get_reserved_ports(); if (!ports_info) { - gf_msg("glusterfs", GF_LOG_WARNING, 0, LG_MSG_RESERVED_PORTS_ERROR, - "Not able to get reserved" - " ports, hence there is a possibility that glusterfs " - "may consume reserved port"); + gf_smsg("glusterfs", GF_LOG_WARNING, 0, LG_MSG_RESERVED_PORTS_ERROR, + NULL); goto out; } @@ -3347,8 +3350,8 @@ gf_ports_reserved(char *blocked_port, unsigned char *ports, uint32_t ceiling) blocked_port[strlen(blocked_port) - 1] = '\0'; if (gf_string2int32(blocked_port, &tmp_port1) == 0) { if (tmp_port1 > GF_PORT_MAX || tmp_port1 < 0) { - gf_msg("glusterfs-socket", GF_LOG_WARNING, 0, - LG_MSG_INVALID_PORT, "invalid port %d", tmp_port1); + gf_smsg("glusterfs-socket", GF_LOG_WARNING, 0, + LG_MSG_INVALID_PORT, "port=%d", tmp_port1, NULL); result = _gf_true; goto out; } else { @@ -3359,10 +3362,8 @@ gf_ports_reserved(char *blocked_port, unsigned char *ports, uint32_t ceiling) BIT_SET(ports, tmp_port1); } } else { - gf_msg("glusterfs-socket", GF_LOG_WARNING, 0, LG_MSG_INVALID_PORT, - "%s is not a valid port " - "identifier", - blocked_port); + gf_smsg("glusterfs-socket", GF_LOG_WARNING, 0, LG_MSG_INVALID_PORT, + "port=%s", blocked_port, NULL); result = _gf_true; goto out; } @@ -3464,10 +3465,8 @@ gf_get_hostname_from_ip(char *client_ip, char **hostname) ret = getnameinfo(client_sockaddr, addr_sz, client_hostname, sizeof(client_hostname), NULL, 0, 0); if (ret) { - gf_msg("common-utils", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, - "Could not lookup hostname " - "of %s : %s", - client_ip, gai_strerror(ret)); + gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, + "ip=%s", client_ip, "ret=%s", gai_strerror(ret), NULL); ret = -1; goto out; } @@ -3496,8 +3495,8 @@ gf_interface_search(char *ip) ret = getifaddrs(&ifaddr); if (ret != 0) { - gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETIFADDRS_FAILED, - "getifaddrs() failed: %s\n", gai_strerror(ret)); + gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETIFADDRS_FAILED, "ret=%s", + gai_strerror(ret), NULL); goto out; } @@ -3521,10 +3520,8 @@ gf_interface_search(char *ip) host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (ret != 0) { - gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, - "getnameinfo() " - "failed: %s\n", - gai_strerror(ret)); + gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto out; } @@ -3574,14 +3571,12 @@ get_ip_from_addrinfo(struct addrinfo *addr, char **ip) break; default: - gf_msg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, - "Invalid family"); + gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, NULL); return NULL; } if (!inet_ntop(addr->ai_family, in_addr, buf, sizeof(buf))) { - gf_msg("glusterd", GF_LOG_ERROR, 0, LG_MSG_CONVERSION_FAILED, - "String conversion failed"); + gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_CONVERSION_FAILED, NULL); return NULL; } @@ -3616,10 +3611,9 @@ gf_is_loopback_localhost(const struct sockaddr *sa, char *hostname) default: if (hostname) - gf_msg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, - "unknown " - "address family %d for %s", - sa->sa_family, hostname); + gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, + "family=%d", sa->sa_family, "hostname=%s", hostname, + NULL); break; } @@ -3649,8 +3643,8 @@ gf_is_local_addr(char *hostname) ret = getaddrinfo(hostname, NULL, &hints, &result); if (ret != 0) { - gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED, - "error in getaddrinfo: %s\n", gai_strerror(ret)); + gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto out; } @@ -3698,15 +3692,15 @@ gf_is_same_address(char *name1, char *name2) gai_err = getaddrinfo(name1, NULL, &hints, &addr1); if (gai_err != 0) { - gf_msg(name1, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, - "error in getaddrinfo: %s\n", gai_strerror(gai_err)); + gf_smsg(name1, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, "error=%s", + gai_strerror(gai_err), NULL); goto out; } gai_err = getaddrinfo(name2, NULL, &hints, &addr2); if (gai_err != 0) { - gf_msg(name2, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, - "error in getaddrinfo: %s\n", gai_strerror(gai_err)); + gf_smsg(name2, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, "error=%s", + gai_strerror(gai_err), NULL); goto out; } @@ -3844,8 +3838,8 @@ gf_set_volfile_server_common(cmd_args_t *cmd_args, const char *host, !strcmp(tmp->transport, server->transport) && (tmp->port == server->port))) { /* Duplicate option given, log and ignore */ - gf_msg("gluster", GF_LOG_INFO, EEXIST, LG_MSG_INVALID_ENTRY, - "duplicate entry for volfile-server"); + gf_smsg("gluster", GF_LOG_INFO, EEXIST, LG_MSG_DUPLICATE_ENTRY, + NULL); ret = 0; goto out; } @@ -4023,15 +4017,14 @@ gf_thread_set_vname(pthread_t thread, const char *name, va_list args) sizeof(thread_name) - sizeof(GF_THREAD_NAME_PREFIX) + 1, name, args); if (ret < 0) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PTHREAD_NAMING_FAILED, - "Failed to compose thread name ('%s')", name); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PTHREAD_NAMING_FAILED, + "name=%s", name, NULL); return; } if (ret >= sizeof(thread_name)) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PTHREAD_NAMING_FAILED, - "Thread name is too long. It has been truncated ('%s')", - thread_name); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_THREAD_NAME_TOO_LONG, + "name=%s", thread_name, NULL); } #ifdef GF_LINUX_HOST_OS @@ -4045,8 +4038,8 @@ gf_thread_set_vname(pthread_t thread, const char *name, va_list args) ret = ENOSYS; #endif if (ret != 0) { - gf_msg(THIS->name, GF_LOG_WARNING, ret, LG_MSG_PTHREAD_NAMING_FAILED, - "Could not set thread name: %s", thread_name); + gf_smsg(THIS->name, GF_LOG_WARNING, ret, LG_MSG_SET_THREAD_FAILED, + "name=%s", thread_name, NULL); } } @@ -4081,8 +4074,8 @@ gf_thread_vcreate(pthread_t *thread, const pthread_attr_t *attr, ret = pthread_create(thread, attr, start_routine, arg); if (ret != 0) { - gf_msg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_FAILED, - "Thread creation failed"); + gf_smsg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_THREAD_CREATE_FAILED, + NULL); ret = -1; } else if (name != NULL) { gf_thread_set_vname(*thread, name, args); @@ -4118,8 +4111,8 @@ gf_thread_create_detached(pthread_t *thread, void *(*start_routine)(void *), ret = pthread_attr_init(&attr); if (ret) { - gf_msg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_ATTR_INIT_FAILED, - "Thread attribute initialization failed"); + gf_smsg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_ATTR_INIT_FAILED, + NULL); return -1; } @@ -4141,8 +4134,7 @@ gf_skip_header_section(int fd, int header_len) ret = sys_lseek(fd, header_len, SEEK_SET); if (ret == (off_t)-1) { - gf_msg("", GF_LOG_ERROR, 0, LG_MSG_SKIP_HEADER_FAILED, - "Failed to skip header section"); + gf_smsg("", GF_LOG_ERROR, 0, LG_MSG_SKIP_HEADER_FAILED, NULL); } else { ret = 0; } @@ -4155,6 +4147,14 @@ gf_skip_header_section(int fd, int header_len) gf_boolean_t gf_is_pid_running(int pid) { +#ifdef __FreeBSD__ + int ret = -1; + + ret = sys_kill(pid, 0); + if (ret < 0) { + return _gf_false; + } +#else char fname[32] = { 0, }; @@ -4168,6 +4168,7 @@ gf_is_pid_running(int pid) } sys_close(fd); +#endif return _gf_true; } @@ -4192,8 +4193,8 @@ gf_is_service_running(char *pidfile, int *pid) ret = fscanf(file, "%d", pid); if (ret <= 0) { - gf_msg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, - "Unable to read pidfile: %s", pidfile); + gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, "pidfile=%s", + pidfile, NULL); *pid = -1; running = _gf_false; goto out; @@ -4267,10 +4268,10 @@ gf_check_log_format(const char *value) log_format = gf_logformat_withmsgid; if (log_format == -1) - gf_msg( - THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG, - "Invalid log-format. possible values are " GF_LOG_FORMAT_NO_MSG_ID - "|" GF_LOG_FORMAT_WITH_MSG_ID); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG, + "possible_values=" GF_LOG_FORMAT_NO_MSG_ID + "|" GF_LOG_FORMAT_WITH_MSG_ID, + NULL); return log_format; } @@ -4286,9 +4287,9 @@ gf_check_logger(const char *value) logger = gf_logger_syslog; if (logger == -1) - gf_msg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG, - "Invalid logger. possible values are " GF_LOGGER_GLUSTER_LOG - "|" GF_LOGGER_SYSLOG); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG, + "possible_values=" GF_LOGGER_GLUSTER_LOG "|" GF_LOGGER_SYSLOG, + NULL); return logger; } @@ -4360,8 +4361,8 @@ gf_set_timestamp(const char *src, const char *dest) ret = sys_stat(src, &sb); if (ret) { - gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED, - "stat on %s", src); + gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED, + "stat=%s", src, NULL); goto out; } /* The granularity is nano seconds if `utimensat()` is available, @@ -4377,8 +4378,8 @@ gf_set_timestamp(const char *src, const char *dest) /* dirfd = 0 is ignored because `dest` is an absolute path. */ ret = sys_utimensat(AT_FDCWD, dest, new_time, AT_SYMLINK_NOFOLLOW); if (ret) { - gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMENSAT_FAILED, - "utimensat on %s", dest); + gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMENSAT_FAILED, + "dest=%s", dest, NULL); } #else new_time[0].tv_sec = sb.st_atime; @@ -4389,8 +4390,8 @@ gf_set_timestamp(const char *src, const char *dest) ret = sys_utimes(dest, new_time); if (ret) { - gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMES_FAILED, - "utimes on %s", dest); + gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMES_FAILED, + "dest=%s", dest, NULL); } #endif out: @@ -4409,7 +4410,7 @@ gf_backtrace_end(char *buf, size_t frames) frames = min(frames, GF_BACKTRACE_LEN - pos - 1); - if (frames <= 0) + if (0 == frames) return; memset(buf + pos, ')', frames); @@ -4455,8 +4456,8 @@ gf_backtrace_fillframes(char *buf) */ ret = sys_unlink(tmpl); if (ret < 0) { - gf_msg(THIS->name, GF_LOG_INFO, 0, LG_MSG_FILE_OP_FAILED, - "Unable to delete temporary file: %s", tmpl); + gf_smsg(THIS->name, GF_LOG_INFO, 0, LG_MSG_FILE_DELETE_FAILED, + "temporary_file=%s", tmpl, NULL); } /*The most recent two frames are the calling function and @@ -4516,8 +4517,7 @@ gf_backtrace_save(char *buf) if ((0 == gf_backtrace_fillframes(bt))) return bt; - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_BACKTRACE_SAVE_FAILED, - "Failed to save the backtrace."); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_BACKTRACE_SAVE_FAILED, NULL); return NULL; } @@ -4608,16 +4608,16 @@ gf_build_absolute_path(char *current_path, char *relative_path, char **path) */ currentpath_len = strlen(current_path); if (current_path[0] != '/' || (currentpath_len > PATH_MAX)) { - gf_msg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, - "Wrong value for current path %s", current_path); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_WRONG_VALUE, + "current-path=%s", current_path, NULL); ret = -EINVAL; goto err; } relativepath_len = strlen(relative_path); if (relative_path[0] == '/' || (relativepath_len > PATH_MAX)) { - gf_msg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, - "Wrong value for relative path %s", relative_path); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_WRONG_VALUE, + "relative-path=%s", relative_path, NULL); ret = -EINVAL; goto err; } @@ -4733,8 +4733,9 @@ recursive_rmdir(const char *delete_path) goto out; } - GF_SKIP_IRRELEVANT_ENTRIES(entry, dir, scratch); - while (entry) { + while ((entry = sys_readdir(dir, scratch))) { + if (gf_irrelevant_entry(entry)) + continue; snprintf(path, PATH_MAX, "%s/%s", delete_path, entry->d_name); ret = sys_lstat(path, &st); if (ret == -1) { @@ -4760,8 +4761,6 @@ recursive_rmdir(const char *delete_path) gf_msg_debug(this->name, 0, "%s %s", ret ? "Failed to remove" : "Removed", entry->d_name); - - GF_SKIP_IRRELEVANT_ENTRIES(entry, dir, scratch); } ret = sys_closedir(dir); @@ -5441,3 +5440,26 @@ gf_nanosleep(uint64_t nsec) return ret; } + +int +gf_syncfs(int fd) +{ + int ret = 0; +#if defined(HAVE_SYNCFS) + /* Linux with glibc recent enough. */ + ret = syncfs(fd); +#elif defined(HAVE_SYNCFS_SYS) + /* Linux with no library function. */ + ret = syscall(SYS_syncfs, fd); +#else + /* Fallback to generic UNIX stuff. */ + sync(); +#endif + return ret; +} + +char ** +get_xattrs_to_heal() +{ + return xattrs_to_heal; +} diff --git a/libglusterfs/src/ctx.c b/libglusterfs/src/ctx.c index 4a001c29209..3d890b04ec9 100644 --- a/libglusterfs/src/ctx.c +++ b/libglusterfs/src/ctx.c @@ -37,8 +37,12 @@ glusterfs_ctx_new() ctx->log.loglevel = DEFAULT_LOG_LEVEL; -#ifdef RUN_WITH_VALGRIND - ctx->cmd_args.valgrind = _gf_true; +#if defined(RUN_WITH_MEMCHECK) + ctx->cmd_args.vgtool = _gf_memcheck; +#elif defined(RUN_WITH_DRD) + ctx->cmd_args.vgtool = _gf_drd; +#else + ctx->cmd_args.vgtool = _gf_none; #endif /* lock is never destroyed! */ diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index ddd27ebd940..1d9be9217a6 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -98,6 +98,7 @@ get_new_dict_full(int size_hint) } dict->free_pair.key = NULL; + dict->totkvlen = 0; LOCK_INIT(&dict->lock); return dict; @@ -410,6 +411,7 @@ dict_set_lk(dict_t *this, char *key, const int key_len, data_t *value, if (pair) { data_t *unref_data = pair->value; pair->value = data_ref(value); + this->totkvlen += (value->len - unref_data->len); data_unref(unref_data); if (key_free) GF_FREE(key); @@ -445,6 +447,7 @@ dict_set_lk(dict_t *this, char *key, const int key_len, data_t *value, } pair->key_hash = key_hash; pair->value = data_ref(value); + this->totkvlen += (keylen + 1 + value->len); /* If the divisor is 1, the modulo is always 0, * in such case avoid hash calculation. @@ -642,6 +645,7 @@ dict_deln(dict_t *this, char *key, const int keylen) else this->members[hashval] = pair->hash_next; + this->totkvlen -= pair->value->len; data_unref(pair->value); if (pair->prev) @@ -652,6 +656,7 @@ dict_deln(dict_t *this, char *key, const int keylen) if (pair->next) pair->next->prev = pair->prev; + this->totkvlen -= (strlen(pair->key) + 1); GF_FREE(pair->key); if (pair == &this->free_pair) { this->free_pair.key = NULL; @@ -701,6 +706,7 @@ dict_destroy(dict_t *this) prev = pair; } + this->totkvlen = 0; if (this->members != &this->members_internal) { mem_put(this->members); } @@ -1105,117 +1111,146 @@ data_to_int64(data_t *data) { VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1); - return (int64_t)strtoull(data->data, NULL, 0); + char *endptr = NULL; + int64_t value = 0; + + errno = 0; + value = strtoll(data->data, &endptr, 0); + + if (endptr && *endptr != '\0') + /* Unrecognized characters at the end of string. */ + errno = EINVAL; + if (errno) { + gf_msg_callingfn("dict", GF_LOG_WARNING, errno, + LG_MSG_DATA_CONVERSION_ERROR, + "Error in data conversion: '%s' can't " + "be represented as int64_t", + data->data); + return -1; + } + return value; } +/* Like above but implies signed range check. */ + +#define DATA_TO_RANGED_SIGNED(endptr, value, data, type, min, max) \ + do { \ + errno = 0; \ + value = strtoll(data->data, &endptr, 0); \ + if (endptr && *endptr != '\0') \ + errno = EINVAL; \ + if (errno || value > max || value < min) { \ + gf_msg_callingfn("dict", GF_LOG_WARNING, errno, \ + LG_MSG_DATA_CONVERSION_ERROR, \ + "Error in data conversion: '%s' can't " \ + "be represented as " #type, \ + data->data); \ + return -1; \ + } \ + return (type)value; \ + } while (0) + int32_t data_to_int32(data_t *data) { - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1); + char *endptr = NULL; + int64_t value = 0; - return strtoul(data->data, NULL, 0); + VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1); + DATA_TO_RANGED_SIGNED(endptr, value, data, int32_t, INT_MIN, INT_MAX); } int16_t data_to_int16(data_t *data) { - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1); + char *endptr = NULL; + int64_t value = 0; - int16_t value = 0; - - errno = 0; - value = strtol(data->data, NULL, 0); - - if ((value > SHRT_MAX) || (value < SHRT_MIN)) { - errno = ERANGE; - gf_msg_callingfn("dict", GF_LOG_WARNING, errno, - LG_MSG_DATA_CONVERSION_ERROR, - "Error in data" - " conversion: detected overflow"); - return -1; - } - - return (int16_t)value; + VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1); + DATA_TO_RANGED_SIGNED(endptr, value, data, int16_t, SHRT_MIN, SHRT_MAX); } int8_t data_to_int8(data_t *data) { + char *endptr = NULL; + int64_t value = 0; + VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1); + DATA_TO_RANGED_SIGNED(endptr, value, data, int8_t, CHAR_MIN, CHAR_MAX); +} + +uint64_t +data_to_uint64(data_t *data) +{ + VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); - int8_t value = 0; + char *endptr = NULL; + uint64_t value = 0; errno = 0; - value = strtol(data->data, NULL, 0); + value = strtoull(data->data, &endptr, 0); - if ((value > SCHAR_MAX) || (value < SCHAR_MIN)) { - errno = ERANGE; + if (endptr && *endptr != '\0') + errno = EINVAL; + if (errno) { gf_msg_callingfn("dict", GF_LOG_WARNING, errno, LG_MSG_DATA_CONVERSION_ERROR, - "Error in data" - " conversion: detected overflow"); + "Error in data conversion: '%s' can't " + "be represented as uint64_t", + data->data); return -1; } - - return (int8_t)value; + return value; } -uint64_t -data_to_uint64(data_t *data) -{ - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); +/* Like above but implies unsigned range check. */ - return strtoll(data->data, NULL, 0); -} +#define DATA_TO_RANGED_UNSIGNED(endptr, value, data, type, max) \ + do { \ + errno = 0; \ + value = strtoull(data->data, &endptr, 0); \ + if (endptr && *endptr != '\0') \ + errno = EINVAL; \ + if (errno || value > max) { \ + gf_msg_callingfn("dict", GF_LOG_WARNING, errno, \ + LG_MSG_DATA_CONVERSION_ERROR, \ + "Error in data conversion: '%s' can't " \ + "be represented as " #type, \ + data->data); \ + return -1; \ + } \ + return (type)value; \ + } while (0) uint32_t data_to_uint32(data_t *data) { - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); + char *endptr = NULL; + uint64_t value = 0; - return strtol(data->data, NULL, 0); + VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); + DATA_TO_RANGED_UNSIGNED(endptr, value, data, uint32_t, UINT_MAX); } uint16_t data_to_uint16(data_t *data) { - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); - - uint16_t value = 0; - - errno = 0; - value = strtol(data->data, NULL, 0); - - if ((USHRT_MAX - value) < 0) { - errno = ERANGE; - gf_msg_callingfn("dict", GF_LOG_WARNING, errno, - LG_MSG_DATA_CONVERSION_ERROR, - "Error in data conversion: " - "overflow detected"); - return -1; - } + char *endptr = NULL; + uint64_t value = 0; - return (uint16_t)value; + VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); + DATA_TO_RANGED_UNSIGNED(endptr, value, data, uint16_t, USHRT_MAX); } uint8_t data_to_uint8(data_t *data) { - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); - - errno = 0; - uint32_t value = strtol(data->data, NULL, 0); - - if ((UCHAR_MAX - (uint8_t)value) < 0) { - errno = ERANGE; - gf_msg_callingfn("dict", GF_LOG_WARNING, errno, - LG_MSG_DATA_CONVERSION_ERROR, - "data " - "conversion overflow detected"); - return -1; - } + char *endptr = NULL; + uint64_t value = 0; - return (uint8_t)value; + VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); + DATA_TO_RANGED_UNSIGNED(endptr, value, data, uint8_t, UCHAR_MAX); } char * @@ -1249,8 +1284,8 @@ data_to_iatt(data_t *data, char *key) * pass more data but are backward compatible (if the initial contents * of the struct are maintained, of course). */ if (data->len < sizeof(struct iatt)) { - gf_msg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF, - "data value for '%s' is smaller than expected", key); + gf_smsg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF, + "key=%s", key, NULL); return NULL; } @@ -1267,8 +1302,8 @@ int dict_remove_foreach_fn(dict_t *d, char *k, data_t *v, void *_tmp) { if (!d || !k) { - gf_msg("glusterfs", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ENTRY, - "%s is NULL", d ? "key" : "dictionary"); + gf_smsg("glusterfs", GF_LOG_WARNING, EINVAL, LG_MSG_KEY_OR_VALUE_NULL, + "d=%s", d ? "key" : "dictionary", NULL); return -1; } @@ -1460,32 +1495,13 @@ fail: * -val error, val = errno */ -int -dict_get_with_ref(dict_t *this, char *key, data_t **data) -{ - if (!this || !key || !data) { - gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG, - "dict OR key (%s) is NULL", key); - return -EINVAL; - } - - return dict_get_with_refn(this, key, strlen(key), data); -} - -int +static int dict_get_with_refn(dict_t *this, char *key, const int keylen, data_t **data) { data_pair_t *pair = NULL; int ret = -ENOENT; uint32_t hash; - if (!this || !key || !data) { - gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG, - "dict OR key (%s) is NULL", key); - ret = -EINVAL; - goto err; - } - hash = (uint32_t)XXH64(key, keylen, 0); LOCK(&this->lock); @@ -1498,10 +1514,22 @@ dict_get_with_refn(dict_t *this, char *key, const int keylen, data_t **data) } } UNLOCK(&this->lock); -err: + return ret; } +int +dict_get_with_ref(dict_t *this, char *key, data_t **data) +{ + if (!this || !key || !data) { + gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG, + "dict OR key (%s) is NULL", key); + return -EINVAL; + } + + return dict_get_with_refn(this, key, strlen(key), data); +} + static int data_to_ptr_common(data_t *data, void **val) { @@ -1675,7 +1703,7 @@ dict_get_int8(dict_t *this, char *key, int8_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1721,7 +1749,7 @@ dict_get_int16(dict_t *this, char *key, int16_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1793,7 +1821,7 @@ dict_get_int32(dict_t *this, char *key, int32_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1858,7 +1886,7 @@ dict_get_int64(dict_t *this, char *key, int64_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1903,7 +1931,7 @@ dict_get_uint16(dict_t *this, char *key, uint16_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1948,7 +1976,7 @@ dict_get_uint32(dict_t *this, char *key, uint32_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1993,7 +2021,7 @@ dict_get_uint64(dict_t *this, char *key, uint64_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -2103,8 +2131,8 @@ _dict_modify_flag(dict_t *this, char *key, int flag, int op) } else { ptr = GF_CALLOC(1, DICT_MAX_FLAGS / 8, gf_common_mt_char); if (!ptr) { - gf_msg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, - "unable to allocate flag bit array"); + gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, + "flag bit array", NULL); ret = -ENOMEM; goto err; } @@ -2112,8 +2140,8 @@ _dict_modify_flag(dict_t *this, char *key, int flag, int op) data = data_from_dynptr(ptr, DICT_MAX_FLAGS / 8); if (!data) { - gf_msg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, - "unable to allocate data"); + gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, "data", + NULL); GF_FREE(ptr); ret = -ENOMEM; goto err; @@ -2127,8 +2155,8 @@ _dict_modify_flag(dict_t *this, char *key, int flag, int op) if (this->free_pair.key) { /* the free pair is in use */ pair = mem_get0(THIS->ctx->dict_pair_pool); if (!pair) { - gf_msg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, - "unable to allocate dict pair"); + gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, + "dict pair", NULL); ret = -ENOMEM; goto err; } @@ -2138,15 +2166,15 @@ _dict_modify_flag(dict_t *this, char *key, int flag, int op) pair->key = (char *)GF_MALLOC(strlen(key) + 1, gf_common_mt_char); if (!pair->key) { - gf_msg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, - "unable to allocate dict pair"); + gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, + "dict pair", NULL); ret = -ENOMEM; goto err; } strcpy(pair->key, key); pair->key_hash = hash; pair->value = data_ref(data); - + this->totkvlen += (strlen(key) + 1 + data->len); hashval = hash % this->hash_size; pair->hash_next = this->members[hashval]; this->members[hashval] = pair; @@ -2183,8 +2211,8 @@ err: if (data) data_destroy(data); - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_DICT_SET_FAILED, - "unable to set key (%s) in dict ", key); + gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_DICT_SET_FAILED, "key=%s", key, + NULL); return ret; } @@ -2216,7 +2244,7 @@ dict_get_double(dict_t *this, char *key, double *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -2299,7 +2327,7 @@ dict_get_ptr(dict_t *this, char *key, void **ptr) data_t *data = NULL; int ret = 0; - if (!this || !key || !ptr) { + if (!ptr) { ret = -EINVAL; goto err; } @@ -2329,7 +2357,7 @@ dict_get_ptr_and_len(dict_t *this, char *key, void **ptr, int *len) data_t *data = NULL; int ret = 0; - if (!this || !key || !ptr) { + if (!ptr) { ret = -EINVAL; goto err; } @@ -2387,7 +2415,7 @@ dict_get_str(dict_t *this, char *key, char **str) data_t *data = NULL; int ret = -EINVAL; - if (!this || !key || !str) { + if (!str) { goto err; } ret = dict_get_with_ref(this, key, &data); @@ -2561,7 +2589,7 @@ dict_get_bin(dict_t *this, char *key, void **bin) data_t *data = NULL; int ret = -EINVAL; - if (!this || !key || !bin) { + if (!bin) { goto err; } @@ -2664,7 +2692,7 @@ dict_get_gfuuid(dict_t *this, char *key, uuid_t *gfid) data_t *data = NULL; int ret = -EINVAL; - if (!this || !key || !gfid) { + if (!gfid) { goto err; } ret = dict_get_with_ref(this, key, &data); @@ -2697,7 +2725,7 @@ dict_get_mdata(dict_t *this, char *key, struct mdata_iatt *mdata) data_t *data = NULL; int ret = -EINVAL; - if (!this || !key || !mdata) { + if (!mdata) { goto err; } ret = dict_get_with_ref(this, key, &data); @@ -2707,8 +2735,8 @@ dict_get_mdata(dict_t *this, char *key, struct mdata_iatt *mdata) VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_MDATA, key, -EINVAL); if (data->len < sizeof(struct mdata_iatt)) { - gf_msg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF, - "data value for '%s' is smaller than expected", key); + gf_smsg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF, + "key=%s", key, NULL); ret = -ENOBUFS; goto err; } @@ -2735,7 +2763,7 @@ dict_get_iatt(dict_t *this, char *key, struct iatt *iatt) data_t *data = NULL; int ret = -EINVAL; - if (!this || !key || !iatt) { + if (!iatt) { goto err; } ret = dict_get_with_ref(this, key, &data); @@ -2872,53 +2900,15 @@ dict_serialized_length_lk(dict_t *this) { int ret = -EINVAL; int count = this->count; - int len = DICT_HDR_LEN; - data_pair_t *pair = this->members_list; + const int keyhdrlen = DICT_DATA_HDR_KEY_LEN + DICT_DATA_HDR_VAL_LEN; if (count < 0) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_COUNT_LESS_THAN_ZERO, - "count (%d) < 0!", count); + gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_COUNT_LESS_THAN_ZERO, + "count=%d", count, NULL); goto out; } - while (count) { - if (!pair) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, - LG_MSG_COUNT_LESS_THAN_DATA_PAIRS, - "less than count data pairs found!"); - goto out; - } - - len += DICT_DATA_HDR_KEY_LEN + DICT_DATA_HDR_VAL_LEN; - - if (!pair->key) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_NULL_PTR, - "pair->key is null!"); - goto out; - } - - len += strlen(pair->key) + 1 /* for '\0' */; - - if (!pair->value) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_NULL_PTR, - "pair->value is null!"); - goto out; - } - - if (pair->value->len < 0) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, - LG_MSG_VALUE_LENGTH_LESS_THAN_ZERO, "value->len (%d) < 0", - pair->value->len); - goto out; - } - - len += pair->value->len; - - pair = pair->next; - count--; - } - - ret = len; + ret = DICT_HDR_LEN + this->totkvlen + (count * keyhdrlen); out: return ret; } @@ -2945,14 +2935,13 @@ dict_serialize_lk(dict_t *this, char *buf) int32_t netword = 0; if (!buf) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, - "buf is null!"); + gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, NULL); goto out; } if (count < 0) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO, - "count (%d) < 0!", count); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO, + "count=%d", count, NULL); goto out; } @@ -2962,14 +2951,13 @@ dict_serialize_lk(dict_t *this, char *buf) while (count) { if (!pair) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_PAIRS_LESS_THAN_COUNT, - "less than count data pairs found!"); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_PAIRS_LESS_THAN_COUNT, + NULL); goto out; } if (!pair->key) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, - "pair->key is null!"); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, NULL); goto out; } @@ -2979,8 +2967,7 @@ dict_serialize_lk(dict_t *this, char *buf) buf += DICT_DATA_HDR_KEY_LEN; if (!pair->value) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, - "pair->value is null!"); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, NULL); goto out; } @@ -3128,8 +3115,8 @@ dict_unserialize(char *orig_buf, int32_t size, dict_t **fill) buf += DICT_HDR_LEN; if (count < 0) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO, - "count (%d) <= 0", count); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO, + "count=%d", count, NULL); goto out; } @@ -3285,32 +3272,30 @@ dict_serialize_value_with_delim_lk(dict_t *this, char *buf, int32_t *serz_len, data_pair_t *pair = this->members_list; if (!buf) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, "buf is null"); + gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, NULL); goto out; } if (count < 0) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, - "count (%d) < 0", count); + gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, "count=%d", + count, NULL); goto out; } while (count) { if (!pair) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_PAIRS_LESS_THAN_COUNT, - "less than count data pairs found"); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_PAIRS_LESS_THAN_COUNT, + NULL); goto out; } if (!pair->key || !pair->value) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_KEY_OR_VALUE_NULL, - "key or value is null"); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_KEY_OR_VALUE_NULL, NULL); goto out; } if (!pair->value->data) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_VALUE_IN_DICT, - "null value found in dict"); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_VALUE_IN_DICT, NULL); goto out; } @@ -3402,12 +3387,11 @@ dict_dump_to_log(dict_t *dict) ret = dict_dump_to_str(dict, dump, dump_size, format); if (ret) { - gf_msg("dict", GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, - "Failed to log dictionary"); + gf_smsg("dict", GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, NULL); goto out; } - gf_msg("dict", GF_LOG_INFO, 0, LG_MSG_DICT_ERROR, "dict=%p (%s)", dict, - dump); + gf_smsg("dict", GF_LOG_INFO, 0, LG_MSG_DICT_ERROR, "dict=%p", dict, + "dump=%s", dump, NULL); out: GF_FREE(dump); @@ -3440,8 +3424,8 @@ dict_dump_to_statedump(dict_t *dict, char *dict_name, char *domain) ret = dict_dump_to_str(dict, dump, dump_size, format); if (ret) { - gf_msg(domain, GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, - "Failed to log dictionary %s", dict_name); + gf_smsg(domain, GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, "name=%s", + dict_name, NULL); goto out; } gf_proc_dump_build_key(key, domain, "%s", dict_name); diff --git a/libglusterfs/src/event-epoll.c b/libglusterfs/src/event-epoll.c index bfe2648a920..fb4fb845b40 100644 --- a/libglusterfs/src/event-epoll.c +++ b/libglusterfs/src/event-epoll.c @@ -296,9 +296,8 @@ event_pool_new_epoll(int count, int eventthreadcount) epfd = epoll_create(count); if (epfd == -1) { - gf_msg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_CREATE_FAILED, - "epoll fd creation " - "failed"); + gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_CREATE_FAILED, + NULL); GF_FREE(event_pool->reg); GF_FREE(event_pool); event_pool = NULL; @@ -332,8 +331,8 @@ __slot_update_events(struct event_slot_epoll *slot, int poll_in, int poll_out) /* do nothing */ break; default: - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN, - "invalid poll_in value %d", poll_in); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN, + "value=%d", poll_in, NULL); break; } @@ -348,8 +347,8 @@ __slot_update_events(struct event_slot_epoll *slot, int poll_in, int poll_out) /* do nothing */ break; default: - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT, - "invalid poll_out value %d", poll_out); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT, + "value=%d", poll_out, NULL); break; } } @@ -390,8 +389,8 @@ event_register_epoll(struct event_pool *event_pool, int fd, idx = event_slot_alloc(event_pool, fd, notify_poller_death, &slot); if (idx == -1) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, - "could not find slot for fd=%d", fd); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd, + NULL); return -1; } @@ -426,10 +425,8 @@ event_register_epoll(struct event_pool *event_pool, int fd, UNLOCK(&slot->lock); if (ret == -1) { - gf_msg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_ADD_FAILED, - "failed to add fd(=%d) to " - "epoll fd(=%d)", - fd, event_pool->fd); + gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_ADD_FAILED, + "fd=%d", fd, "epoll_fd=%d", event_pool->fd, NULL); event_slot_unref(event_pool, slot, idx); idx = -1; } @@ -458,8 +455,8 @@ event_unregister_epoll_common(struct event_pool *event_pool, int fd, int idx, slot = event_slot_get(event_pool, idx); if (!slot) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, - "could not find slot for fd=%d idx=%d", fd, idx); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd, + "idx=%d", idx, NULL); return -1; } @@ -470,10 +467,8 @@ event_unregister_epoll_common(struct event_pool *event_pool, int fd, int idx, ret = epoll_ctl(event_pool->fd, EPOLL_CTL_DEL, fd, NULL); if (ret == -1) { - gf_msg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_DEL_FAILED, - "fail to del " - "fd(=%d) from epoll fd(=%d)", - fd, event_pool->fd); + gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_DEL_FAILED, + "fd=%d", fd, "epoll_fd=%d", event_pool->fd, NULL); goto unlock; } @@ -525,8 +520,8 @@ event_select_on_epoll(struct event_pool *event_pool, int fd, int idx, slot = event_slot_get(event_pool, idx); if (!slot) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, - "could not find slot for fd=%d idx=%d", fd, idx); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd, + "idx=%d", idx, NULL); return -1; } @@ -557,10 +552,8 @@ event_select_on_epoll(struct event_pool *event_pool, int fd, int idx, ret = epoll_ctl(event_pool->fd, EPOLL_CTL_MOD, fd, &epoll_event); if (ret == -1) { - gf_msg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_MODIFY_FAILED, - "failed to " - "modify fd(=%d) events to %d", - fd, epoll_event.events); + gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_MODIFY_FAILED, + "fd=%d", fd, "events=%d", epoll_event.events, NULL); } } unlock: @@ -595,8 +588,8 @@ event_dispatch_epoll_handler(struct event_pool *event_pool, slot = event_slot_get(event_pool, idx); if (!slot) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, - "could not find slot for idx=%d", idx); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "idx=%d", idx, + NULL); return -1; } @@ -604,20 +597,17 @@ event_dispatch_epoll_handler(struct event_pool *event_pool, { fd = slot->fd; if (fd == -1) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_STALE_FD_FOUND, - "stale fd found on " - "idx=%d, gen=%d, events=%d, slot->gen=%d", - idx, gen, event->events, slot->gen); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_STALE_FD_FOUND, "idx=%d", + idx, "gen=%d", gen, "events=%d", event->events, + "slot->gen=%d", slot->gen, NULL); /* fd got unregistered in another thread */ goto pre_unlock; } if (gen != slot->gen) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_GENERATION_MISMATCH, - "generation " - "mismatch on idx=%d, gen=%d, slot->gen=%d, " - "slot->fd=%d", - idx, gen, slot->gen, slot->fd); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_GENERATION_MISMATCH, + "idx=%d", idx, "gen=%d", gen, "slot->gen=%d", slot->gen, + "slot->fd=%d", slot->fd, NULL); /* slot was re-used and therefore is another fd! */ goto pre_unlock; } @@ -676,10 +666,8 @@ event_dispatch_epoll_worker(void *data) GF_VALIDATE_OR_GOTO("event", event_pool, out); - gf_msg("epoll", GF_LOG_INFO, 0, LG_MSG_STARTED_EPOLL_THREAD, - "Started" - " thread with index %d", - myindex - 1); + gf_smsg("epoll", GF_LOG_INFO, 0, LG_MSG_STARTED_EPOLL_THREAD, "index=%d", + myindex - 1, NULL); pthread_mutex_lock(&event_pool->mutex); { @@ -743,8 +731,8 @@ event_dispatch_epoll_worker(void *data) } pthread_mutex_unlock(&event_pool->mutex); - gf_msg("epoll", GF_LOG_INFO, 0, LG_MSG_EXITED_EPOLL_THREAD, - "Exited thread with index %d", myindex); + gf_smsg("epoll", GF_LOG_INFO, 0, LG_MSG_EXITED_EPOLL_THREAD, + "index=%d", myindex, NULL); goto out; } @@ -762,8 +750,8 @@ event_dispatch_epoll_worker(void *data) ret = event_dispatch_epoll_handler(event_pool, &event); if (ret) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_EXITED_EPOLL_THREAD, - "Failed to dispatch handler"); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_DISPATCH_HANDLER_FAILED, + NULL); } } out: @@ -827,9 +815,8 @@ event_dispatch_epoll(struct event_pool *event_pool) if (i != 0) pthread_detach(event_pool->pollers[i]); } else { - gf_msg("epoll", GF_LOG_WARNING, 0, - LG_MSG_START_EPOLL_THREAD_FAILED, - "Failed to start thread for index %d", i); + gf_smsg("epoll", GF_LOG_WARNING, 0, + LG_MSG_START_EPOLL_THREAD_FAILED, "index=%d", i, NULL); if (i == 0) { GF_FREE(ev_data); break; @@ -922,11 +909,9 @@ event_reconfigure_threads_epoll(struct event_pool *event_pool, int value) event_dispatch_epoll_worker, ev_data, "epoll%03hx", i & 0x3ff); if (ret) { - gf_msg("epoll", GF_LOG_WARNING, 0, - LG_MSG_START_EPOLL_THREAD_FAILED, - "Failed to start thread" - " for index %d", - i); + gf_smsg("epoll", GF_LOG_WARNING, 0, + LG_MSG_START_EPOLL_THREAD_FAILED, "index=%d", i, + NULL); GF_FREE(ev_data); } else { pthread_detach(t_id); @@ -989,8 +974,8 @@ event_handled_epoll(struct event_pool *event_pool, int fd, int idx, int gen) slot = event_slot_get(event_pool, idx); if (!slot) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, - "could not find slot for fd=%d idx=%d", fd, idx); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd, + "idx=%d", idx, NULL); return -1; } diff --git a/libglusterfs/src/event-poll.c b/libglusterfs/src/event-poll.c index 14dc5e3180c..2cba963f096 100644 --- a/libglusterfs/src/event-poll.c +++ b/libglusterfs/src/event-poll.c @@ -48,10 +48,8 @@ __flush_fd(int fd, int idx, int gen, void *data, int poll_in, int poll_out, do { ret = sys_read(fd, buf, 64); if (ret == -1 && errno != EAGAIN) { - gf_msg("poll", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, - "read on %d returned " - "error", - fd); + gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_READ_FILE_FAILED, + "fd=%d", fd, NULL); } } while (ret == 64); @@ -111,8 +109,7 @@ event_pool_new_poll(int count, int eventthreadcount) ret = pipe(event_pool->breaker); if (ret == -1) { - gf_msg("poll", GF_LOG_ERROR, errno, LG_MSG_PIPE_CREATE_FAILED, - "pipe creation failed"); + gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_PIPE_CREATE_FAILED, NULL); GF_FREE(event_pool->reg); GF_FREE(event_pool); return NULL; @@ -120,8 +117,7 @@ event_pool_new_poll(int count, int eventthreadcount) ret = fcntl(event_pool->breaker[0], F_SETFL, O_NONBLOCK); if (ret == -1) { - gf_msg("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED, - "could not set pipe to non blocking mode"); + gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED, NULL); sys_close(event_pool->breaker[0]); sys_close(event_pool->breaker[1]); event_pool->breaker[0] = event_pool->breaker[1] = -1; @@ -133,8 +129,7 @@ event_pool_new_poll(int count, int eventthreadcount) ret = fcntl(event_pool->breaker[1], F_SETFL, O_NONBLOCK); if (ret == -1) { - gf_msg("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED, - "could not set pipe to non blocking mode"); + gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED, NULL); sys_close(event_pool->breaker[0]); sys_close(event_pool->breaker[1]); @@ -148,8 +143,7 @@ event_pool_new_poll(int count, int eventthreadcount) ret = event_register_poll(event_pool, event_pool->breaker[0], __flush_fd, NULL, 1, 0, 0); if (ret == -1) { - gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_REGISTER_PIPE_FAILED, - "could not register pipe fd with poll event loop"); + gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_REGISTER_PIPE_FAILED, NULL); sys_close(event_pool->breaker[0]); sys_close(event_pool->breaker[1]); event_pool->breaker[0] = event_pool->breaker[1] = -1; @@ -160,11 +154,8 @@ event_pool_new_poll(int count, int eventthreadcount) } if (eventthreadcount > 1) { - gf_msg("poll", GF_LOG_INFO, 0, LG_MSG_POLL_IGNORE_MULTIPLE_THREADS, - "Currently poll " - "does not use multiple event processing threads, " - "thread count (%d) ignored", - eventthreadcount); + gf_smsg("poll", GF_LOG_INFO, 0, LG_MSG_POLL_IGNORE_MULTIPLE_THREADS, + "count=%d", eventthreadcount, NULL); } /* although, eventhreadcount for poll implementation is always @@ -215,8 +206,8 @@ event_register_poll(struct event_pool *event_pool, int fd, /* do nothing */ break; default: - gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN, - "invalid poll_in value %d", poll_in); + gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN, + "value=%d", poll_in, NULL); break; } @@ -231,8 +222,8 @@ event_register_poll(struct event_pool *event_pool, int fd, /* do nothing */ break; default: - gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT, - "invalid poll_out value %d", poll_out); + gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT, + "value=%d", poll_out, NULL); break; } @@ -257,8 +248,8 @@ event_unregister_poll(struct event_pool *event_pool, int fd, int idx_hint) idx = __event_getindex(event_pool, fd, idx_hint); if (idx == -1) { - gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, - "index not found for fd=%d (idx_hint=%d)", fd, idx_hint); + gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "fd=%d", + fd, "idx_hint=%d", idx_hint, NULL); errno = ENOENT; goto unlock; } @@ -298,8 +289,8 @@ event_select_on_poll(struct event_pool *event_pool, int fd, int idx_hint, idx = __event_getindex(event_pool, fd, idx_hint); if (idx == -1) { - gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, - "index not found for fd=%d (idx_hint=%d)", fd, idx_hint); + gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "fd=%d", + fd, "idx_hint=%d", idx_hint, NULL); errno = ENOENT; goto unlock; } @@ -361,10 +352,8 @@ event_dispatch_poll_handler(struct event_pool *event_pool, struct pollfd *ufds, idx = __event_getindex(event_pool, ufds[i].fd, i); if (idx == -1) { - gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, - "index not found for " - "fd=%d (idx_hint=%d)", - ufds[i].fd, i); + gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "fd=%d", + ufds[i].fd, "idx_hint=%d", i, NULL); goto unlock; } diff --git a/libglusterfs/src/event.c b/libglusterfs/src/event.c index 235128b6044..402c253ca25 100644 --- a/libglusterfs/src/event.c +++ b/libglusterfs/src/event.c @@ -17,6 +17,7 @@ #include <string.h> #include "glusterfs/gf-event.h" +#include "glusterfs/timespec.h" #include "glusterfs/common-utils.h" #include "glusterfs/libglusterfs-messages.h" #include "glusterfs/syscall.h" @@ -266,7 +267,7 @@ gf_event_dispatch_destroy(struct event_pool *event_pool) if (sys_write(fd[1], "dummy", 6) == -1) { break; } - clock_gettime(CLOCK_REALTIME, &sleep_till); + timespec_now_realtime(&sleep_till); sleep_till.tv_sec += 1; ret = pthread_cond_timedwait(&event_pool->cond, &event_pool->mutex, &sleep_till); diff --git a/libglusterfs/src/events.c b/libglusterfs/src/events.c index 6d1e3836477..33157549897 100644 --- a/libglusterfs/src/events.c +++ b/libglusterfs/src/events.c @@ -40,6 +40,7 @@ _gf_event(eventtypes_t event, const char *fmt, ...) char *host = NULL; struct addrinfo hints; struct addrinfo *result = NULL; + struct addrinfo *iter_result_ptr = NULL; xlator_t *this = THIS; char *volfile_server_transport = NULL; @@ -51,13 +52,6 @@ _gf_event(eventtypes_t event, const char *fmt, ...) goto out; } - /* Initialize UDP socket */ - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - ret = EVENT_ERROR_SOCKET; - goto out; - } - if (ctx) { volfile_server_transport = ctx->cmd_args.volfile_server_transport; } @@ -66,7 +60,6 @@ _gf_event(eventtypes_t event, const char *fmt, ...) } /* host = NULL returns localhost */ - host = NULL; if (ctx && ctx->cmd_args.volfile_server && (strcmp(volfile_server_transport, "unix"))) { /* If it is client code then volfile_server is set @@ -84,6 +77,24 @@ _gf_event(eventtypes_t event, const char *fmt, ...) goto out; } + // iterate over the result and break when socket creation is success. + for (iter_result_ptr = result; iter_result_ptr != NULL; + iter_result_ptr = iter_result_ptr->ai_next) { + sock = socket(iter_result_ptr->ai_family, iter_result_ptr->ai_socktype, + iter_result_ptr->ai_protocol); + if (sock != -1) { + break; + } + } + /* + * If none of the addrinfo structures lead to a successful socket + * creation, socket creation has failed. + */ + if (sock < 0) { + ret = EVENT_ERROR_SOCKET; + goto out; + } + va_start(arguments, fmt); ret = gf_vasprintf(&msg, fmt, arguments); va_end(arguments); @@ -93,7 +104,7 @@ _gf_event(eventtypes_t event, const char *fmt, ...) goto out; } - ret = gf_asprintf(&eventstr, "%u %d %s", (unsigned)time(NULL), event, msg); + ret = gf_asprintf(&eventstr, "%u %d %s", (unsigned)gf_time(), event, msg); GF_FREE(msg); if (ret <= 0) { ret = EVENT_ERROR_MSG_FORMAT; diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c index e0767a7e61f..62606e91164 100644 --- a/libglusterfs/src/fd.c +++ b/libglusterfs/src/fd.c @@ -502,6 +502,32 @@ out: } void +fd_close(fd_t *fd) +{ + xlator_t *xl, *old_THIS; + + old_THIS = THIS; + + for (xl = fd->inode->table->xl->graph->first; xl != NULL; xl = xl->next) { + if (!xl->call_cleanup) { + THIS = xl; + + if (IA_ISDIR(fd->inode->ia_type)) { + if (xl->cbks->fdclosedir != NULL) { + xl->cbks->fdclosedir(xl, fd); + } + } else { + if (xl->cbks->fdclose != NULL) { + xl->cbks->fdclose(xl, fd); + } + } + } + } + + THIS = old_THIS; +} + +void fd_unref(fd_t *fd) { int32_t refcount = 0; diff --git a/libglusterfs/src/gf-dirent.c b/libglusterfs/src/gf-dirent.c index 9c8c74beb54..a809efc97ef 100644 --- a/libglusterfs/src/gf-dirent.c +++ b/libglusterfs/src/gf-dirent.c @@ -276,7 +276,7 @@ gf_fill_iatt_for_dirent(gf_dirent_t *entry, inode_t *parent, xlator_t *subvol) gf_uuid_copy(loc.pargfid, parent->gfid); loc.name = entry->d_name; loc.parent = inode_ref(parent); - ret = inode_path(loc.inode, entry->d_name, &path); + ret = inode_path(loc.parent, entry->d_name, &path); loc.path = path; if (ret < 0) goto out; diff --git a/libglusterfs/src/gidcache.c b/libglusterfs/src/gidcache.c index 40fcffbb35e..64a93802f76 100644 --- a/libglusterfs/src/gidcache.c +++ b/libglusterfs/src/gidcache.c @@ -10,6 +10,7 @@ #include "glusterfs/gidcache.h" #include "glusterfs/mem-pool.h" +#include "glusterfs/common-utils.h" /* * We treat this as a very simple set-associative LRU cache, with entries aged @@ -64,7 +65,7 @@ gid_cache_lookup(gid_cache_t *cache, uint64_t id, uint64_t uid, uint64_t gid) time_t now; const gid_list_t *agl; - now = time(NULL); + now = gf_time(); LOCK(&cache->gc_lock); bucket = id % cache->gc_nbuckets; agl = BUCKET_START(cache->gc_cache, bucket); @@ -132,7 +133,7 @@ gid_cache_add(gid_cache_t *cache, gid_list_t *gl) if (!cache->gc_max_age) return 0; - now = time(NULL); + now = gf_time(); LOCK(&cache->gc_lock); /* diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c index 63b6358bbe0..ae06f8be386 100644 --- a/libglusterfs/src/globals.c +++ b/libglusterfs/src/globals.c @@ -314,7 +314,18 @@ glusterfs_cleanup(void *ptr) GF_FREE(thread_syncopctx.groups); } - mem_pool_thread_destructor(); + mem_pool_thread_destructor(NULL); +} + +void +gf_thread_needs_cleanup(void) +{ + /* The value stored in free_key TLS is not really used for anything, but + * pthread implementation doesn't call the TLS destruction function unless + * it's != NULL. This function must be called whenever something is + * allocated for this thread so that glusterfs_cleanup() will be called + * and resources can be released. */ + (void)pthread_setspecific(free_key, (void *)1); } static void diff --git a/libglusterfs/src/glusterfs/common-utils.h b/libglusterfs/src/glusterfs/common-utils.h index f6d82cc0b85..f297fdab5c9 100644 --- a/libglusterfs/src/glusterfs/common-utils.h +++ b/libglusterfs/src/glusterfs/common-utils.h @@ -18,6 +18,7 @@ #include <string.h> #include <assert.h> #include <pthread.h> +#include <unistd.h> #include <openssl/md5.h> #ifndef GF_BSD_HOST_OS #include <alloca.h> @@ -26,6 +27,11 @@ #include <fnmatch.h> #include <uuid/uuid.h> +/* FreeBSD, etc. */ +#ifndef __BITS_PER_LONG +#define __BITS_PER_LONG (CHAR_BIT * (sizeof(long))) +#endif + #ifndef ffsll #define ffsll(x) __builtin_ffsll(x) #endif @@ -123,6 +129,7 @@ trap(void); /* Default value of signing waiting time to sign a file for bitrot */ #define SIGNING_TIMEOUT "120" +#define BR_WORKERS "4" /* xxhash */ #define GF_XXH64_DIGEST_LENGTH 8 @@ -147,6 +154,9 @@ trap(void); #define GF_THREAD_NAME_LIMIT 16 #define GF_THREAD_NAME_PREFIX "glfs_" +/* Advisory buffer size for formatted timestamps (see gf_time_fmt) */ +#define GF_TIMESTR_SIZE 256 + /* * we could have initialized these as +ve values and treated * them as negative while comparing etc.. (which would have @@ -166,7 +176,8 @@ enum _gf_special_pid { GF_CLIENT_PID_SCRUB = -9, GF_CLIENT_PID_TIER_DEFRAG = -10, GF_SERVER_PID_TRASH = -11, - GF_CLIENT_PID_ADD_REPLICA_MOUNT = -12 + GF_CLIENT_PID_ADD_REPLICA_MOUNT = -12, + GF_CLIENT_PID_SET_UTIME = -13, }; enum _gf_xlator_ipc_targets { @@ -178,6 +189,12 @@ enum _gf_xlator_ipc_targets { typedef enum _gf_special_pid gf_special_pid_t; typedef enum _gf_xlator_ipc_targets _gf_xlator_ipc_targets_t; +/* Array to hold custom xattr keys */ +extern char *xattrs_to_heal[]; + +char ** +get_xattrs_to_heal(); + /* The DHT file rename operation is not a straightforward rename. * It involves creating linkto and linkfiles, and can unlink or rename the * source file depending on the hashed and cached subvols for the source @@ -238,6 +255,8 @@ list_node_del(struct list_node *node); struct dnscache * gf_dnscache_init(time_t ttl); +void +gf_dnscache_deinit(struct dnscache *cache); struct dnscache_entry * gf_dnscache_entry_init(void); void @@ -436,6 +455,15 @@ BIT_VALUE(unsigned char *array, unsigned int index) } while (0) #endif +/* Compile-time assert, borrowed from Linux kernel. */ +#ifdef HAVE_STATIC_ASSERT +#define GF_STATIC_ASSERT(expr, ...) \ + __gf_static_assert(expr, ##__VA_ARGS__, #expr) +#define __gf_static_assert(expr, msg, ...) _Static_assert(expr, msg) +#else +#define GF_STATIC_ASSERT(expr, ...) +#endif + #define GF_ABORT(msg...) \ do { \ gf_msg_callingfn("", GF_LOG_CRITICAL, 0, LG_MSG_ASSERTION_FAILED, \ @@ -466,18 +494,15 @@ union gf_sock_union { #define IOV_MIN(n) min(IOV_MAX, n) -#define GF_SKIP_IRRELEVANT_ENTRIES(entry, dir, scr) \ - do { \ - entry = NULL; \ - if (dir) { \ - entry = sys_readdir(dir, scr); \ - while (entry && (!strcmp(entry->d_name, ".") || \ - !fnmatch("*.tmp", entry->d_name, 0) || \ - !strcmp(entry->d_name, ".."))) { \ - entry = sys_readdir(dir, scr); \ - } \ - } \ - } while (0) +static inline gf_boolean_t +gf_irrelevant_entry(struct dirent *entry) +{ + GF_ASSERT(entry); + + return (!strcmp(entry->d_name, ".") || + !fnmatch("*.tmp", entry->d_name, 0) || + !strcmp(entry->d_name, "..")); +} static inline void iov_free(struct iovec *vector, int count) @@ -788,7 +813,7 @@ typedef enum { } gf_timefmts; static inline char * -gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) +gf_time_fmt_tv(char *dst, size_t sz_dst, struct timeval *tv, unsigned int fmt) { extern void _gf_timestuff(const char ***, const char ***); static gf_timefmts timefmt_last = (gf_timefmts)-1; @@ -796,6 +821,8 @@ gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) static const char **zeros; struct tm tm, *res; int localtime = 0; + int len = 0; + int pos = 0; if (timefmt_last == ((gf_timefmts)-1)) { _gf_timestuff(&fmts, &zeros); @@ -805,15 +832,35 @@ gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) fmt = gf_timefmt_default; } localtime = gf_log_get_localtime(); - res = localtime ? localtime_r(&utime, &tm) : gmtime_r(&utime, &tm); - if (utime && (res != NULL)) { - strftime(dst, sz_dst, fmts[fmt], &tm); + res = localtime ? localtime_r(&tv->tv_sec, &tm) + : gmtime_r(&tv->tv_sec, &tm); + if (tv->tv_sec && (res != NULL)) { + len = strftime(dst, sz_dst, fmts[fmt], &tm); + if (len == 0) + return dst; + pos += len; + if (tv->tv_usec >= 0) { + len = snprintf(dst + pos, sz_dst - pos, ".%" GF_PRI_SUSECONDS, + tv->tv_usec); + if (len >= sz_dst - pos) + return dst; + pos += len; + } + strftime(dst + pos, sz_dst - pos, " %z", &tm); } else { strncpy(dst, "N/A", sz_dst); } return dst; } +static inline char * +gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) +{ + struct timeval tv = {utime, -1}; + + return gf_time_fmt_tv(dst, sz_dst, &tv, fmt); +} + /* This function helps us use gfid (unique identity) to generate inode's unique * number in glusterfs. */ @@ -1163,6 +1210,47 @@ int gf_d_type_from_ia_type(ia_type_t type); int +gf_syncfs(int fd); + +int gf_nanosleep(uint64_t nsec); +static inline time_t +gf_time(void) +{ + return time(NULL); +} + +/* Return delta value in microseconds. */ + +static inline double +gf_tvdiff(struct timeval *start, struct timeval *end) +{ + struct timeval t; + + if (start->tv_usec > end->tv_usec) + t.tv_sec = end->tv_sec - 1, t.tv_usec = end->tv_usec + 1000000; + else + t.tv_sec = end->tv_sec, t.tv_usec = end->tv_usec; + + return (double)(t.tv_sec - start->tv_sec) * 1e6 + + (double)(t.tv_usec - start->tv_usec); +} + +/* Return delta value in nanoseconds. */ + +static inline double +gf_tsdiff(struct timespec *start, struct timespec *end) +{ + struct timespec t; + + if (start->tv_nsec > end->tv_nsec) + t.tv_sec = end->tv_sec - 1, t.tv_nsec = end->tv_nsec + 1000000000; + else + t.tv_sec = end->tv_sec, t.tv_nsec = end->tv_nsec; + + return (double)(t.tv_sec - start->tv_sec) * 1e9 + + (double)(t.tv_nsec - start->tv_nsec); +} + #endif /* _COMMON_UTILS_H */ diff --git a/libglusterfs/src/glusterfs/dict.h b/libglusterfs/src/glusterfs/dict.h index ce1c2100276..d0467c6dfb6 100644 --- a/libglusterfs/src/glusterfs/dict.h +++ b/libglusterfs/src/glusterfs/dict.h @@ -25,9 +25,6 @@ typedef struct _data_pair data_pair_t; #define dict_add_sizen(this, key, value) dict_addn(this, key, SLEN(key), value) -#define dict_get_with_ref_sizen(this, key, value) \ - dict_get_with_refn(this, key, SLEN(key), value) - #define dict_get_sizen(this, key) dict_getn(this, key, SLEN(key)) #define dict_del_sizen(this, key) dict_deln(this, key, SLEN(key)) @@ -98,7 +95,7 @@ struct _data { char *data; gf_atomic_t refcount; gf_dict_data_type_t data_type; - int32_t len; + uint32_t len; gf_boolean_t is_static; }; @@ -122,6 +119,8 @@ struct _dict { gf_lock_t lock; data_pair_t *members_internal; data_pair_t free_pair; + /* Variable to store total keylen + value->len */ + uint32_t totkvlen; }; typedef gf_boolean_t (*dict_match_t)(dict_t *d, char *k, data_t *v, void *data); @@ -136,6 +135,7 @@ int32_t dict_set(dict_t *this, char *key, data_t *value); int32_t dict_setn(dict_t *this, char *key, const int keylen, data_t *value); + /* function to set a new key/value pair (without checking for duplicate) */ int32_t dict_add(dict_t *this, char *key, data_t *value); @@ -143,8 +143,6 @@ int32_t dict_addn(dict_t *this, char *key, const int keylen, data_t *value); int dict_get_with_ref(dict_t *this, char *key, data_t **data); -int -dict_get_with_refn(dict_t *this, char *key, const int keylen, data_t **data); data_t * dict_get(dict_t *this, char *key); data_t * diff --git a/libglusterfs/src/glusterfs/fd.h b/libglusterfs/src/glusterfs/fd.h index 28906d34e4d..3ffaaa60504 100644 --- a/libglusterfs/src/glusterfs/fd.h +++ b/libglusterfs/src/glusterfs/fd.h @@ -106,6 +106,9 @@ fd_ref(fd_t *fd); void fd_unref(fd_t *fd); +void +fd_close(fd_t *fd); + fd_t * fd_create(struct _inode *inode, pid_t pid); diff --git a/libglusterfs/src/glusterfs/gf-event.h b/libglusterfs/src/glusterfs/gf-event.h index c0f05e7c83b..40f8fbdf10a 100644 --- a/libglusterfs/src/glusterfs/gf-event.h +++ b/libglusterfs/src/glusterfs/gf-event.h @@ -12,6 +12,7 @@ #define _GF_EVENT_H_ #include <pthread.h> +#include "common-utils.h" #include "list.h" struct event_pool; @@ -31,6 +32,9 @@ typedef void (*event_handler_t)(int fd, int idx, int gen, void *data, #define EVENT_EPOLL_SLOTS 1024 #define EVENT_MAX_THREADS 1024 +/* See rpcsvc.h to check why. */ +GF_STATIC_ASSERT(EVENT_MAX_THREADS % __BITS_PER_LONG == 0); + struct event_pool { struct event_ops *ops; diff --git a/libglusterfs/src/glusterfs/globals.h b/libglusterfs/src/glusterfs/globals.h index f0c7395b4cb..b22eaae6c2f 100644 --- a/libglusterfs/src/glusterfs/globals.h +++ b/libglusterfs/src/glusterfs/globals.h @@ -45,7 +45,7 @@ 1 /* MIN is the fresh start op-version, mostly \ should not change */ #define GD_OP_VERSION_MAX \ - GD_OP_VERSION_8_0 /* MAX VERSION is the maximum \ + GD_OP_VERSION_9_0 /* MAX VERSION is the maximum \ count in VME table, should \ keep changing with \ introduction of newer \ @@ -118,9 +118,12 @@ #define GD_OP_VERSION_7_0 70000 /* Op-version for GlusterFS 7.0 */ #define GD_OP_VERSION_7_1 70100 /* Op-version for GlusterFS 7.1 */ #define GD_OP_VERSION_7_2 70200 /* Op-version for GlusterFS 7.2 */ +#define GD_OP_VERSION_7_3 70300 /* Op-version for GlusterFS 7.3 */ #define GD_OP_VERSION_8_0 80000 /* Op-version for GlusterFS 8.0 */ +#define GD_OP_VERSION_9_0 90000 /* Op-version for GlusterFS 9.0 */ + #define GD_OP_VER_PERSISTENT_AFR_XATTRS GD_OP_VERSION_3_6_0 #include "glusterfs/xlator.h" @@ -166,6 +169,9 @@ glusterfs_leaseid_exist(void); int glusterfs_globals_init(glusterfs_ctx_t *ctx); +void +gf_thread_needs_cleanup(void); + struct tvec_base * glusterfs_ctx_tw_get(glusterfs_ctx_t *ctx); void diff --git a/libglusterfs/src/glusterfs/glusterfs-acl.h b/libglusterfs/src/glusterfs/glusterfs-acl.h index cae55e8062f..987bf5fab0b 100644 --- a/libglusterfs/src/glusterfs/glusterfs-acl.h +++ b/libglusterfs/src/glusterfs/glusterfs-acl.h @@ -143,7 +143,7 @@ gf_posix_acl_get_key(const acl_type_t type) return acl_key; } -static inline const acl_type_t +static inline acl_type_t gf_posix_acl_get_type(const char *key) { acl_type_t type = 0; diff --git a/libglusterfs/src/glusterfs/glusterfs.h b/libglusterfs/src/glusterfs/glusterfs.h index bbb66d264eb..e6425618b7f 100644 --- a/libglusterfs/src/glusterfs/glusterfs.h +++ b/libglusterfs/src/glusterfs/glusterfs.h @@ -43,6 +43,9 @@ #define GF_YES 1 #define GF_NO 0 +#define IS_ERROR(ret) ((ret) < 0) +#define IS_SUCCESS(ret) ((ret) >= 0) + #ifndef O_LARGEFILE /* savannah bug #20053, patch for compiling on darwin */ #define O_LARGEFILE 0100000 /* from bits/fcntl.h */ @@ -422,7 +425,7 @@ static const char *const FOP_PRI_STRINGS[] = {"HIGH", "NORMAL", "LOW", "LEAST"}; static inline const char * fop_pri_to_string(gf_fop_pri_t pri) { - if (pri < 0) + if (IS_ERROR(pri)) return "UNSPEC"; if (pri >= GF_FOP_PRI_MAX) @@ -463,6 +466,8 @@ typedef struct _server_cmdline server_cmdline_t; #define GF_OPTION_DISABLE _gf_false #define GF_OPTION_DEFERRED 2 +typedef enum { _gf_none, _gf_memcheck, _gf_drd } gf_valgrind_tool; + struct _cmd_args { /* basic options */ char *volfile_server; @@ -555,7 +560,8 @@ struct _cmd_args { /* Run this process with valgrind? Might want to prevent calling * functions that prevent valgrind from working correctly, like * dlclose(). */ - int valgrind; + gf_valgrind_tool vgtool; + int localtime_logging; /* For the subdir mount */ @@ -727,12 +733,13 @@ struct _glusterfs_ctx { } stats; struct list_head volfile_list; - /* Add members to manage janitor threads for cleanup fd */ struct list_head janitor_fds; - pthread_cond_t janitor_cond; - pthread_mutex_t janitor_lock; + pthread_cond_t fd_cond; + pthread_mutex_t fd_lock; pthread_t janitor; + /* The variable is use to save total posix xlator count */ + uint32_t pxl_count; char volume_id[GF_UUID_BUF_SIZE]; /* Used only in protocol/client */ }; diff --git a/libglusterfs/src/glusterfs/latency.h b/libglusterfs/src/glusterfs/latency.h index ed47b1f0cbc..4d601bbcbd6 100644 --- a/libglusterfs/src/glusterfs/latency.h +++ b/libglusterfs/src/glusterfs/latency.h @@ -11,13 +11,23 @@ #ifndef __LATENCY_H__ #define __LATENCY_H__ -#include "glusterfs/glusterfs.h" +#include <inttypes.h> +#include <time.h> -typedef struct fop_latency { - double min; /* min time for the call (microseconds) */ - double max; /* max time for the call (microseconds) */ - double total; /* total time (microseconds) */ +typedef struct _gf_latency { + uint64_t min; /* min time for the call (nanoseconds) */ + uint64_t max; /* max time for the call (nanoseconds) */ + uint64_t total; /* total time (nanoseconds) */ uint64_t count; -} fop_latency_t; +} gf_latency_t; +gf_latency_t * +gf_latency_new(size_t n); + +void +gf_latency_reset(gf_latency_t *lat); + +void +gf_latency_update(gf_latency_t *lat, struct timespec *begin, + struct timespec *end); #endif /* __LATENCY_H__ */ diff --git a/libglusterfs/src/glusterfs/libglusterfs-messages.h b/libglusterfs/src/glusterfs/libglusterfs-messages.h index 7e0eebbe535..cb31dd7614b 100644 --- a/libglusterfs/src/glusterfs/libglusterfs-messages.h +++ b/libglusterfs/src/glusterfs/libglusterfs-messages.h @@ -112,6 +112,134 @@ GLFS_MSGID( LG_MSG_XXH64_TO_GFID_FAILED, LG_MSG_ASYNC_WARNING, LG_MSG_ASYNC_FAILURE, LG_MSG_GRAPH_CLEANUP_FAILED, LG_MSG_GRAPH_SETUP_FAILED, LG_MSG_GRAPH_DETACH_STARTED, LG_MSG_GRAPH_ATTACH_FAILED, - LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED); + LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED, LG_MSG_DUPLICATE_ENTRY, + LG_MSG_THREAD_NAME_TOO_LONG, LG_MSG_SET_THREAD_FAILED, + LG_MSG_THREAD_CREATE_FAILED, LG_MSG_FILE_DELETE_FAILED, LG_MSG_WRONG_VALUE, + LG_MSG_PATH_OPEN_FAILED, LG_MSG_DISPATCH_HANDLER_FAILED, + LG_MSG_READ_FILE_FAILED, LG_MSG_ENTRIES_NOT_PROVIDED, + LG_MSG_ENTRIES_PROVIDED, LG_MSG_UNKNOWN_OPTION_TYPE, + LG_MSG_OPTION_DEPRECATED, LG_MSG_INVALID_INIT, LG_MSG_OBJECT_NULL, + LG_MSG_GRAPH_NOT_SET, LG_MSG_FILENAME_NOT_SPECIFIED, LG_MSG_STRUCT_MISS, + LG_MSG_METHOD_MISS, LG_MSG_INPUT_DATA_NULL, LG_MSG_OPEN_LOGFILE_FAILED); + +#define LG_MSG_EPOLL_FD_CREATE_FAILED_STR "epoll fd creation failed" +#define LG_MSG_INVALID_POLL_IN_STR "invalid poll_in value" +#define LG_MSG_INVALID_POLL_OUT_STR "invalid poll_out value" +#define LG_MSG_SLOT_NOT_FOUND_STR "could not find slot" +#define LG_MSG_EPOLL_FD_ADD_FAILED_STR "failed to add fd to epoll" +#define LG_MSG_EPOLL_FD_DEL_FAILED_STR "fail to delete fd to epoll" +#define LG_MSG_EPOLL_FD_MODIFY_FAILED_STR "failed to modify fd events" +#define LG_MSG_STALE_FD_FOUND_STR "stale fd found" +#define LG_MSG_GENERATION_MISMATCH_STR "generation mismatch" +#define LG_MSG_STARTED_EPOLL_THREAD_STR "Started thread with index" +#define LG_MSG_EXITED_EPOLL_THREAD_STR "Exited thread" +#define LG_MSG_DISPATCH_HANDLER_FAILED_STR "Failed to dispatch handler" +#define LG_MSG_START_EPOLL_THREAD_FAILED_STR "Failed to start thread" +#define LG_MSG_PIPE_CREATE_FAILED_STR "pipe creation failed" +#define LG_MSG_SET_PIPE_FAILED_STR "could not set pipe to non blocking mode" +#define LG_MSG_REGISTER_PIPE_FAILED_STR \ + "could not register pipe fd with poll event loop" +#define LG_MSG_POLL_IGNORE_MULTIPLE_THREADS_STR \ + "Currently poll does not use multiple event processing threads, count " \ + "ignored" +#define LG_MSG_INDEX_NOT_FOUND_STR "index not found" +#define LG_MSG_READ_FILE_FAILED_STR "read on file returned error" +#define LG_MSG_RB_TABLE_CREATE_FAILED_STR "Failed to create rb table bucket" +#define LG_MSG_HASH_FUNC_ERROR_STR "Hash function not given" +#define LG_MSG_ENTRIES_NOT_PROVIDED_STR \ + "Both mem-pool and expected entries not provided" +#define LG_MSG_ENTRIES_PROVIDED_STR \ + "Both mem-pool and expected entries are provided" +#define LG_MSG_RBTHASH_INIT_BUCKET_FAILED_STR "failed to init buckets" +#define LG_MSG_RBTHASH_GET_ENTRY_FAILED_STR "Failed to get entry from mem-pool" +#define LG_MSG_RBTHASH_GET_BUCKET_FAILED_STR "Failed to get bucket" +#define LG_MSG_RBTHASH_INSERT_FAILED_STR "Failed to insert entry" +#define LG_MSG_RBTHASH_INIT_ENTRY_FAILED_STR "Failed to init entry" +#define LG_MSG_FILE_STAT_FAILED_STR "failed to stat" +#define LG_MSG_INET_PTON_FAILED_STR "inet_pton() failed" +#define LG_MSG_INVALID_ENTRY_STR "Invalid arguments" +#define LG_MSG_NEGATIVE_NUM_PASSED_STR "negative number passed" +#define LG_MSG_PATH_ERROR_STR "Path manipulation failed" +#define LG_MSG_FILE_OP_FAILED_STR "could not open/read file, getting ports info" +#define LG_MSG_RESERVED_PORTS_ERROR_STR \ + "Not able to get reserved ports, hence there is a possibility that " \ + "glusterfs may consume reserved port" +#define LG_MSG_INVALID_PORT_STR "invalid port" +#define LG_MSG_GETNAMEINFO_FAILED_STR "Could not lookup hostname" +#define LG_MSG_GETIFADDRS_FAILED_STR "getifaddrs() failed" +#define LG_MSG_INVALID_FAMILY_STR "Invalid family" +#define LG_MSG_CONVERSION_FAILED_STR "String conversion failed" +#define LG_MSG_GETADDRINFO_FAILED_STR "error in getaddrinfo" +#define LG_MSG_DUPLICATE_ENTRY_STR "duplicate entry for volfile-server" +#define LG_MSG_PTHREAD_NAMING_FAILED_STR "Failed to compose thread name" +#define LG_MSG_THREAD_NAME_TOO_LONG_STR \ + "Thread name is too long. It has been truncated" +#define LG_MSG_SET_THREAD_FAILED_STR "Could not set thread name" +#define LG_MSG_THREAD_CREATE_FAILED_STR "Thread creation failed" +#define LG_MSG_PTHREAD_ATTR_INIT_FAILED_STR \ + "Thread attribute initialization failed" +#define LG_MSG_SKIP_HEADER_FAILED_STR "Failed to skip header section" +#define LG_MSG_INVALID_LOG_STR "Invalid log-format" +#define LG_MSG_UTIMENSAT_FAILED_STR "utimenstat failed" +#define LG_MSG_UTIMES_FAILED_STR "utimes failed" +#define LG_MSG_FILE_DELETE_FAILED_STR "Unable to delete file" +#define LG_MSG_BACKTRACE_SAVE_FAILED_STR "Failed to save the backtrace" +#define LG_MSG_WRONG_VALUE_STR "wrong value" +#define LG_MSG_DIR_OP_FAILED_STR "Failed to create directory" +#define LG_MSG_DIR_IS_SYMLINK_STR "dir is symlink" +#define LG_MSG_RESOLVE_HOSTNAME_FAILED_STR "couldnot resolve hostname" +#define LG_MSG_PATH_OPEN_FAILED_STR "Unable to open path" +#define LG_MSG_NO_MEMORY_STR "Error allocating memory" +#define LG_MSG_EVENT_NOTIFY_FAILED_STR "notification failed" +#define LG_MSG_PER_DENTRY_FAILED_STR "per dentry fn returned" +#define LG_MSG_PARENT_DENTRY_NOT_FOUND_STR "parent not found" +#define LG_MSG_DENTRY_CYCLIC_LOOP_STR \ + "detected cyclic loop formation during inode linkage" +#define LG_MSG_CTX_NULL_STR "_ctx not found" +#define LG_MSG_DENTRY_NOT_FOUND_STR "dentry not found" +#define LG_MSG_OUT_OF_RANGE_STR "out of range" +#define LG_MSG_UNKNOWN_OPTION_TYPE_STR "unknown option type" +#define LG_MSG_VALIDATE_RETURNS_STR "validate of returned" +#define LG_MSG_OPTION_DEPRECATED_STR \ + "option is deprecated, continuing with correction" +#define LG_MSG_VALIDATE_REC_FAILED_STR "validate_rec failed" +#define LG_MSG_MAPPING_FAILED_STR "mapping failed" +#define LG_MSG_INIT_IOBUF_FAILED_STR "init failed" +#define LG_MSG_ARENA_NOT_FOUND_STR "arena not found" +#define LG_MSG_PAGE_SIZE_EXCEEDED_STR \ + "page_size of iobufs in arena being added is greater than max available" +#define LG_MSG_POOL_NOT_FOUND_STR "pool not found" +#define LG_MSG_IOBUF_NOT_FOUND_STR "iobuf not found" +#define LG_MSG_DLOPEN_FAILED_STR "DL open failed" +#define LG_MSG_DLSYM_ERROR_STR "dlsym missing" +#define LG_MSG_LOAD_FAILED_STR "Failed to load xlator options table" +#define LG_MSG_INPUT_DATA_NULL_STR \ + "input data is null. cannot update the lru limit of the inode table. " \ + "continuing with older value." +#define LG_MSG_INIT_FAILED_STR "No init() found" +#define LG_MSG_VOLUME_ERROR_STR \ + "Initialization of volume failed. review your volfile again." +#define LG_MSG_TREE_NOT_FOUND_STR "Translator tree not found" +#define LG_MSG_SET_LOG_LEVEL_STR "setting log level" +#define LG_MSG_INVALID_INIT_STR \ + "Invalid log-level. possible values are DEBUG|WARNING|ERROR|NONE|TRACE" +#define LG_MSG_OBJECT_NULL_STR "object is null, returning false." +#define LG_MSG_GRAPH_NOT_SET_STR "Graph is not set for xlator" +#define LG_MSG_OPEN_LOGFILE_FAILED_STR "failed to open logfile" +#define LG_MSG_STRDUP_ERROR_STR "failed to create metrics dir" +#define LG_MSG_FILENAME_NOT_SPECIFIED_STR "no filename specified" +#define LG_MSG_UNDERSIZED_BUF_STR "data value is smaller than expected" +#define LG_MSG_DICT_SET_FAILED_STR "unable to set dict" +#define LG_MSG_COUNT_LESS_THAN_ZERO_STR "count < 0!" +#define LG_MSG_PAIRS_LESS_THAN_COUNT_STR "less than count data pairs found" +#define LG_MSG_NULL_PTR_STR "pair->key is null!" +#define LG_MSG_VALUE_LENGTH_LESS_THAN_ZERO_STR "value->len < 0" +#define LG_MSG_INVALID_ARG_STR "buf is null" +#define LG_MSG_KEY_OR_VALUE_NULL_STR "key or value is null" +#define LG_MSG_NULL_VALUE_IN_DICT_STR "null value found in dict" +#define LG_MSG_FAILED_TO_LOG_DICT_STR "Failed to log dictionary" +#define LG_MSG_DICT_ERROR_STR "dict error" +#define LG_MSG_STRUCT_MISS_STR "struct missing" +#define LG_MSG_METHOD_MISS_STR "method missing(init)" #endif /* !_LG_MESSAGES_H_ */ diff --git a/libglusterfs/src/glusterfs/mem-pool.h b/libglusterfs/src/glusterfs/mem-pool.h index e0441756be7..e5b3276d047 100644 --- a/libglusterfs/src/glusterfs/mem-pool.h +++ b/libglusterfs/src/glusterfs/mem-pool.h @@ -202,6 +202,24 @@ out: return dup_mem; } +#ifdef GF_DISABLE_MEMPOOL + +/* No-op memory pool enough to fit current API without massive redesign. */ + +struct mem_pool { + unsigned long sizeof_type; +}; + +#define mem_pools_init() \ + do { \ + } while (0) +#define mem_pools_fini() \ + do { \ + } while (0) +#define mem_pool_thread_destructor(pool_list) (void)pool_list + +#else /* !GF_DISABLE_MEMPOOL */ + /* kind of 'header' for the actual mem_pool_shared structure, this might make * it possible to dump some more details in a statedump */ struct mem_pool { @@ -209,10 +227,11 @@ struct mem_pool { unsigned long sizeof_type; unsigned long count; /* requested pool size (unused) */ char *name; - gf_atomic_t active; /* current allocations */ + char *xl_name; + gf_atomic_t active; /* current allocations */ #ifdef DEBUG - gf_atomic_t hit; /* number of allocations served from pt_pool */ - gf_atomic_t miss; /* number of std allocs due to miss */ + gf_atomic_t hit; /* number of allocations served from pt_pool */ + gf_atomic_t miss; /* number of std allocs due to miss */ #endif struct list_head owner; /* glusterfs_ctx_t->mempool_list */ glusterfs_ctx_t *ctx; /* take ctx->lock when updating owner */ @@ -244,24 +263,26 @@ typedef struct per_thread_pool { } per_thread_pool_t; typedef struct per_thread_pool_list { - /* - * These first two members are protected by the global pool lock. When - * a thread first tries to use any pool, we create one of these. We - * link it into the global list using thr_list so the pool-sweeper - * thread can find it, and use pthread_setspecific so this thread can - * find it. When the per-thread destructor runs, we "poison" the pool - * list to prevent further allocations. This also signals to the - * pool-sweeper thread that the list should be detached and freed after - * the next time it's swept. - */ + /* thr_list is used to place the TLS pool_list into the active global list + * (pool_threads) or the inactive global list (pool_free_threads). It's + * protected by the global pool_lock. */ struct list_head thr_list; - unsigned int poison; + + /* This lock is used to update poison and the hot/cold lists of members + * of 'pools' array. */ + pthread_spinlock_t lock; + + /* This field is used to mark a pool_list as not being owned by any thread. + * This means that the sweeper thread won't be cleaning objects stored in + * its pools. mem_put() uses it to decide if the object being released is + * placed into its original pool_list or directly destroyed. */ + bool poison; + /* * There's really more than one pool, but the actual number is hidden * in the implementation code so we just make it a single-element array * here. */ - pthread_spinlock_t lock; per_thread_pool_t pools[1]; } per_thread_pool_list_t; @@ -284,6 +305,10 @@ void mem_pools_init(void); /* start the pool_sweeper thread */ void mem_pools_fini(void); /* cleanup memory pools */ +void +mem_pool_thread_destructor(per_thread_pool_list_t *pool_list); + +#endif /* GF_DISABLE_MEMPOOL */ struct mem_pool * mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, @@ -306,9 +331,6 @@ void mem_pool_destroy(struct mem_pool *pool); void -mem_pool_thread_destructor(void); - -void gf_mem_acct_enable_set(void *ctx); #endif /* _MEM_POOL_H */ diff --git a/libglusterfs/src/glusterfs/mem-types.h b/libglusterfs/src/glusterfs/mem-types.h index 36cf7820ad5..d45d5b68c91 100644 --- a/libglusterfs/src/glusterfs/mem-types.h +++ b/libglusterfs/src/glusterfs/mem-types.h @@ -133,6 +133,7 @@ enum gf_common_mem_types_ { gf_common_volfile_t, gf_common_mt_mgmt_v3_lock_timer_t, /* used only in one location */ gf_common_mt_server_cmdline_t, /* used only in one location */ + gf_common_mt_latency_t, gf_common_mt_end }; #endif diff --git a/libglusterfs/src/glusterfs/stack.h b/libglusterfs/src/glusterfs/stack.h index 17585508a22..536a330d38b 100644 --- a/libglusterfs/src/glusterfs/stack.h +++ b/libglusterfs/src/glusterfs/stack.h @@ -45,6 +45,9 @@ typedef int32_t (*ret_fn_t)(call_frame_t *frame, call_frame_t *prev_frame, xlator_t *this, int32_t op_ret, int32_t op_errno, ...); +void +gf_frame_latency_update(call_frame_t *frame); + struct call_pool { union { struct list_head all_frames; @@ -149,8 +152,6 @@ struct _call_stack { } while (0); struct xlator_fops; -void -gf_update_latency(call_frame_t *frame); static inline void FRAME_DESTROY(call_frame_t *frame) @@ -158,7 +159,7 @@ FRAME_DESTROY(call_frame_t *frame) void *local = NULL; if (frame->root->ctx->measure_latency) - gf_update_latency(frame); + gf_frame_latency_update(frame); list_del_init(&frame->frames); if (frame->local) { @@ -429,6 +430,7 @@ call_stack_alloc_groups(call_stack_t *stack, int ngrps) if (ngrps <= SMALL_GROUP_COUNT) { stack->groups = stack->groups_small; } else { + GF_FREE(stack->groups_large); stack->groups_large = GF_CALLOC(ngrps, sizeof(gid_t), gf_common_mt_groups_t); if (!stack->groups_large) @@ -442,6 +444,12 @@ call_stack_alloc_groups(call_stack_t *stack, int ngrps) } static inline int +call_stack_groups_capacity(call_stack_t *stack) +{ + return max(stack->ngrps, SMALL_GROUP_COUNT); +} + +static inline int call_frames_count(call_stack_t *call_stack) { call_frame_t *pos; diff --git a/libglusterfs/src/glusterfs/statedump.h b/libglusterfs/src/glusterfs/statedump.h index 89d04f94587..ce082706bdf 100644 --- a/libglusterfs/src/glusterfs/statedump.h +++ b/libglusterfs/src/glusterfs/statedump.h @@ -127,4 +127,6 @@ gf_proc_dump_xlator_meminfo(xlator_t *this, strfd_t *strfd); void gf_proc_dump_xlator_profile(xlator_t *this, strfd_t *strfd); +void +gf_latency_statedump_and_reset(char *key, gf_latency_t *lat); #endif /* STATEDUMP_H */ diff --git a/libglusterfs/src/glusterfs/store.h b/libglusterfs/src/glusterfs/store.h index c8be544e164..a1f70c7b840 100644 --- a/libglusterfs/src/glusterfs/store.h +++ b/libglusterfs/src/glusterfs/store.h @@ -95,7 +95,7 @@ int32_t gf_store_iter_get_matching(gf_store_iter_t *iter, char *key, char **value); int32_t -gf_store_iter_destroy(gf_store_iter_t *iter); +gf_store_iter_destroy(gf_store_iter_t **iter); char * gf_store_strerror(gf_store_op_errno_t op_errno); diff --git a/libglusterfs/src/glusterfs/syncop.h b/libglusterfs/src/glusterfs/syncop.h index 3614d969264..4e9241a32fc 100644 --- a/libglusterfs/src/glusterfs/syncop.h +++ b/libglusterfs/src/glusterfs/syncop.h @@ -16,6 +16,8 @@ #include <ucontext.h> #include "glusterfs/dict.h" // for dict_t #include "glusterfs/stack.h" // for call_frame_t, STACK_DESTROY, STACK_... +#include "glusterfs/timer.h" + #define SYNCENV_PROC_MAX 16 #define SYNCENV_PROC_MIN 2 #define SYNCPROC_IDLE_TIME 600 @@ -29,9 +31,15 @@ #define SYNCOPCTX_PID 0x00000008 #define SYNCOPCTX_LKOWNER 0x00000010 +#ifdef HAVE_TSAN_API +/* Currently hardcoded within thread context maintained by the sanitizer. */ +#define TSAN_THREAD_NAMELEN 64 +#endif + struct synctask; struct syncproc; struct syncenv; +struct synccond; typedef int (*synctask_cbk_t)(int ret, call_frame_t *frame, void *opaque); @@ -55,9 +63,12 @@ struct synctask { call_frame_t *opframe; synctask_cbk_t synccbk; synctask_fn_t syncfn; - synctask_state_t state; + struct timespec *delta; + gf_timer_t *timer; + struct synccond *synccond; void *opaque; void *stack; + synctask_state_t state; int woken; int slept; int ret; @@ -65,6 +76,13 @@ struct synctask { uid_t uid; gid_t gid; +#ifdef HAVE_TSAN_API + struct { + void *fiber; + char name[TSAN_THREAD_NAMELEN]; + } tsan; +#endif + ucontext_t ctx; struct syncproc *proc; @@ -77,6 +95,14 @@ struct synctask { struct syncproc { pthread_t processor; + +#ifdef HAVE_TSAN_API + struct { + void *fiber; + char name[TSAN_THREAD_NAMELEN]; + } tsan; +#endif + ucontext_t sched; struct syncenv *env; struct synctask *current; @@ -85,19 +111,21 @@ struct syncproc { /* hosts the scheduler thread and framework for executing synctasks */ struct syncenv { struct syncproc proc[SYNCENV_PROC_MAX]; - int procs; + + pthread_mutex_t mutex; + pthread_cond_t cond; struct list_head runq; - int runcount; struct list_head waitq; - int waitcount; + + int procs; + int procs_idle; + + int runcount; int procmin; int procmax; - pthread_mutex_t mutex; - pthread_cond_t cond; - size_t stacksize; int destroy; /* FLAG to mark syncenv is in destroy mode @@ -123,6 +151,13 @@ struct synclock { }; typedef struct synclock synclock_t; +struct synccond { + pthread_mutex_t pmutex; + pthread_cond_t pcond; + struct list_head waitq; +}; +typedef struct synccond synccond_t; + struct syncbarrier { gf_boolean_t initialized; /*Set on successful initialization*/ pthread_mutex_t guard; /* guard the remaining members, pair @cond */ @@ -219,7 +254,7 @@ struct syncopctx { #define __yield(args) \ do { \ if (args->task) { \ - synctask_yield(args->task); \ + synctask_yield(args->task, NULL); \ } else { \ pthread_mutex_lock(&args->mutex); \ { \ @@ -240,7 +275,7 @@ struct syncopctx { task = synctask_get(); \ stb->task = task; \ if (task) \ - frame = task->opframe; \ + frame = copy_frame(task->opframe); \ else \ frame = syncop_create_frame(THIS); \ \ @@ -261,10 +296,7 @@ struct syncopctx { STACK_WIND_COOKIE(frame, cbk, (void *)stb, subvol, fn_op, params); \ \ __yield(stb); \ - if (task) \ - STACK_RESET(frame->root); \ - else \ - STACK_DESTROY(frame->root); \ + STACK_DESTROY(frame->root); \ } while (0) /* @@ -313,7 +345,9 @@ synctask_join(struct synctask *task); void synctask_wake(struct synctask *task); void -synctask_yield(struct synctask *task); +synctask_yield(struct synctask *task, struct timespec *delta); +void +synctask_sleep(int32_t secs); void synctask_waitfor(struct synctask *task, int count); @@ -411,6 +445,24 @@ synclock_trylock(synclock_t *lock); int synclock_unlock(synclock_t *lock); +int32_t +synccond_init(synccond_t *cond); + +void +synccond_destroy(synccond_t *cond); + +int +synccond_wait(synccond_t *cond, synclock_t *lock); + +int +synccond_timedwait(synccond_t *cond, synclock_t *lock, struct timespec *delta); + +void +synccond_signal(synccond_t *cond); + +void +synccond_broadcast(synccond_t *cond); + int syncbarrier_init(syncbarrier_t *barrier); int diff --git a/libglusterfs/src/glusterfs/syscall.h b/libglusterfs/src/glusterfs/syscall.h index 6b33c141a5e..b6d3ab4f2ad 100644 --- a/libglusterfs/src/glusterfs/syscall.h +++ b/libglusterfs/src/glusterfs/syscall.h @@ -96,18 +96,27 @@ int sys_unlink(const char *pathname); int +sys_unlinkat(int dfd, const char *pathname); + +int sys_rmdir(const char *pathname); int sys_symlink(const char *oldpath, const char *newpath); int +sys_symlinkat(const char *oldpath, int dirfd, const char *newpath); + +int sys_rename(const char *oldpath, const char *newpath); int sys_link(const char *oldpath, const char *newpath); int +sys_linkat(int oldfd, const char *oldpath, int newfd, const char *newpath); + +int sys_chmod(const char *path, mode_t mode); int @@ -257,4 +266,13 @@ ssize_t sys_copy_file_range(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out, size_t len, unsigned int flags); +int +sys_kill(pid_t pid, int sig); + +#ifdef __FreeBSD__ +int +sys_sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, + const void *newp, size_t newlen); +#endif + #endif /* __SYSCALL_H__ */ diff --git a/libglusterfs/src/glusterfs/xlator.h b/libglusterfs/src/glusterfs/xlator.h index c94bd75cf1c..4fd3abdaeff 100644 --- a/libglusterfs/src/glusterfs/xlator.h +++ b/libglusterfs/src/glusterfs/xlator.h @@ -702,6 +702,8 @@ typedef size_t (*cbk_inodectx_size_t)(xlator_t *this, inode_t *inode); typedef size_t (*cbk_fdctx_size_t)(xlator_t *this, fd_t *fd); +typedef void (*cbk_fdclose_t)(xlator_t *this, fd_t *fd); + struct xlator_cbks { cbk_forget_t forget; cbk_release_t release; @@ -712,6 +714,8 @@ struct xlator_cbks { cbk_ictxmerge_t ictxmerge; cbk_inodectx_size_t ictxsize; cbk_fdctx_size_t fdctxsize; + cbk_fdclose_t fdclose; + cbk_fdclose_t fdclosedir; }; typedef int32_t (*dumpop_priv_t)(xlator_t *this); @@ -801,7 +805,7 @@ struct _xlator { struct { /* for latency measurement */ - fop_latency_t latencies[GF_FOP_MAXVALUE]; + gf_latency_t latencies[GF_FOP_MAXVALUE]; /* for latency measurement */ fop_metrics_t metrics[GF_FOP_MAXVALUE]; diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c index 64e77e095a2..13f298eb3bd 100644 --- a/libglusterfs/src/graph.c +++ b/libglusterfs/src/graph.c @@ -41,7 +41,7 @@ _gf_dump_details (int argc, char **argv) { extern FILE *gf_log_logfile; int i = 0; - char timestr[64]; + char timestr[GF_TIMESTR_SIZE]; time_t utime = 0; pid_t mypid = 0; struct utsname uname_buf = {{0, }, }; @@ -482,7 +482,7 @@ fill_uuid(char *uuid, int size, struct timeval tv) char hostname[50] = { 0, }; - char now_str[64]; + char now_str[GF_TIMESTR_SIZE]; if (gethostname(hostname, sizeof(hostname) - 1) != 0) { gf_msg("graph", GF_LOG_ERROR, errno, LG_MSG_GETHOSTNAME_FAILED, @@ -490,9 +490,8 @@ fill_uuid(char *uuid, int size, struct timeval tv) hostname[sizeof(hostname) - 1] = '\0'; } - gf_time_fmt(now_str, sizeof now_str, tv.tv_sec, gf_timefmt_dirent); - snprintf(uuid, size, "%s-%d-%s:%" GF_PRI_SUSECONDS, hostname, getpid(), - now_str, tv.tv_usec); + gf_time_fmt_tv(now_str, sizeof now_str, &tv, gf_timefmt_dirent); + snprintf(uuid, size, "%s-%d-%s", hostname, getpid(), now_str); return; } diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index 6086219ebb1..dbadf77442d 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -232,15 +232,15 @@ __foreach_ancestor_dentry(dentry_t *dentry, ret = per_dentry_fn(dentry, data); if (ret) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PER_DENTRY_FAILED, - "per dentry fn returned %d", ret); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PER_DENTRY_FAILED, + "ret=%d", ret, NULL); goto out; } parent = dentry->parent; if (!parent) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PARENT_DENTRY_NOT_FOUND, - "parent not found"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PARENT_DENTRY_NOT_FOUND, + NULL); goto out; } @@ -274,11 +274,9 @@ __is_dentry_cyclic(dentry_t *dentry) ret = __foreach_ancestor_dentry(dentry, __check_cycle, dentry->inode); if (ret) { - gf_msg(dentry->inode->table->name, GF_LOG_CRITICAL, 0, - LG_MSG_DENTRY_CYCLIC_LOOP, - "detected cyclic loop formation during inode linkage. " - "inode (%s) linking under itself as %s", - uuid_utoa(dentry->inode->gfid), dentry->name); + gf_smsg(dentry->inode->table->name, GF_LOG_CRITICAL, 0, + LG_MSG_DENTRY_CYCLIC_LOOP, "gfid=%s name=-%s", + uuid_utoa(dentry->inode->gfid), dentry->name, NULL); } return ret; @@ -337,8 +335,7 @@ __inode_ctx_free(inode_t *inode) xlator_t *old_THIS = NULL; if (!inode->_ctx) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_CTX_NULL, - "_ctx not found"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_CTX_NULL, NULL); goto noctx; } @@ -1243,10 +1240,10 @@ __inode_unlink(inode_t *inode, inode_t *parent, const char *name) if (dentry) { dentry = __dentry_unset(dentry); } else { - gf_msg("inode", GF_LOG_WARNING, 0, LG_MSG_DENTRY_NOT_FOUND, - "%s/%s: dentry not found in %s", - uuid_utoa_r(parent->gfid, pgfid), name, - uuid_utoa_r(inode->gfid, gfid)); + gf_smsg("inode", GF_LOG_WARNING, 0, LG_MSG_DENTRY_NOT_FOUND, + "parent-gfid=%s name=%s gfid%s", + uuid_utoa_r(parent->gfid, pgfid), name, + uuid_utoa_r(inode->gfid, gfid), NULL); } return dentry; @@ -1430,10 +1427,8 @@ __inode_path(inode_t *inode, const char *name, char **bufp) i++; /* "/" */ i += strlen(trav->name); if (i > PATH_MAX) { - gf_msg(table->name, GF_LOG_CRITICAL, 0, LG_MSG_DENTRY_CYCLIC_LOOP, - "possible infinite " - "loop detected, forcing break. name=(%s)", - name); + gf_smsg(table->name, GF_LOG_CRITICAL, 0, LG_MSG_DENTRY_CYCLIC_LOOP, + "name=%s", name, NULL); ret = -ENOENT; goto out; } diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c index e0538f1f5b0..4e7d2958764 100644 --- a/libglusterfs/src/iobuf.c +++ b/libglusterfs/src/iobuf.c @@ -168,8 +168,7 @@ __iobuf_arena_alloc(struct iobuf_pool *iobuf_pool, size_t page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (iobuf_arena->mem_base == MAP_FAILED) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_MAPPING_FAILED, - "mapping failed"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_MAPPING_FAILED, NULL); goto err; } @@ -181,8 +180,7 @@ __iobuf_arena_alloc(struct iobuf_pool *iobuf_pool, size_t page_size, __iobuf_arena_init_iobufs(iobuf_arena); if (!iobuf_arena->iobufs) { - gf_msg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INIT_IOBUF_FAILED, - "init failed"); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INIT_IOBUF_FAILED, NULL); goto err; } @@ -227,8 +225,8 @@ __iobuf_pool_add_arena(struct iobuf_pool *iobuf_pool, const size_t page_size, if (!iobuf_arena) { iobuf_arena = __iobuf_arena_alloc(iobuf_pool, page_size, num_pages); if (!iobuf_arena) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND, - "arena not found"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND, + NULL); return NULL; } } @@ -552,10 +550,8 @@ iobuf_get2(struct iobuf_pool *iobuf_pool, size_t page_size) iobuf_pool->request_misses++; return iobuf; } else if (index == -1) { - gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED, - "page_size (%zu) of iobufs in arena being added is " - "greater than max available", - page_size); + gf_smsg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED, + "page_size=%zu", page_size, NULL); return NULL; } @@ -564,8 +560,8 @@ iobuf_get2(struct iobuf_pool *iobuf_pool, size_t page_size) iobuf = __iobuf_get(iobuf_pool, rounded_size, index); if (!iobuf) { pthread_mutex_unlock(&iobuf_pool->mutex); - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND, - "iobuf not found"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND, + NULL); goto post_unlock; } @@ -618,10 +614,8 @@ iobuf_get(struct iobuf_pool *iobuf_pool) index = gf_iobuf_get_arena_index(iobuf_pool->default_page_size); if (index == -1) { - gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED, - "page_size (%zu) of iobufs in arena being added is " - "greater than max available", - iobuf_pool->default_page_size); + gf_smsg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED, + "page_size=%zu", iobuf_pool->default_page_size, NULL); return NULL; } @@ -630,8 +624,8 @@ iobuf_get(struct iobuf_pool *iobuf_pool) iobuf = __iobuf_get(iobuf_pool, iobuf_pool->default_page_size, index); if (!iobuf) { pthread_mutex_unlock(&iobuf_pool->mutex); - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND, - "iobuf not found"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND, + NULL); goto out; } @@ -701,15 +695,14 @@ iobuf_put(struct iobuf *iobuf) iobuf_arena = iobuf->iobuf_arena; if (!iobuf_arena) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND, - "arena not found"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND, NULL); return; } iobuf_pool = iobuf_arena->iobuf_pool; if (!iobuf_pool) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_POOL_NOT_FOUND, - "iobuf pool not found"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_POOL_NOT_FOUND, "iobuf", + NULL); return; } @@ -948,14 +941,12 @@ iobuf_size(struct iobuf *iobuf) GF_VALIDATE_OR_GOTO("iobuf", iobuf, out); if (!iobuf->iobuf_arena) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND, - "arena not found"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND, NULL); goto out; } if (!iobuf->iobuf_arena->iobuf_pool) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_POOL_NOT_FOUND, - "pool not found"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_POOL_NOT_FOUND, NULL); goto out; } diff --git a/libglusterfs/src/latency.c b/libglusterfs/src/latency.c index 15b397c3799..ce4b0e8255d 100644 --- a/libglusterfs/src/latency.c +++ b/libglusterfs/src/latency.c @@ -16,35 +16,32 @@ #include "glusterfs/glusterfs.h" #include "glusterfs/statedump.h" -void -gf_update_latency(call_frame_t *frame) +gf_latency_t * +gf_latency_new(size_t n) { - double elapsed; - struct timespec *begin, *end; - - fop_latency_t *lat; - - begin = &frame->begin; - end = &frame->end; + int i = 0; + gf_latency_t *lat = NULL; - if (!(begin->tv_sec && end->tv_sec)) - goto out; + lat = GF_MALLOC(n * sizeof(*lat), gf_common_mt_latency_t); + if (!lat) + return NULL; - elapsed = (end->tv_sec - begin->tv_sec) * 1e9 + - (end->tv_nsec - begin->tv_nsec); + for (i = 0; i < n; i++) { + gf_latency_reset(lat + i); + } + return lat; +} - if (frame->op < 0 || frame->op >= GF_FOP_MAXVALUE) { - gf_log("[core]", GF_LOG_WARNING, "Invalid frame op value: %d", - frame->op); +void +gf_latency_update(gf_latency_t *lat, struct timespec *begin, + struct timespec *end) +{ + if (!(begin->tv_sec && end->tv_sec)) { + /*Measure latency might have been enabled/disabled during the op*/ return; } - /* Can happen mostly at initiator xlator, as STACK_WIND/UNWIND macros - set it right anyways for those frames */ - if (!frame->op) - frame->op = frame->root->op; - - lat = &frame->this->stats.interval.latencies[frame->op]; + double elapsed = gf_tsdiff(begin, end); if (lat->max < elapsed) lat->max = elapsed; @@ -54,42 +51,34 @@ gf_update_latency(call_frame_t *frame) lat->total += elapsed; lat->count++; -out: - return; } void -gf_proc_dump_latency_info(xlator_t *xl) +gf_latency_reset(gf_latency_t *lat) { - char key_prefix[GF_DUMP_MAX_BUF_LEN]; - char key[GF_DUMP_MAX_BUF_LEN]; - int i; - - snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.latency", xl->name); - gf_proc_dump_add_section("%s", key_prefix); - - for (i = 0; i < GF_FOP_MAXVALUE; i++) { - gf_proc_dump_build_key(key, key_prefix, "%s", (char *)gf_fop_list[i]); - - fop_latency_t *lat = &xl->stats.interval.latencies[i]; + if (!lat) + return; + memset(lat, 0, sizeof(*lat)); + lat->min = ULLONG_MAX; + /* make sure 'min' is set to high value, so it would be + properly set later */ +} - /* Doesn't make sense to continue if there are no fops - came in the given interval */ - if (!lat->count) - continue; +void +gf_frame_latency_update(call_frame_t *frame) +{ + gf_latency_t *lat; + /* Can happen mostly at initiator xlator, as STACK_WIND/UNWIND macros + set it right anyways for those frames */ + if (!frame->op) + frame->op = frame->root->op; - gf_proc_dump_write( - key, "AVG:%.03f,CNT:%" PRId64 ",TOTAL:%.03f,MIN:%.03f,MAX:%.03f", - (lat->total / lat->count), lat->count, lat->total, lat->min, - lat->max); + if (frame->op < 0 || frame->op >= GF_FOP_MAXVALUE) { + gf_log("[core]", GF_LOG_WARNING, "Invalid frame op value: %d", + frame->op); + return; } - memset(xl->stats.interval.latencies, 0, - sizeof(xl->stats.interval.latencies)); - - /* make sure 'min' is set to high value, so it would be - properly set later */ - for (i = 0; i < GF_FOP_MAXVALUE; i++) { - xl->stats.interval.latencies[i].min = 0xffffffff; - } + lat = &frame->this->stats.interval.latencies[frame->op]; + gf_latency_update(lat, &frame->begin, &frame->end); } diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym index dc7382ba749..5f18cd56cbe 100644 --- a/libglusterfs/src/libglusterfs.sym +++ b/libglusterfs/src/libglusterfs.sym @@ -451,6 +451,7 @@ gf_event_unregister_close fd_anonymous fd_anonymous_with_flags fd_bind +fd_close fd_create fd_create_uint64 __fd_ctx_del @@ -584,6 +585,7 @@ gf_dirent_free gf_dirent_orig_offset gf_dm_hashfn gf_dnscache_init +gf_dnscache_deinit gf_errno_to_error gf_error_to_errno _gf_event @@ -937,6 +939,12 @@ syncbarrier_destroy syncbarrier_init syncbarrier_wait syncbarrier_wake +synccond_init +synccond_destroy +synccond_wait +synccond_timedwait +synccond_signal +synccond_broadcast syncenv_destroy syncenv_new synclock_destroy @@ -1014,6 +1022,7 @@ synctask_new synctask_new1 synctask_set synctask_setid +synctask_sleep synctask_wake synctask_yield sys_access @@ -1039,6 +1048,7 @@ sys_futimes sys_lchown sys_lgetxattr sys_link +sys_linkat sys_llistxattr sys_lremovexattr sys_lseek @@ -1062,13 +1072,17 @@ sys_rmdir sys_stat sys_statvfs sys_symlink +sys_symlinkat sys_truncate sys_unlink +sys_unlinkat sys_utimensat sys_write sys_writev sys_socket sys_accept +sys_kill +sys_sysctl tbf_init tbf_throttle timespec_now @@ -1169,4 +1183,11 @@ glusterfs_process_svc_detach mgmt_is_multiplexed_daemon xlator_is_cleanup_starting gf_nanosleep +gf_syncfs graph_total_client_xlator +get_xattrs_to_heal +gf_latency_statedump_and_reset +gf_latency_new +gf_latency_reset +gf_latency_update +gf_frame_latency_update diff --git a/libglusterfs/src/logging.c b/libglusterfs/src/logging.c index e900df08a4b..a930d3e3b63 100644 --- a/libglusterfs/src/logging.c +++ b/libglusterfs/src/logging.c @@ -35,7 +35,6 @@ #define GF_LOG_CONTROL_FILE "/etc/glusterfs/logger.conf" #define GF_LOG_BACKTRACE_DEPTH 5 #define GF_LOG_BACKTRACE_SIZE 4096 -#define GF_LOG_TIMESTR_SIZE 256 #define GF_MAX_SLOG_PAIR_COUNT 100 #include "glusterfs/logging.h" @@ -312,18 +311,16 @@ gf_log_rotate(glusterfs_ctx_t *ctx) fd = sys_open(ctx->log.filename, O_CREAT | O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR); if (fd < 0) { - gf_msg("logrotate", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, - "failed to open " - "logfile"); + gf_smsg("logrotate", GF_LOG_ERROR, errno, + LG_MSG_OPEN_LOGFILE_FAILED, NULL); return; } new_logfile = fdopen(fd, "a"); if (!new_logfile) { - gf_msg("logrotate", GF_LOG_CRITICAL, errno, LG_MSG_FILE_OP_FAILED, - "failed to open logfile" - " %s", - ctx->log.filename); + gf_smsg("logrotate", GF_LOG_CRITICAL, errno, + LG_MSG_OPEN_LOGFILE_FAILED, "filename=%s", + ctx->log.filename, NULL); sys_close(fd); return; } @@ -685,9 +682,8 @@ gf_log_init(void *data, const char *file, const char *ident) } if (mkdir_p(logdir, 0755, true)) { /* EEXIST is handled in mkdir_p() itself */ - gf_msg("logging", GF_LOG_ERROR, 0, LG_MSG_STRDUP_ERROR, - "failed to create metrics dir %s (%s)", logdir, - strerror(errno)); + gf_smsg("logging", GF_LOG_ERROR, 0, LG_MSG_STRDUP_ERROR, + "logdir=%s", logdir, "errno=%s", strerror(errno), NULL); GF_FREE(logdir); return -1; } @@ -763,7 +759,7 @@ _gf_log_callingfn(const char *domain, const char *file, const char *function, xlator_t *this = THIS; char *logline = NULL; char *msg = NULL; - char timestr[GF_LOG_TIMESTR_SIZE] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; char *callstr = NULL; @@ -823,12 +819,12 @@ _gf_log_callingfn(const char *domain, const char *file, const char *function, if (-1 == ret) goto out; - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); - ret = gf_asprintf( - &logline, "[%s.%" GF_PRI_SUSECONDS "] %c [%s:%d:%s] %s %d-%s: %s\n", - timestr, tv.tv_usec, gf_level_strings[level], basename, line, function, - callstr, ((this->graph) ? this->graph->id : 0), domain, msg); + ret = gf_asprintf(&logline, "[%s] %c [%s:%d:%s] %s %d-%s: %s\n", timestr, + gf_level_strings[level], basename, line, function, + callstr, ((this->graph) ? this->graph->id : 0), domain, + msg); if (-1 == ret) { goto out; } @@ -1091,7 +1087,7 @@ _gf_msg_nomem(const char *domain, const char *file, const char *function, char msg[2048] = { 0, }; - char timestr[GF_LOG_TIMESTR_SIZE] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; glusterfs_ctx_t *ctx = NULL; @@ -1119,20 +1115,20 @@ _gf_msg_nomem(const char *domain, const char *file, const char *function, ret = gettimeofday(&tv, NULL); if (-1 == ret) goto out; - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); /* TODO: Currently we print in the enhanced format, with a message ID * of 0. Need to enhance this to support format as configured */ wlen = snprintf( msg, sizeof msg, - "[%s.%" GF_PRI_SUSECONDS "] %c [MSGID: %" PRIu64 + "[%s] %c [MSGID: %" PRIu64 "]" " [%s:%d:%s] %s: no memory " "available for size (%" GF_PRI_SIZET ") current memory usage in kilobytes %ld" " [call stack follows]\n", - timestr, tv.tv_usec, gf_level_strings[level], (uint64_t)0, basename, - line, function, domain, size, + timestr, gf_level_strings[level], (uint64_t)0, basename, line, function, + domain, size, (!getrusage(RUSAGE_SELF, &r_usage) ? r_usage.ru_maxrss : 0)); if (-1 == wlen) { ret = -1; @@ -1278,7 +1274,7 @@ gf_log_glusterlog(glusterfs_ctx_t *ctx, const char *domain, const char *file, int errnum, uint64_t msgid, char **appmsgstr, char *callstr, struct timeval tv, int graph_id, gf_log_format_t fmt) { - char timestr[GF_LOG_TIMESTR_SIZE] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; char *header = NULL; @@ -1289,7 +1285,7 @@ gf_log_glusterlog(glusterfs_ctx_t *ctx, const char *domain, const char *file, gf_log_rotate(ctx); /* format the time stamp */ - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); /* generate footer */ if (errnum) { @@ -1305,40 +1301,35 @@ gf_log_glusterlog(glusterfs_ctx_t *ctx, const char *domain, const char *file, if (fmt == gf_logformat_traditional) { if (!callstr) { ret = gf_asprintf(&header, - "[%s.%" GF_PRI_SUSECONDS - "] %c [%s:%d:%s]" + "[%s] %c [%s:%d:%s]" " %d-%s: %s", - timestr, tv.tv_usec, gf_level_strings[level], - file, line, function, graph_id, domain, - *appmsgstr); + timestr, gf_level_strings[level], file, line, + function, graph_id, domain, *appmsgstr); } else { ret = gf_asprintf(&header, - "[%s.%" GF_PRI_SUSECONDS - "] %c [%s:%d:%s] %s" + "[%s] %c [%s:%d:%s] %s" " %d-%s: %s", - timestr, tv.tv_usec, gf_level_strings[level], - file, line, function, callstr, graph_id, domain, - *appmsgstr); + timestr, gf_level_strings[level], file, line, + function, callstr, graph_id, domain, *appmsgstr); } } else { /* gf_logformat_withmsgid */ /* CEE log format unsupported in logger_glusterlog, so just * print enhanced log format */ if (!callstr) { ret = gf_asprintf(&header, - "[%s.%" GF_PRI_SUSECONDS "] %c [MSGID: %" PRIu64 + "[%s] %c [MSGID: %" PRIu64 "]" " [%s:%d:%s] %d-%s: %s", - timestr, tv.tv_usec, gf_level_strings[level], - msgid, file, line, function, graph_id, domain, - *appmsgstr); + timestr, gf_level_strings[level], msgid, file, + line, function, graph_id, domain, *appmsgstr); } else { ret = gf_asprintf(&header, - "[%s.%" GF_PRI_SUSECONDS "] %c [MSGID: %" PRIu64 + "[%s] %c [MSGID: %" PRIu64 "]" " [%s:%d:%s] %s %d-%s: %s", - timestr, tv.tv_usec, gf_level_strings[level], - msgid, file, line, function, callstr, graph_id, - domain, *appmsgstr); + timestr, gf_level_strings[level], msgid, file, + line, function, callstr, graph_id, domain, + *appmsgstr); } } if (-1 == ret) { @@ -1389,39 +1380,36 @@ gf_syslog_log_repetitions(const char *domain, const char *file, int graph_id) { int priority; - char timestr_latest[GF_LOG_TIMESTR_SIZE] = { + char timestr_latest[GF_TIMESTR_SIZE] = { 0, }; - char timestr_oldest[GF_LOG_TIMESTR_SIZE] = { + char timestr_oldest[GF_TIMESTR_SIZE] = { 0, }; SET_LOG_PRIO(level, priority); - gf_time_fmt(timestr_latest, sizeof timestr_latest, latest.tv_sec, - gf_timefmt_FT); - gf_time_fmt(timestr_oldest, sizeof timestr_oldest, oldest.tv_sec, - gf_timefmt_FT); + gf_time_fmt_tv(timestr_latest, sizeof timestr_latest, &latest, + gf_timefmt_FT); + gf_time_fmt_tv(timestr_oldest, sizeof timestr_oldest, &oldest, + gf_timefmt_FT); if (errnum) { - syslog( - priority, - "The message \"[MSGID: %" PRIu64 - "] [%s:%d:%s] " - "%d-%s: %s [%s] \" repeated %d times between %s.%" GF_PRI_SUSECONDS - " and %s.%" GF_PRI_SUSECONDS, - msgid, file, line, function, graph_id, domain, *appmsgstr, - strerror(errnum), refcount, timestr_oldest, oldest.tv_usec, - timestr_latest, latest.tv_usec); + syslog(priority, + "The message \"[MSGID: %" PRIu64 + "] [%s:%d:%s] " + "%d-%s: %s [%s] \" repeated %d times between %s" + " and %s", + msgid, file, line, function, graph_id, domain, *appmsgstr, + strerror(errnum), refcount, timestr_oldest, timestr_latest); } else { syslog(priority, "The message \"[MSGID: %" PRIu64 "] [%s:%d:%s] " - "%d-%s: %s \" repeated %d times between %s.%" GF_PRI_SUSECONDS - " and %s.%" GF_PRI_SUSECONDS, + "%d-%s: %s \" repeated %d times between %s" + " and %s", msgid, file, line, function, graph_id, domain, *appmsgstr, - refcount, timestr_oldest, oldest.tv_usec, timestr_latest, - latest.tv_usec); + refcount, timestr_oldest, timestr_latest); } return 0; } @@ -1435,10 +1423,10 @@ gf_glusterlog_log_repetitions(glusterfs_ctx_t *ctx, const char *domain, struct timeval latest, int graph_id) { int ret = 0; - char timestr_latest[GF_LOG_TIMESTR_SIZE] = { + char timestr_latest[GF_TIMESTR_SIZE] = { 0, }; - char timestr_oldest[GF_LOG_TIMESTR_SIZE] = { + char timestr_oldest[GF_TIMESTR_SIZE] = { 0, }; char errstr[256] = { @@ -1462,21 +1450,17 @@ gf_glusterlog_log_repetitions(glusterfs_ctx_t *ctx, const char *domain, goto err; } - gf_time_fmt(timestr_latest, sizeof timestr_latest, latest.tv_sec, - gf_timefmt_FT); + gf_time_fmt_tv(timestr_latest, sizeof timestr_latest, &latest, + gf_timefmt_FT); - gf_time_fmt(timestr_oldest, sizeof timestr_oldest, oldest.tv_sec, - gf_timefmt_FT); + gf_time_fmt_tv(timestr_oldest, sizeof timestr_oldest, &oldest, + gf_timefmt_FT); if (errnum) snprintf(errstr, sizeof(errstr) - 1, " [%s]", strerror(errnum)); - ret = gf_asprintf(&footer, - "%s\" repeated %d times between" - " [%s.%" GF_PRI_SUSECONDS "] and [%s.%" GF_PRI_SUSECONDS - "]", - errstr, refcount, timestr_oldest, oldest.tv_usec, - timestr_latest, latest.tv_usec); + ret = gf_asprintf(&footer, "%s\" repeated %d times between [%s] and [%s]", + errstr, refcount, timestr_oldest, timestr_latest); if (-1 == ret) { ret = -1; goto err; @@ -2016,7 +2000,7 @@ _gf_log(const char *domain, const char *file, const char *function, int line, const char *basename = NULL; FILE *new_logfile = NULL; va_list ap; - char timestr[GF_LOG_TIMESTR_SIZE] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; struct timeval tv = { @@ -2074,16 +2058,17 @@ _gf_log(const char *domain, const char *file, const char *function, int line, fd = sys_open(ctx->log.filename, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR); if (fd < 0) { - gf_msg("logrotate", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, - "failed to open logfile"); + gf_smsg("logrotate", GF_LOG_ERROR, errno, + LG_MSG_OPEN_LOGFILE_FAILED, NULL); return -1; } sys_close(fd); new_logfile = fopen(ctx->log.filename, "a"); if (!new_logfile) { - gf_msg("logrotate", GF_LOG_CRITICAL, errno, LG_MSG_FILE_OP_FAILED, - "failed to open logfile %s", ctx->log.filename); + gf_smsg("logrotate", GF_LOG_CRITICAL, errno, + LG_MSG_OPEN_LOGFILE_FAILED, "filename=%s", + ctx->log.filename, NULL); goto log; } @@ -2102,12 +2087,11 @@ log: if (-1 == ret) goto out; - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); - ret = gf_asprintf( - &logline, "[%s.%" GF_PRI_SUSECONDS "] %c [%s:%d:%s] %d-%s: %s\n", - timestr, tv.tv_usec, gf_level_strings[level], basename, line, function, - ((this->graph) ? this->graph->id : 0), domain, msg); + ret = gf_asprintf(&logline, "[%s] %c [%s:%d:%s] %d-%s: %s\n", timestr, + gf_level_strings[level], basename, line, function, + ((this->graph) ? this->graph->id : 0), domain, msg); if (-1 == ret) { goto err; } @@ -2190,8 +2174,8 @@ gf_cmd_log_init(const char *filename) return -1; if (!filename) { - gf_msg(this->name, GF_LOG_CRITICAL, 0, LG_MSG_INVALID_ENTRY, - "gf_cmd_log_init: no filename specified\n"); + gf_smsg(this->name, GF_LOG_CRITICAL, 0, LG_MSG_FILENAME_NOT_SPECIFIED, + "gf_cmd_log_init", NULL); return -1; } @@ -2208,17 +2192,15 @@ gf_cmd_log_init(const char *filename) fd = sys_open(ctx->log.cmd_log_filename, O_CREAT | O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR); if (fd < 0) { - gf_msg(this->name, GF_LOG_CRITICAL, errno, LG_MSG_FILE_OP_FAILED, - "failed to open cmd_log_file"); + gf_smsg(this->name, GF_LOG_CRITICAL, errno, LG_MSG_OPEN_LOGFILE_FAILED, + "cmd_log_file", NULL); return -1; } ctx->log.cmdlogfile = fdopen(fd, "a"); if (!ctx->log.cmdlogfile) { - gf_msg(this->name, GF_LOG_CRITICAL, errno, LG_MSG_FILE_OP_FAILED, - "gf_cmd_log_init: failed to open logfile \"%s\" " - "\n", - ctx->log.cmd_log_filename); + gf_smsg(this->name, GF_LOG_CRITICAL, errno, LG_MSG_OPEN_LOGFILE_FAILED, + "gf_cmd_log_init: %s", ctx->log.cmd_log_filename, NULL); sys_close(fd); return -1; } @@ -2229,7 +2211,7 @@ int gf_cmd_log(const char *domain, const char *fmt, ...) { va_list ap; - char timestr[64]; + char timestr[GF_TIMESTR_SIZE]; struct timeval tv = { 0, }; @@ -2262,10 +2244,9 @@ gf_cmd_log(const char *domain, const char *fmt, ...) goto out; } - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); - ret = gf_asprintf(&logline, "[%s.%" GF_PRI_SUSECONDS "] %s : %s\n", timestr, - tv.tv_usec, domain, msg); + ret = gf_asprintf(&logline, "[%s] %s : %s\n", timestr, domain, msg); if (ret == -1) { goto out; } @@ -2282,20 +2263,18 @@ gf_cmd_log(const char *domain, const char *fmt, ...) fd = sys_open(ctx->log.cmd_log_filename, O_CREAT | O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR); if (fd < 0) { - gf_msg(THIS->name, GF_LOG_CRITICAL, errno, LG_MSG_FILE_OP_FAILED, - "failed to open " - "logfile \"%s\" \n", - ctx->log.cmd_log_filename); + gf_smsg(THIS->name, GF_LOG_CRITICAL, errno, + LG_MSG_OPEN_LOGFILE_FAILED, "name=%s", + ctx->log.cmd_log_filename, NULL); ret = -1; goto out; } ctx->log.cmdlogfile = fdopen(fd, "a"); if (!ctx->log.cmdlogfile) { - gf_msg(THIS->name, GF_LOG_CRITICAL, errno, LG_MSG_FILE_OP_FAILED, - "failed to open logfile \"%s\"" - " \n", - ctx->log.cmd_log_filename); + gf_smsg(THIS->name, GF_LOG_CRITICAL, errno, + LG_MSG_OPEN_LOGFILE_FAILED, "name=%s", + ctx->log.cmd_log_filename, NULL); ret = -1; sys_close(fd); goto out; diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c index ea9cc6881b1..2d5a12b0a00 100644 --- a/libglusterfs/src/mem-pool.c +++ b/libglusterfs/src/mem-pool.c @@ -362,6 +362,30 @@ free: FREE(ptr); } +#if defined(GF_DISABLE_MEMPOOL) + +struct mem_pool * +mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, + unsigned long count, char *name) +{ + struct mem_pool *new; + + new = GF_MALLOC(sizeof(struct mem_pool), gf_common_mt_mem_pool); + if (!new) + return NULL; + + new->sizeof_type = sizeof_type; + return new; +} + +void +mem_pool_destroy(struct mem_pool *pool) +{ + GF_FREE(pool); +} + +#else /* !GF_DISABLE_MEMPOOL */ + static pthread_mutex_t pool_lock = PTHREAD_MUTEX_INITIALIZER; static struct list_head pool_threads; static pthread_mutex_t pool_free_lock = PTHREAD_MUTEX_INITIALIZER; @@ -371,12 +395,10 @@ static size_t pool_list_size; static __thread per_thread_pool_list_t *thread_pool_list = NULL; -#if !defined(GF_DISABLE_MEMPOOL) #define N_COLD_LISTS 1024 #define POOL_SWEEP_SECS 30 typedef struct { - struct list_head death_row; pooled_obj_hdr_t *cold_lists[N_COLD_LISTS]; unsigned int n_cold_lists; } sweep_state_t; @@ -393,36 +415,33 @@ static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; static unsigned int init_count = 0; static pthread_t sweeper_tid; -gf_boolean_t +static bool collect_garbage(sweep_state_t *state, per_thread_pool_list_t *pool_list) { unsigned int i; per_thread_pool_t *pt_pool; - gf_boolean_t poisoned; (void)pthread_spin_lock(&pool_list->lock); - poisoned = pool_list->poison != 0; - if (!poisoned) { - for (i = 0; i < NPOOLS; ++i) { - pt_pool = &pool_list->pools[i]; - if (pt_pool->cold_list) { - if (state->n_cold_lists >= N_COLD_LISTS) { - break; - } - state->cold_lists[state->n_cold_lists++] = pt_pool->cold_list; + for (i = 0; i < NPOOLS; ++i) { + pt_pool = &pool_list->pools[i]; + if (pt_pool->cold_list) { + if (state->n_cold_lists >= N_COLD_LISTS) { + (void)pthread_spin_unlock(&pool_list->lock); + return true; } - pt_pool->cold_list = pt_pool->hot_list; - pt_pool->hot_list = NULL; + state->cold_lists[state->n_cold_lists++] = pt_pool->cold_list; } + pt_pool->cold_list = pt_pool->hot_list; + pt_pool->hot_list = NULL; } (void)pthread_spin_unlock(&pool_list->lock); - return poisoned; + return false; } -void +static void free_obj_list(pooled_obj_hdr_t *victim) { pooled_obj_hdr_t *next; @@ -434,82 +453,96 @@ free_obj_list(pooled_obj_hdr_t *victim) } } -void * +static void * pool_sweeper(void *arg) { sweep_state_t state; per_thread_pool_list_t *pool_list; - per_thread_pool_list_t *next_pl; - per_thread_pool_t *pt_pool; - unsigned int i; - gf_boolean_t poisoned; + uint32_t i; + bool pending; /* * This is all a bit inelegant, but the point is to avoid doing * expensive things (like freeing thousands of objects) while holding a - * global lock. Thus, we split each iteration into three passes, with + * global lock. Thus, we split each iteration into two passes, with * only the first and fastest holding the lock. */ + pending = true; + for (;;) { - sleep(POOL_SWEEP_SECS); + /* If we know there's pending work to do (or it's the first run), we + * do collect garbage more often. */ + sleep(pending ? POOL_SWEEP_SECS / 5 : POOL_SWEEP_SECS); + (void)pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - INIT_LIST_HEAD(&state.death_row); state.n_cold_lists = 0; + pending = false; /* First pass: collect stuff that needs our attention. */ (void)pthread_mutex_lock(&pool_lock); - list_for_each_entry_safe(pool_list, next_pl, &pool_threads, thr_list) + list_for_each_entry(pool_list, &pool_threads, thr_list) { - (void)pthread_mutex_unlock(&pool_lock); - poisoned = collect_garbage(&state, pool_list); - (void)pthread_mutex_lock(&pool_lock); - - if (poisoned) { - list_move(&pool_list->thr_list, &state.death_row); + if (collect_garbage(&state, pool_list)) { + pending = true; } } (void)pthread_mutex_unlock(&pool_lock); - /* Second pass: free dead pools. */ - (void)pthread_mutex_lock(&pool_free_lock); - list_for_each_entry_safe(pool_list, next_pl, &state.death_row, thr_list) - { - for (i = 0; i < NPOOLS; ++i) { - pt_pool = &pool_list->pools[i]; - free_obj_list(pt_pool->cold_list); - free_obj_list(pt_pool->hot_list); - pt_pool->hot_list = pt_pool->cold_list = NULL; - } - list_del(&pool_list->thr_list); - list_add(&pool_list->thr_list, &pool_free_threads); - } - (void)pthread_mutex_unlock(&pool_free_lock); - - /* Third pass: free cold objects from live pools. */ + /* Second pass: free cold objects from live pools. */ for (i = 0; i < state.n_cold_lists; ++i) { free_obj_list(state.cold_lists[i]); } (void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); } + + return NULL; } void -mem_pool_thread_destructor(void) +mem_pool_thread_destructor(per_thread_pool_list_t *pool_list) { - per_thread_pool_list_t *pool_list = thread_pool_list; + per_thread_pool_t *pt_pool; + uint32_t i; - /* The pool-sweeper thread will take it from here. - * - * We can change 'poison' here without taking locks because the change - * itself doesn't interact with other parts of the code and a simple write - * is already atomic from the point of view of the processor. - * - * This change can modify what mem_put() does, but both possibilities are - * fine until the sweeper thread kicks in. The real synchronization must be - * between mem_put() and the sweeper thread. */ + if (pool_list == NULL) { + pool_list = thread_pool_list; + } + + /* The current thread is terminating. None of the allocated objects will + * be used again. We can directly destroy them here instead of delaying + * it until the next sweeper loop. */ if (pool_list != NULL) { - pool_list->poison = 1; + /* Remove pool_list from the global list to avoid that sweeper + * could touch it. */ + pthread_mutex_lock(&pool_lock); + list_del(&pool_list->thr_list); + pthread_mutex_unlock(&pool_lock); + + /* We need to protect hot/cold changes from potential mem_put() calls + * that reference this pool_list. Once poison is set to true, we are + * sure that no one else will touch hot/cold lists. The only possible + * race is when at the same moment a mem_put() is adding a new item + * to the hot list. We protect from that by taking pool_list->lock. + * After that we don't need the lock to destroy the hot/cold lists. */ + pthread_spin_lock(&pool_list->lock); + pool_list->poison = true; + pthread_spin_unlock(&pool_list->lock); + + for (i = 0; i < NPOOLS; i++) { + pt_pool = &pool_list->pools[i]; + + free_obj_list(pt_pool->hot_list); + pt_pool->hot_list = NULL; + + free_obj_list(pt_pool->cold_list); + pt_pool->cold_list = NULL; + } + + pthread_mutex_lock(&pool_free_lock); + list_add(&pool_list->thr_list, &pool_free_threads); + pthread_mutex_unlock(&pool_free_lock); + thread_pool_list = NULL; } } @@ -537,6 +570,22 @@ mem_pools_preinit(void) init_done = GF_MEMPOOL_INIT_EARLY; } +static __attribute__((destructor)) void +mem_pools_postfini(void) +{ + /* TODO: This function should destroy all per thread memory pools that + * are still alive, but this is not possible right now because glibc + * starts calling destructors as soon as exit() is called, and + * gluster doesn't ensure that all threads have been stopped before + * calling exit(). Existing threads would crash when they try to use + * memory or they terminate if we destroy things here. + * + * When we propertly terminate all threads, we can add the needed + * code here. Till then we need to leave the memory allocated. Most + * probably this function will be executed on process termination, + * so the memory will be released anyway by the system. */ +} + /* Call mem_pools_init() once threading has been configured completely. This * prevent the pool_sweeper thread from getting killed once the main() thread * exits during deamonizing. */ @@ -569,10 +618,6 @@ mem_pools_fini(void) */ break; case 1: { - per_thread_pool_list_t *pool_list; - per_thread_pool_list_t *next_pl; - unsigned int i; - /* if mem_pools_init() was not called, sweeper_tid will be invalid * and the functions will error out. That is not critical. In all * other cases, the sweeper_tid will be valid and the thread gets @@ -580,32 +625,11 @@ mem_pools_fini(void) (void)pthread_cancel(sweeper_tid); (void)pthread_join(sweeper_tid, NULL); - /* At this point all threads should have already terminated, so - * it should be safe to destroy all pending per_thread_pool_list_t - * structures that are stored for each thread. */ - mem_pool_thread_destructor(); - - /* free all objects from all pools */ - list_for_each_entry_safe(pool_list, next_pl, &pool_threads, - thr_list) - { - for (i = 0; i < NPOOLS; ++i) { - free_obj_list(pool_list->pools[i].hot_list); - free_obj_list(pool_list->pools[i].cold_list); - pool_list->pools[i].hot_list = NULL; - pool_list->pools[i].cold_list = NULL; - } - - list_del(&pool_list->thr_list); - FREE(pool_list); - } - - list_for_each_entry_safe(pool_list, next_pl, &pool_free_threads, - thr_list) - { - list_del(&pool_list->thr_list); - FREE(pool_list); - } + /* There could be threads still running in some cases, so we can't + * destroy pool_lists in use. We can also not destroy unused + * pool_lists because some allocated objects may still be pointing + * to them. */ + mem_pool_thread_destructor(NULL); init_done = GF_MEMPOOL_INIT_DESTROY; /* Fall through. */ @@ -616,21 +640,29 @@ mem_pools_fini(void) pthread_mutex_unlock(&init_mutex); } -#else -void -mem_pools_init(void) -{ -} void -mem_pools_fini(void) -{ -} -void -mem_pool_thread_destructor(void) +mem_pool_destroy(struct mem_pool *pool) { -} + if (!pool) + return; -#endif + /* remove this pool from the owner (glusterfs_ctx_t) */ + LOCK(&pool->ctx->lock); + { + list_del(&pool->owner); + } + UNLOCK(&pool->ctx->lock); + + /* free this pool, but keep the mem_pool_shared */ + GF_FREE(pool); + + /* + * Pools are now permanent, so the mem_pool->pool is kept around. All + * of the objects *in* the pool will eventually be freed via the + * pool-sweeper thread, and this way we don't have to add a lot of + * reference-counting complexity. + */ +} struct mem_pool * mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, @@ -681,6 +713,7 @@ mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, new->sizeof_type = sizeof_type; new->count = count; new->name = name; + new->xl_name = THIS->name; new->pool = pool; GF_ATOMIC_INIT(new->active, 0); #ifdef DEBUG @@ -698,21 +731,6 @@ mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, return new; } -void * -mem_get0(struct mem_pool *mem_pool) -{ - void *ptr = mem_get(mem_pool); - if (ptr) { -#if defined(GF_DISABLE_MEMPOOL) - memset(ptr, 0, mem_pool->sizeof_type); -#else - memset(ptr, 0, AVAILABLE_SIZE(mem_pool->pool->power_of_two)); -#endif - } - - return ptr; -} - per_thread_pool_list_t * mem_get_pool_list(void) { @@ -747,13 +765,21 @@ mem_get_pool_list(void) } } + /* There's no need to take pool_list->lock, because this is already an + * atomic operation and we don't need to synchronize it with any change + * in hot/cold lists. */ + pool_list->poison = false; + (void)pthread_mutex_lock(&pool_lock); - pool_list->poison = 0; list_add(&pool_list->thr_list, &pool_threads); (void)pthread_mutex_unlock(&pool_lock); thread_pool_list = pool_list; + /* Ensure that all memory objects associated to the new pool_list are + * destroyed when the thread terminates. */ + gf_thread_needs_cleanup(); + return pool_list; } @@ -813,6 +839,23 @@ mem_get_from_pool(struct mem_pool *mem_pool) return retval; } +#endif /* GF_DISABLE_MEMPOOL */ + +void * +mem_get0(struct mem_pool *mem_pool) +{ + void *ptr = mem_get(mem_pool); + if (ptr) { +#if defined(GF_DISABLE_MEMPOOL) + memset(ptr, 0, mem_pool->sizeof_type); +#else + memset(ptr, 0, AVAILABLE_SIZE(mem_pool->pool->power_of_two)); +#endif + } + + return ptr; +} + void * mem_get(struct mem_pool *mem_pool) { @@ -857,6 +900,14 @@ mem_put(void *ptr) /* Not one of ours; don't touch it. */ return; } + + if (!hdr->pool_list) { + gf_msg_callingfn("mem-pool", GF_LOG_CRITICAL, EINVAL, + LG_MSG_INVALID_ARG, + "invalid argument hdr->pool_list NULL"); + return; + } + pool_list = hdr->pool_list; pt_pool = &pool_list->pools[hdr->power_of_two - POOL_SMALLEST]; @@ -879,27 +930,3 @@ mem_put(void *ptr) } #endif /* GF_DISABLE_MEMPOOL */ } - -void -mem_pool_destroy(struct mem_pool *pool) -{ - if (!pool) - return; - - /* remove this pool from the owner (glusterfs_ctx_t) */ - LOCK(&pool->ctx->lock); - { - list_del(&pool->owner); - } - UNLOCK(&pool->ctx->lock); - - /* free this pool, but keep the mem_pool_shared */ - GF_FREE(pool); - - /* - * Pools are now permanent, so the mem_pool->pool is kept around. All - * of the objects *in* the pool will eventually be freed via the - * pool-sweeper thread, and this way we don't have to add a lot of - * reference-counting complexity. - */ -} diff --git a/libglusterfs/src/monitoring.c b/libglusterfs/src/monitoring.c index 45e3d776903..fbb68dc8622 100644 --- a/libglusterfs/src/monitoring.c +++ b/libglusterfs/src/monitoring.c @@ -113,15 +113,15 @@ dump_latency_and_count(xlator_t *xl, int fd) dprintf(fd, "%s.interval.%s.fail_count %" PRIu64 "\n", xl->name, gf_fop_list[index], cbk); } - if (xl->stats.interval.latencies[index].count != 0.0) { + if (xl->stats.interval.latencies[index].count != 0) { dprintf(fd, "%s.interval.%s.latency %lf\n", xl->name, gf_fop_list[index], - (xl->stats.interval.latencies[index].total / + (((double)xl->stats.interval.latencies[index].total) / xl->stats.interval.latencies[index].count)); - dprintf(fd, "%s.interval.%s.max %lf\n", xl->name, + dprintf(fd, "%s.interval.%s.max %" PRIu64 "\n", xl->name, gf_fop_list[index], xl->stats.interval.latencies[index].max); - dprintf(fd, "%s.interval.%s.min %lf\n", xl->name, + dprintf(fd, "%s.interval.%s.min %" PRIu64 "\n", xl->name, gf_fop_list[index], xl->stats.interval.latencies[index].min); } diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c index 400a3901689..f6b5aa0ea23 100644 --- a/libglusterfs/src/options.c +++ b/libglusterfs/src/options.c @@ -25,7 +25,8 @@ xlator_option_validate_path(xlator_t *xl, const char *key, const char *value, if (strstr(value, "../")) { snprintf(errstr, 256, "invalid path given '%s'", value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -35,7 +36,8 @@ xlator_option_validate_path(xlator_t *xl, const char *key, const char *value, "option %s %s: '%s' is not an " "absolute path name", key, value, value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -59,7 +61,8 @@ xlator_option_validate_int(xlator_t *xl, const char *key, const char *value, if (gf_string2longlong(value, &inputll) != 0) { snprintf(errstr, 256, "invalid number format \"%s\" in option \"%s\"", value, key); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -67,7 +70,8 @@ xlator_option_validate_int(xlator_t *xl, const char *key, const char *value, if ((inputll == 0) && (gf_string2ulonglong(value, &uinputll) != 0)) { snprintf(errstr, 256, "invalid number format \"%s\" in option \"%s\"", value, key); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -87,8 +91,8 @@ xlator_option_validate_int(xlator_t *xl, const char *key, const char *value, "'%lld' in 'option %s %s' is smaller than " "minimum value '%.0f'", inputll, key, value, opt->min); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", - errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } } else if (opt->validate == GF_OPT_VALIDATE_MAX) { @@ -97,8 +101,8 @@ xlator_option_validate_int(xlator_t *xl, const char *key, const char *value, "'%lld' in 'option %s %s' is greater than " "maximum value '%.0f'", inputll, key, value, opt->max); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", - errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } } else if ((inputll < opt->min) || (inputll > opt->max)) { @@ -106,7 +110,8 @@ xlator_option_validate_int(xlator_t *xl, const char *key, const char *value, "'%lld' in 'option %s %s' is out of range " "[%.0f - %.0f]", inputll, key, value, opt->min, opt->max); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); goto out; } @@ -129,7 +134,8 @@ xlator_option_validate_sizet(xlator_t *xl, const char *key, const char *value, if (gf_string2bytesize_uint64(value, &size) != 0) { snprintf(errstr, 256, "invalid number format \"%s\" in option \"%s\"", value, key); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); ret = -1; goto out; } @@ -147,7 +153,8 @@ xlator_option_validate_sizet(xlator_t *xl, const char *key, const char *value, "'%" PRIu64 "' in 'option %s %s' is out of range [%.0f - %.0f]", size, key, value, opt->min, opt->max); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); ret = -1; } @@ -171,7 +178,8 @@ xlator_option_validate_bool(xlator_t *xl, const char *key, const char *value, if (gf_string2boolean(value, &is_valid) != 0) { snprintf(errstr, 256, "option %s %s: '%s' is not a valid boolean value", key, value, value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -206,7 +214,8 @@ xlator_option_validate_xlator(xlator_t *xl, const char *key, const char *value, if (!xlopt) { snprintf(errstr, 256, "option %s %s: '%s' is not a valid volume name", key, value, value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -305,7 +314,8 @@ out: char errstr[4096]; set_error_str(errstr, sizeof(errstr), opt, key, value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); if (op_errstr) *op_errstr = gf_strdup(errstr); } @@ -324,7 +334,8 @@ xlator_option_validate_percent(xlator_t *xl, const char *key, const char *value, if (gf_string2percent(value, &percent) != 0) { snprintf(errstr, 256, "invalid percent format \"%s\" in \"option %s\"", value, key); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -332,7 +343,8 @@ xlator_option_validate_percent(xlator_t *xl, const char *key, const char *value, snprintf(errstr, 256, "'%lf' in 'option %s %s' is out of range [0 - 100]", percent, key, value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); goto out; } @@ -378,8 +390,8 @@ xlator_option_validate_percent_or_sizet(xlator_t *xl, const char *key, "'%lf' in 'option %s %s' is out" " of range [0 - 100]", size, key, value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", - errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, + "error=%s", errstr, NULL); goto out; } ret = 0; @@ -394,8 +406,8 @@ xlator_option_validate_percent_or_sizet(xlator_t *xl, const char *key, " %s' should not be fractional value. Use " "valid unsigned integer value.", size, key, value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", - errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -413,8 +425,8 @@ xlator_option_validate_percent_or_sizet(xlator_t *xl, const char *key, "'%lf' in 'option %s %s'" " is out of range [%.0f - %.0f]", size, key, value, opt->min, opt->max); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", - errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); goto out; } ret = 0; @@ -425,7 +437,8 @@ xlator_option_validate_percent_or_sizet(xlator_t *xl, const char *key, snprintf(errstr, 256, "invalid number format \"%s\" in \"option %s\"", value, key); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", errstr, + NULL); out: if (ret && op_errstr) @@ -447,7 +460,8 @@ xlator_option_validate_time(xlator_t *xl, const char *key, const char *value, "invalid time format \"%s\" in " "\"option %s\"", value, key); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -466,7 +480,8 @@ xlator_option_validate_time(xlator_t *xl, const char *key, const char *value, "' in 'option %s %s' is " "out of range [%.0f - %.0f]", input_time, key, value, opt->min, opt->max); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); goto out; } @@ -489,7 +504,8 @@ xlator_option_validate_double(xlator_t *xl, const char *key, const char *value, if (gf_string2double(value, &input) != 0) { snprintf(errstr, 256, "invalid number format \"%s\" in option \"%s\"", value, key); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -509,8 +525,8 @@ xlator_option_validate_double(xlator_t *xl, const char *key, const char *value, "'%f' in 'option %s %s' is smaller than " "minimum value '%f'", input, key, value, opt->min); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", - errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } } else if (opt->validate == GF_OPT_VALIDATE_MAX) { @@ -519,8 +535,8 @@ xlator_option_validate_double(xlator_t *xl, const char *key, const char *value, "'%f' in 'option %s %s' is greater than " "maximum value '%f'", input, key, value, opt->max); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", - errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } } else if ((input < opt->min) || (input > opt->max)) { @@ -528,7 +544,8 @@ xlator_option_validate_double(xlator_t *xl, const char *key, const char *value, "'%f' in 'option %s %s' is out of range " "[%f - %f]", input, key, value, opt->min, opt->max); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); goto out; } @@ -549,7 +566,8 @@ xlator_option_validate_addr(xlator_t *xl, const char *key, const char *value, if (!valid_internet_address((char *)value, _gf_false, _gf_false)) { snprintf(errstr, 256, "option %s %s: Can not parse %s address", key, value, value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); if (op_errstr) *op_errstr = gf_strdup(errstr); } @@ -640,7 +658,8 @@ out: "option %s %s: '%s' is not " "a valid internet-address-list", key, value, value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); if (op_errstr) *op_errstr = gf_strdup(errstr); } @@ -681,7 +700,8 @@ out: "option %s %s: '%s' is not " "a valid mount-auth-address", key, value, value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); if (op_errstr) *op_errstr = gf_strdup(errstr); } @@ -747,20 +767,16 @@ validate_list_elements(const char *string, volume_option_t *opt, key = strtok_r(str_ptr, ":", &substr_sav); if (!key || (key_validator && key_validator(key))) { ret = -1; - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY, - "invalid list '%s', key " - "'%s' not valid.", - string, key ? key : ""); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY, + "list=%s", string, "key=%s", key ? key : "", NULL); goto out; } value = strtok_r(NULL, ":", &substr_sav); if (!value || (value_validator && value_validator(value, opt))) { ret = -1; - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY, - "invalid list '%s', " - "value '%s' not valid.", - string, key); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY, + "list=%s", string, "value=%s", key, NULL); goto out; } @@ -865,8 +881,8 @@ xlator_option_validate(xlator_t *xl, char *key, char *value, }; if (opt->type > GF_OPTION_TYPE_MAX) { - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, - "unknown option type '%d'", opt->type); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_UNKNOWN_OPTION_TYPE, + "type=%d", opt->type, NULL); goto out; } @@ -947,18 +963,16 @@ xl_opt_validate(dict_t *dict, char *key, data_t *value, void *data) ret = xlator_option_validate(xl, key, value->data, opt, &errstr); if (ret) - gf_msg(xl->name, GF_LOG_WARNING, 0, LG_MSG_VALIDATE_RETURNS, - "validate of %s returned %d", key, ret); + gf_smsg(xl->name, GF_LOG_WARNING, 0, LG_MSG_VALIDATE_RETURNS, "key=%s", + key, "ret=%d", ret, NULL); if (errstr) /* possible small leak of previously set stub->errstr */ stub->errstr = errstr; if (fnmatch(opt->key[0], key, FNM_NOESCAPE) != 0) { - gf_msg(xl->name, GF_LOG_DEBUG, 0, LG_MSG_INVALID_ENTRY, - "option '%s' is deprecated, preferred is '%s', " - "continuing with correction", - key, opt->key[0]); + gf_smsg(xl->name, GF_LOG_DEBUG, 0, LG_MSG_OPTION_DEPRECATED, "key=%s", + key, "preferred=%s", opt->key[0], NULL); dict_set(dict, opt->key[0], value); dict_del(dict, key); } @@ -1026,9 +1040,8 @@ xlator_validate_rec(xlator_t *xlator, char **op_errstr) while (trav) { if (xlator_validate_rec(trav->xlator, op_errstr)) { - gf_msg("xlator", GF_LOG_WARNING, 0, LG_MSG_VALIDATE_REC_FAILED, - "validate_rec " - "failed"); + gf_smsg("xlator", GF_LOG_WARNING, 0, LG_MSG_VALIDATE_REC_FAILED, + NULL); goto out; } @@ -1052,8 +1065,8 @@ xlator_validate_rec(xlator_t *xlator, char **op_errstr) THIS = old_THIS; if (ret) { - gf_msg(xlator->name, GF_LOG_INFO, 0, LG_MSG_INVALID_ENTRY, "%s", - *op_errstr); + gf_smsg(xlator->name, GF_LOG_INFO, 0, LG_MSG_INVALID_ENTRY, "%s", + *op_errstr, NULL); goto out; } diff --git a/libglusterfs/src/rbthash.c b/libglusterfs/src/rbthash.c index ae2e158d61e..c90b5a21f44 100644 --- a/libglusterfs/src/rbthash.c +++ b/libglusterfs/src/rbthash.c @@ -56,9 +56,8 @@ __rbthash_init_buckets(rbthash_table_t *tbl, int buckets) tbl->buckets[i].bucket = rb_create( (rb_comparison_func *)rbthash_comparator, tbl, NULL); if (!tbl->buckets[i].bucket) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RB_TABLE_CREATE_FAILED, - "Failed to " - "create rb table bucket"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RB_TABLE_CREATE_FAILED, + NULL); ret = -1; goto err; } @@ -88,20 +87,17 @@ rbthash_table_init(glusterfs_ctx_t *ctx, int buckets, rbt_hasher_t hfunc, int ret = -1; if (!hfunc) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_HASH_FUNC_ERROR, - "Hash function not given"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_HASH_FUNC_ERROR, NULL); return NULL; } if (!entrypool && !expected_entries) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, - "Both mem-pool and expected entries not provided"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_ENTRIES_NOT_PROVIDED, NULL); return NULL; } if (entrypool && expected_entries) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, - "Both mem-pool and expected entries are provided"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_ENTRIES_PROVIDED, NULL); return NULL; } @@ -132,8 +128,8 @@ rbthash_table_init(glusterfs_ctx_t *ctx, int buckets, rbt_hasher_t hfunc, ret = __rbthash_init_buckets(newtab, buckets); if (ret == -1) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INIT_BUCKET_FAILED, - "Failed to init buckets"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INIT_BUCKET_FAILED, + NULL); if (newtab->pool_alloced) mem_pool_destroy(newtab->entrypool); } else { @@ -170,8 +166,8 @@ rbthash_init_entry(rbthash_table_t *tbl, void *data, void *key, int keylen) entry = mem_get(tbl->entrypool); if (!entry) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_ENTRY_FAILED, - "Failed to get entry from mem-pool"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_ENTRY_FAILED, + NULL); goto ret; } @@ -243,8 +239,8 @@ rbthash_insert_entry(rbthash_table_t *tbl, rbthash_entry_t *entry) bucket = rbthash_entry_bucket(tbl, entry); if (!bucket) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED, - "Failed to get bucket"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED, + NULL); goto err; } @@ -253,8 +249,8 @@ rbthash_insert_entry(rbthash_table_t *tbl, rbthash_entry_t *entry) { if (!rb_probe(bucket->bucket, (void *)entry)) { UNLOCK(&bucket->bucketlock); - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED, - "Failed to insert entry"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED, + NULL); ret = -1; goto err; } @@ -276,16 +272,16 @@ rbthash_insert(rbthash_table_t *tbl, void *data, void *key, int keylen) entry = rbthash_init_entry(tbl, data, key, keylen); if (!entry) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INIT_ENTRY_FAILED, - "Failed to init entry"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INIT_ENTRY_FAILED, + NULL); goto err; } ret = rbthash_insert_entry(tbl, entry); if (ret == -1) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED, - "Failed to insert entry"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED, + NULL); rbthash_deinit_entry(tbl, entry); goto err; } @@ -331,8 +327,8 @@ rbthash_get(rbthash_table_t *tbl, void *key, int keylen) bucket = rbthash_key_bucket(tbl, key, keylen); if (!bucket) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_GET_BUCKET_FAILED, - "Failed to get bucket"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED, + NULL); return NULL; } @@ -365,8 +361,8 @@ rbthash_remove(rbthash_table_t *tbl, void *key, int keylen) bucket = rbthash_key_bucket(tbl, key, keylen); if (!bucket) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED, - "Failed to get bucket"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED, + NULL); return NULL; } diff --git a/libglusterfs/src/stack.c b/libglusterfs/src/stack.c index 371f60c4436..1531f0da43f 100644 --- a/libglusterfs/src/stack.c +++ b/libglusterfs/src/stack.c @@ -92,7 +92,7 @@ gf_proc_dump_call_frame(call_frame_t *call_frame, const char *key_buf, ...) }; int ret = -1; - char timestr[256] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; int len; @@ -162,7 +162,7 @@ gf_proc_dump_call_stack(call_stack_t *call_stack, const char *key_buf, ...) va_list ap; call_frame_t *trav; int32_t i = 1, cnt = 0; - char timestr[256] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; int len; diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c index 5e0f04f3217..65f0eb5c7f3 100644 --- a/libglusterfs/src/statedump.c +++ b/libglusterfs/src/statedump.c @@ -199,6 +199,40 @@ gf_proc_dump_write(char *key, char *value, ...) return ret; } +void +gf_latency_statedump_and_reset(char *key, gf_latency_t *lat) +{ + /* Doesn't make sense to continue if there are no fops + came in the given interval */ + if (!lat || !lat->count) + return; + gf_proc_dump_write(key, + "AVG:%lf CNT:%" PRIu64 " TOTAL:%" PRIu64 " MIN:%" PRIu64 + " MAX:%" PRIu64, + (((double)lat->total) / lat->count), lat->count, + lat->total, lat->min, lat->max); + gf_latency_reset(lat); +} + +void +gf_proc_dump_xl_latency_info(xlator_t *xl) +{ + char key_prefix[GF_DUMP_MAX_BUF_LEN]; + char key[GF_DUMP_MAX_BUF_LEN]; + int i; + + snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.latency", xl->name); + gf_proc_dump_add_section("%s", key_prefix); + + for (i = 0; i < GF_FOP_MAXVALUE; i++) { + gf_proc_dump_build_key(key, key_prefix, "%s", (char *)gf_fop_list[i]); + + gf_latency_t *lat = &xl->stats.interval.latencies[i]; + + gf_latency_statedump_and_reset(key, lat); + } +} + static void gf_proc_dump_xlator_mem_info(xlator_t *xl) { @@ -270,7 +304,7 @@ gf_proc_dump_xlator_mem_info_only_in_use(xlator_t *xl) void gf_proc_dump_mem_info() { -#ifdef HAVE_MALLOC_STATS +#ifdef HAVE_MALLINFO struct mallinfo info; memset(&info, 0, sizeof(struct mallinfo)); @@ -296,7 +330,7 @@ gf_proc_dump_mem_info_to_dict(dict_t *dict) { if (!dict) return; -#ifdef HAVE_MALLOC_STATS +#ifdef HAVE_MALLINFO struct mallinfo info; int ret = -1; @@ -349,26 +383,13 @@ gf_proc_dump_mem_info_to_dict(dict_t *dict) void gf_proc_dump_mempool_info(glusterfs_ctx_t *ctx) { +#ifdef GF_DISABLE_MEMPOOL + gf_proc_dump_write("built with --disable-mempool", " so no memory pools"); +#else struct mem_pool *pool = NULL; gf_proc_dump_add_section("mempool"); -#if defined(OLD_MEM_POOLS) - list_for_each_entry(pool, &ctx->mempool_list, global_list) - { - gf_proc_dump_write("-----", "-----"); - gf_proc_dump_write("pool-name", "%s", pool->name); - gf_proc_dump_write("hot-count", "%d", pool->hot_count); - gf_proc_dump_write("cold-count", "%d", pool->cold_count); - gf_proc_dump_write("padded_sizeof", "%lu", pool->padded_sizeof_type); - gf_proc_dump_write("alloc-count", "%" PRIu64, pool->alloc_count); - gf_proc_dump_write("max-alloc", "%d", pool->max_alloc); - - gf_proc_dump_write("pool-misses", "%" PRIu64, pool->pool_misses); - gf_proc_dump_write("cur-stdalloc", "%d", pool->curr_stdalloc); - gf_proc_dump_write("max-stdalloc", "%d", pool->max_stdalloc); - } -#else LOCK(&ctx->lock); { list_for_each_entry(pool, &ctx->mempool_list, owner) @@ -377,6 +398,7 @@ gf_proc_dump_mempool_info(glusterfs_ctx_t *ctx) gf_proc_dump_write("-----", "-----"); gf_proc_dump_write("pool-name", "%s", pool->name); + gf_proc_dump_write("xlator-name", "%s", pool->xl_name); gf_proc_dump_write("active-count", "%" GF_PRI_ATOMIC, active); gf_proc_dump_write("sizeof-type", "%lu", pool->sizeof_type); gf_proc_dump_write("padded-sizeof", "%d", @@ -387,15 +409,13 @@ gf_proc_dump_mempool_info(glusterfs_ctx_t *ctx) } } UNLOCK(&ctx->lock); - - /* TODO: details of (struct mem_pool_shared) pool->pool */ -#endif +#endif /* GF_DISABLE_MEMPOOL */ } void gf_proc_dump_mempool_info_to_dict(glusterfs_ctx_t *ctx, dict_t *dict) { -#if defined(OLD_MEM_POOLS) +#ifndef GF_DISABLE_MEMPOOL struct mem_pool *pool = NULL; char key[GF_DUMP_MAX_BUF_LEN] = { 0, @@ -406,51 +426,47 @@ gf_proc_dump_mempool_info_to_dict(glusterfs_ctx_t *ctx, dict_t *dict) if (!ctx || !dict) return; - list_for_each_entry(pool, &ctx->mempool_list, global_list) + LOCK(&ctx->lock); { - snprintf(key, sizeof(key), "pool%d.name", count); - ret = dict_set_str(dict, key, pool->name); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.hotcount", count); - ret = dict_set_int32(dict, key, pool->hot_count); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.coldcount", count); - ret = dict_set_int32(dict, key, pool->cold_count); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.paddedsizeof", count); - ret = dict_set_uint64(dict, key, pool->padded_sizeof_type); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.alloccount", count); - ret = dict_set_uint64(dict, key, pool->alloc_count); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.max_alloc", count); - ret = dict_set_int32(dict, key, pool->max_alloc); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.max-stdalloc", count); - ret = dict_set_int32(dict, key, pool->max_stdalloc); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.pool-misses", count); - ret = dict_set_uint64(dict, key, pool->pool_misses); - if (ret) - return; - count++; + list_for_each_entry(pool, &ctx->mempool_list, owner) + { + int64_t active = GF_ATOMIC_GET(pool->active); + + snprintf(key, sizeof(key), "pool%d.name", count); + ret = dict_set_str(dict, key, pool->name); + if (ret) + goto out; + + snprintf(key, sizeof(key), "pool%d.active-count", count); + ret = dict_set_uint64(dict, key, active); + if (ret) + goto out; + + snprintf(key, sizeof(key), "pool%d.sizeof-type", count); + ret = dict_set_uint64(dict, key, pool->sizeof_type); + if (ret) + goto out; + + snprintf(key, sizeof(key), "pool%d.padded-sizeof", count); + ret = dict_set_uint64(dict, key, 1 << pool->pool->power_of_two); + if (ret) + goto out; + + snprintf(key, sizeof(key), "pool%d.size", count); + ret = dict_set_uint64(dict, key, + (1 << pool->pool->power_of_two) * active); + if (ret) + goto out; + + snprintf(key, sizeof(key), "pool%d.shared-pool", count); + ret = dict_set_static_ptr(dict, key, pool->pool); + if (ret) + goto out; + } } - ret = dict_set_int32(dict, "mempool-count", count); -#endif +out: + UNLOCK(&ctx->lock); +#endif /* !GF_DISABLE_MEMPOOL */ } void @@ -485,7 +501,7 @@ gf_proc_dump_single_xlator_info(xlator_t *trav) return; if (ctx->measure_latency) - gf_proc_dump_latency_info(trav); + gf_proc_dump_xl_latency_info(trav); gf_proc_dump_xlator_mem_info(trav); @@ -782,7 +798,7 @@ gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx) char brick_name[PATH_MAX] = { 0, }; - char timestr[256] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; char sign_string[512] = { @@ -842,7 +858,7 @@ gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx) ? dump_options.dump_path : ((ctx->statedump_path != NULL) ? ctx->statedump_path : DEFAULT_VAR_RUN_DIRECTORY)), - brick_name, getpid(), (uint64_t)time(NULL)); + brick_name, getpid(), (uint64_t)gf_time()); if ((ret < 0) || (ret >= sizeof(path))) { goto out; } @@ -861,10 +877,7 @@ gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx) // continue even though gettimeofday() has failed ret = gettimeofday(&tv, NULL); if (0 == ret) { - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); - len = strlen(timestr); - snprintf(timestr + len, sizeof timestr - len, ".%" GF_PRI_SUSECONDS, - tv.tv_usec); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); } len = snprintf(sign_string, sizeof(sign_string), "DUMP-START-TIME: %s\n", @@ -913,10 +926,7 @@ gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx) ret = gettimeofday(&tv, NULL); if (0 == ret) { - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); - len = strlen(timestr); - snprintf(timestr + len, sizeof timestr - len, ".%" GF_PRI_SUSECONDS, - tv.tv_usec); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); } len = snprintf(sign_string, sizeof(sign_string), "\nDUMP-END-TIME: %s", @@ -1035,7 +1045,7 @@ gf_proc_dump_xlator_profile(xlator_t *this, strfd_t *strfd) { gf_dump_strfd = strfd; - gf_proc_dump_latency_info(this); + gf_proc_dump_xl_latency_info(this); gf_dump_strfd = NULL; } diff --git a/libglusterfs/src/store.c b/libglusterfs/src/store.c index f444741ef0c..5c316b9291a 100644 --- a/libglusterfs/src/store.c +++ b/libglusterfs/src/store.c @@ -649,23 +649,25 @@ out: } int32_t -gf_store_iter_destroy(gf_store_iter_t *iter) +gf_store_iter_destroy(gf_store_iter_t **iter) { int32_t ret = -1; - if (!iter) + if (!(*iter)) return 0; /* gf_store_iter_new will not return a valid iter object with iter->file * being NULL*/ - ret = fclose(iter->file); + ret = fclose((*iter)->file); if (ret) gf_msg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, "Unable" " to close file: %s, ret: %d", - iter->filepath, ret); + (*iter)->filepath, ret); + + GF_FREE(*iter); + *iter = NULL; - GF_FREE(iter); return ret; } diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c index 2eb7b49fc4c..df20cec559f 100644 --- a/libglusterfs/src/syncop.c +++ b/libglusterfs/src/syncop.c @@ -11,6 +11,10 @@ #include "glusterfs/syncop.h" #include "glusterfs/libglusterfs-messages.h" +#ifdef HAVE_TSAN_API +#include <sanitizer/tsan_interface.h> +#endif + int syncopctx_setfsuid(void *uid) { @@ -97,6 +101,13 @@ syncopctx_setfsgroups(int count, const void *groups) /* set/reset the ngrps, this is where reset of groups is handled */ opctx->ngrps = count; + + if ((opctx->valid & SYNCOPCTX_GROUPS) == 0) { + /* This is the first time we are storing groups into the TLS structure + * so we mark the current thread so that it will be properly cleaned + * up when the thread terminates. */ + gf_thread_needs_cleanup(); + } opctx->valid |= SYNCOPCTX_GROUPS; out: @@ -147,10 +158,14 @@ out: return ret; } +void * +syncenv_processor(void *thdata); + static void __run(struct synctask *task) { struct syncenv *env = NULL; + int32_t total, ret, i; env = task->env; @@ -166,7 +181,6 @@ __run(struct synctask *task) env->runcount--; break; case SYNCTASK_WAIT: - env->waitcount--; break; case SYNCTASK_DONE: gf_msg(task->xl->name, GF_LOG_WARNING, 0, LG_MSG_COMPLETED_TASK, @@ -180,8 +194,27 @@ __run(struct synctask *task) } list_add_tail(&task->all_tasks, &env->runq); - env->runcount++; task->state = SYNCTASK_RUN; + + env->runcount++; + + total = env->procs + env->runcount - env->procs_idle; + if (total > env->procmax) { + total = env->procmax; + } + if (total > env->procs) { + for (i = 0; i < env->procmax; i++) { + if (env->proc[i].env == NULL) { + env->proc[i].env = env; + ret = gf_thread_create(&env->proc[i].processor, NULL, + syncenv_processor, &env->proc[i], + "sproc%d", i); + if ((ret < 0) || (++env->procs >= total)) { + break; + } + } + } + } } static void @@ -203,7 +236,6 @@ __wait(struct synctask *task) gf_msg(task->xl->name, GF_LOG_WARNING, 0, LG_MSG_REWAITING_TASK, "re-waiting already waiting " "task"); - env->waitcount--; break; case SYNCTASK_DONE: gf_msg(task->xl->name, GF_LOG_WARNING, 0, LG_MSG_COMPLETED_TASK, @@ -216,12 +248,11 @@ __wait(struct synctask *task) } list_add_tail(&task->all_tasks, &env->waitq); - env->waitcount++; task->state = SYNCTASK_WAIT; } void -synctask_yield(struct synctask *task) +synctask_yield(struct synctask *task, struct timespec *delta) { xlator_t *oldTHIS = THIS; @@ -230,9 +261,16 @@ synctask_yield(struct synctask *task) task->proc->sched.uc_flags &= ~_UC_TLSBASE; #endif + task->delta = delta; + if (task->state != SYNCTASK_DONE) { task->state = SYNCTASK_SUSPEND; } + +#ifdef HAVE_TSAN_API + __tsan_switch_to_fiber(task->proc->tsan.fiber, 0); +#endif + if (swapcontext(&task->ctx, &task->proc->sched) < 0) { gf_msg("syncop", GF_LOG_ERROR, errno, LG_MSG_SWAPCONTEXT_FAILED, "swapcontext failed"); @@ -242,6 +280,35 @@ synctask_yield(struct synctask *task) } void +synctask_sleep(int32_t secs) +{ + struct timespec delta; + struct synctask *task; + + task = synctask_get(); + + if (task == NULL) { + sleep(secs); + } else { + delta.tv_sec = secs; + delta.tv_nsec = 0; + + synctask_yield(task, &delta); + } +} + +static void +__synctask_wake(struct synctask *task) +{ + task->woken = 1; + + if (task->slept) + __run(task); + + pthread_cond_broadcast(&task->env->cond); +} + +void synctask_wake(struct synctask *task) { struct syncenv *env = NULL; @@ -250,13 +317,18 @@ synctask_wake(struct synctask *task) pthread_mutex_lock(&env->mutex); { - task->woken = 1; + if (task->timer != NULL) { + if (gf_timer_call_cancel(task->xl->ctx, task->timer) != 0) { + goto unlock; + } - if (task->slept) - __run(task); + task->timer = NULL; + task->synccond = NULL; + } - pthread_cond_broadcast(&env->cond); + __synctask_wake(task); } +unlock: pthread_mutex_unlock(&env->mutex); } @@ -275,7 +347,7 @@ synctask_wrap(void) task->state = SYNCTASK_DONE; - synctask_yield(task); + synctask_yield(task, NULL); } void @@ -294,6 +366,10 @@ synctask_destroy(struct synctask *task) pthread_cond_destroy(&task->cond); } +#ifdef HAVE_TSAN_API + __tsan_destroy_fiber(task->tsan.fiber); +#endif + GF_FREE(task); } @@ -404,6 +480,13 @@ synctask_create(struct syncenv *env, size_t stacksize, synctask_fn_t fn, makecontext(&newtask->ctx, (void (*)(void))synctask_wrap, 0); +#ifdef HAVE_TSAN_API + newtask->tsan.fiber = __tsan_create_fiber(0); + snprintf(newtask->tsan.name, TSAN_THREAD_NAMELEN, "<synctask of %s>", + this->name); + __tsan_set_fiber_name(newtask->tsan.fiber, newtask->tsan.name); +#endif + newtask->state = SYNCTASK_INIT; newtask->slept = 1; @@ -415,11 +498,6 @@ synctask_create(struct syncenv *env, size_t stacksize, synctask_fn_t fn, } synctask_wake(newtask); - /* - * Make sure someone's there to execute anything we just put on the - * run queue. - */ - syncenv_scale(env); return newtask; err: @@ -513,8 +591,12 @@ syncenv_task(struct syncproc *proc) goto unlock; } - sleep_till.tv_sec = time(NULL) + SYNCPROC_IDLE_TIME; + env->procs_idle++; + + sleep_till.tv_sec = gf_time() + SYNCPROC_IDLE_TIME; ret = pthread_cond_timedwait(&env->cond, &env->mutex, &sleep_till); + + env->procs_idle--; } task = list_entry(env->runq.next, struct synctask, all_tasks); @@ -533,6 +615,34 @@ unlock: return task; } +static void +synctask_timer(void *data) +{ + struct synctask *task = data; + struct synccond *cond; + + cond = task->synccond; + if (cond != NULL) { + pthread_mutex_lock(&cond->pmutex); + + list_del_init(&task->waitq); + task->synccond = NULL; + + pthread_mutex_unlock(&cond->pmutex); + + task->ret = -ETIMEDOUT; + } + + pthread_mutex_lock(&task->env->mutex); + + gf_timer_call_cancel(task->xl->ctx, task->timer); + task->timer = NULL; + + __synctask_wake(task); + + pthread_mutex_unlock(&task->env->mutex); +} + void synctask_switchto(struct synctask *task) { @@ -548,6 +658,10 @@ synctask_switchto(struct synctask *task) task->ctx.uc_flags &= ~_UC_TLSBASE; #endif +#ifdef HAVE_TSAN_API + __tsan_switch_to_fiber(task->tsan.fiber, 0); +#endif + if (swapcontext(&task->proc->sched, &task->ctx) < 0) { gf_msg("syncop", GF_LOG_ERROR, errno, LG_MSG_SWAPCONTEXT_FAILED, "swapcontext failed"); @@ -565,7 +679,14 @@ synctask_switchto(struct synctask *task) } else { task->slept = 1; __wait(task); + + if (task->delta != NULL) { + task->timer = gf_timer_call_after(task->xl->ctx, *task->delta, + synctask_timer, task); + } } + + task->delta = NULL; } pthread_mutex_unlock(&env->mutex); } @@ -573,63 +694,27 @@ synctask_switchto(struct synctask *task) void * syncenv_processor(void *thdata) { - struct syncenv *env = NULL; struct syncproc *proc = NULL; struct synctask *task = NULL; proc = thdata; - env = proc->env; - for (;;) { - task = syncenv_task(proc); - if (!task) - break; +#ifdef HAVE_TSAN_API + proc->tsan.fiber = __tsan_create_fiber(0); + snprintf(proc->tsan.name, TSAN_THREAD_NAMELEN, "<sched of syncenv@%p>", + proc); + __tsan_set_fiber_name(proc->tsan.fiber, proc->tsan.name); +#endif + while ((task = syncenv_task(proc)) != NULL) { synctask_switchto(task); - - syncenv_scale(env); } - return NULL; -} - -void -syncenv_scale(struct syncenv *env) -{ - int diff = 0; - int scale = 0; - int i = 0; - int ret = 0; - - pthread_mutex_lock(&env->mutex); - { - if (env->procs > env->runcount) - goto unlock; - - scale = env->runcount; - if (scale > env->procmax) - scale = env->procmax; - if (scale > env->procs) - diff = scale - env->procs; - while (diff) { - diff--; - for (; (i < env->procmax); i++) { - if (env->proc[i].processor == 0) - break; - } +#ifdef HAVE_TSAN_API + __tsan_destroy_fiber(proc->tsan.fiber); +#endif - env->proc[i].env = env; - ret = gf_thread_create(&env->proc[i].processor, NULL, - syncenv_processor, &env->proc[i], - "sproc%03hx", env->procs & 0x3ff); - if (ret) - break; - env->procs++; - i++; - } - } -unlock: - pthread_mutex_unlock(&env->mutex); + return NULL; } /* The syncenv threads are cleaned up in this routine. @@ -708,12 +793,13 @@ syncenv_new(size_t stacksize, int procmin, int procmax) newenv->stacksize = stacksize; newenv->procmin = procmin; newenv->procmax = procmax; + newenv->procs_idle = 0; for (i = 0; i < newenv->procmin; i++) { newenv->proc[i].env = newenv; ret = gf_thread_create(&newenv->proc[i].processor, NULL, syncenv_processor, &newenv->proc[i], "sproc%d", - newenv->procs); + i); if (ret) break; newenv->procs++; @@ -803,7 +889,7 @@ __synclock_lock(struct synclock *lock) task->woken = 0; list_add_tail(&task->waitq, &lock->waitq); pthread_mutex_unlock(&lock->guard); - synctask_yield(task); + synctask_yield(task, NULL); /* task is removed from waitq in unlock, * under lock->guard.*/ pthread_mutex_lock(&lock->guard); @@ -956,6 +1042,136 @@ synclock_unlock(synclock_t *lock) return ret; } +/* Condition variables */ + +int32_t +synccond_init(synccond_t *cond) +{ + int32_t ret; + + INIT_LIST_HEAD(&cond->waitq); + + ret = pthread_mutex_init(&cond->pmutex, NULL); + if (ret != 0) { + return -ret; + } + + ret = pthread_cond_init(&cond->pcond, NULL); + if (ret != 0) { + pthread_mutex_destroy(&cond->pmutex); + } + + return -ret; +} + +void +synccond_destroy(synccond_t *cond) +{ + pthread_cond_destroy(&cond->pcond); + pthread_mutex_destroy(&cond->pmutex); +} + +int +synccond_timedwait(synccond_t *cond, synclock_t *lock, struct timespec *delta) +{ + struct timespec now; + struct synctask *task = NULL; + int ret; + + task = synctask_get(); + + if (task == NULL) { + if (delta != NULL) { + timespec_now_realtime(&now); + timespec_adjust_delta(&now, *delta); + } + + pthread_mutex_lock(&cond->pmutex); + + if (delta == NULL) { + ret = -pthread_cond_wait(&cond->pcond, &cond->pmutex); + } else { + ret = -pthread_cond_timedwait(&cond->pcond, &cond->pmutex, &now); + } + } else { + pthread_mutex_lock(&cond->pmutex); + + list_add_tail(&task->waitq, &cond->waitq); + task->synccond = cond; + + ret = synclock_unlock(lock); + if (ret == 0) { + pthread_mutex_unlock(&cond->pmutex); + + synctask_yield(task, delta); + + ret = synclock_lock(lock); + if (ret == 0) { + ret = task->ret; + } + task->ret = 0; + + return ret; + } + + list_del_init(&task->waitq); + } + + pthread_mutex_unlock(&cond->pmutex); + + return ret; +} + +int +synccond_wait(synccond_t *cond, synclock_t *lock) +{ + return synccond_timedwait(cond, lock, NULL); +} + +void +synccond_signal(synccond_t *cond) +{ + struct synctask *task; + + pthread_mutex_lock(&cond->pmutex); + + if (!list_empty(&cond->waitq)) { + task = list_first_entry(&cond->waitq, struct synctask, waitq); + list_del_init(&task->waitq); + + pthread_mutex_unlock(&cond->pmutex); + + synctask_wake(task); + } else { + pthread_cond_signal(&cond->pcond); + + pthread_mutex_unlock(&cond->pmutex); + } +} + +void +synccond_broadcast(synccond_t *cond) +{ + struct list_head list; + struct synctask *task; + + INIT_LIST_HEAD(&list); + + pthread_mutex_lock(&cond->pmutex); + + list_splice_init(&cond->waitq, &list); + pthread_cond_broadcast(&cond->pcond); + + pthread_mutex_unlock(&cond->pmutex); + + while (!list_empty(&list)) { + task = list_first_entry(&list, struct synctask, waitq); + list_del_init(&task->waitq); + + synctask_wake(task); + } +} + /* Barriers */ int @@ -1025,7 +1241,7 @@ __syncbarrier_wait(struct syncbarrier *barrier, int waitfor) /* called within a synctask */ list_add_tail(&task->waitq, &barrier->waitq); pthread_mutex_unlock(&barrier->guard); - synctask_yield(task); + synctask_yield(task, NULL); pthread_mutex_lock(&barrier->guard); } else { /* called by a non-synctask */ @@ -2874,12 +3090,13 @@ syncop_seek(xlator_t *subvol, fd_t *fd, off_t offset, gf_seek_what_t what, SYNCOP(subvol, (&args), syncop_seek_cbk, subvol->fops->seek, fd, offset, what, xdata_in); - if (*off) - *off = args.offset; - - if (args.op_ret == -1) + if (args.op_ret < 0) { return -args.op_errno; - return args.op_ret; + } else { + if (off) + *off = args.offset; + return args.op_ret; + } } int diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c index 1d88c8adac1..04400f98b6c 100644 --- a/libglusterfs/src/syscall.c +++ b/libglusterfs/src/syscall.c @@ -13,6 +13,10 @@ #include "glusterfs/mem-pool.h" #include "glusterfs/libglusterfs-messages.h" +#ifdef __FreeBSD__ +#include <sys/sysctl.h> +#include <signal.h> +#endif #include <sys/types.h> #include <utime.h> #include <sys/time.h> @@ -214,6 +218,15 @@ sys_unlink(const char *pathname) } int +sys_unlinkat(int dfd, const char *pathname) +{ +#ifdef GF_SOLARIS_HOST_OS + return FS_RET_CHECK0(solaris_unlinkat(dfd, pathname, 0), errno); +#endif + return FS_RET_CHECK0(unlinkat(dfd, pathname, 0), errno); +} + +int sys_rmdir(const char *pathname) { return FS_RET_CHECK0(rmdir(pathname), errno); @@ -226,6 +239,12 @@ sys_symlink(const char *oldpath, const char *newpath) } int +sys_symlinkat(const char *oldpath, int dirfd, const char *newpath) +{ + return FS_RET_CHECK0(symlinkat(oldpath, dirfd, newpath), errno); +} + +int sys_rename(const char *oldpath, const char *newpath) { #ifdef GF_SOLARIS_HOST_OS @@ -253,6 +272,12 @@ sys_link(const char *oldpath, const char *newpath) } int +sys_linkat(int oldfd, const char *oldpath, int newfd, const char *newpath) +{ + return FS_RET_CHECK0(linkat(oldfd, oldpath, newfd, newpath, 0), errno); +} + +int sys_chmod(const char *path, mode_t mode) { return FS_RET_CHECK0(chmod(path, mode), errno); @@ -485,7 +510,7 @@ sys_lsetxattr(const char *path, const char *name, const void *value, #endif #ifdef GF_BSD_HOST_OS - return FS_RET_CHECK0( + return FS_RET_CHECK( extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, value, size), errno); #endif @@ -603,7 +628,7 @@ sys_fsetxattr(int filedes, const char *name, const void *value, size_t size, #endif #ifdef GF_BSD_HOST_OS - return FS_RET_CHECK0( + return FS_RET_CHECK( extattr_set_fd(filedes, EXTATTR_NAMESPACE_USER, name, value, size), errno); #endif @@ -828,7 +853,24 @@ sys_copy_file_range(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out, return syscall(SYS_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags); #else - return -ENOSYS; + errno = ENOSYS; + return -1; #endif /* HAVE_COPY_FILE_RANGE_SYS */ #endif /* HAVE_COPY_FILE_RANGE */ } + +#ifdef __FreeBSD__ +int +sys_kill(pid_t pid, int sig) +{ + return FS_RET_CHECK0(kill(pid, sig), errno); +} + +int +sys_sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, + const void *newp, size_t newlen) +{ + return FS_RET_CHECK0(sysctl(name, namelen, oldp, oldlenp, newp, newlen), + errno); +} +#endif diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index 8605fbd0e6f..9a2582d45d5 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -184,9 +184,11 @@ xlator_volopt_dynload(char *xlator_type, void **dl_handle, volume_opt_list_t *opt_list) { int ret = -1; + int flag = 0; char *name = NULL; void *handle = NULL; xlator_api_t *xlapi = NULL; + volume_option_t *opt = NULL; GF_VALIDATE_OR_GOTO("xlator", xlator_type, out); @@ -194,8 +196,10 @@ xlator_volopt_dynload(char *xlator_type, void **dl_handle, * need this check */ if (!strstr(xlator_type, "rpc-transport")) ret = gf_asprintf(&name, "%s/%s.so", XLATORDIR, xlator_type); - else + else { + flag = 1; ret = gf_asprintf(&name, "%s/%s.so", XLATORPARENTDIR, xlator_type); + } if (-1 == ret) { goto out; } @@ -206,24 +210,34 @@ xlator_volopt_dynload(char *xlator_type, void **dl_handle, handle = dlopen(name, RTLD_NOW); if (!handle) { - gf_msg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, "%s", - dlerror()); + gf_smsg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, "error=%s", + dlerror(), NULL); goto out; } - /* check new struct first, and then check this */ - xlapi = dlsym(handle, "xlator_api"); - if (!xlapi) { - gf_msg("xlator", GF_LOG_ERROR, 0, LG_MSG_DLSYM_ERROR, - "dlsym(xlator_api) missing: %s", dlerror()); - goto out; - } + if (flag == 0) { + /* check new struct first, and then check this */ + xlapi = dlsym(handle, "xlator_api"); + if (!xlapi) { + gf_smsg("xlator", GF_LOG_ERROR, 0, LG_MSG_DLSYM_ERROR, "error=%s", + dlerror(), NULL); + goto out; + } - opt_list->given_opt = xlapi->options; - if (!opt_list->given_opt) { - gf_msg("xlator", GF_LOG_ERROR, 0, LG_MSG_LOAD_FAILED, - "Failed to load xlator options table"); - goto out; + opt_list->given_opt = xlapi->options; + if (!opt_list->given_opt) { + gf_smsg("xlator", GF_LOG_ERROR, 0, LG_MSG_LOAD_FAILED, NULL); + goto out; + } + } else { + opt = dlsym(handle, "options"); + if (!opt) { + gf_smsg("xlator", GF_LOG_ERROR, 0, LG_MSG_DLSYM_ERROR, "error=%s", + dlerror(), NULL); + goto out; + } + + opt_list->given_opt = opt; } *dl_handle = handle; @@ -246,21 +260,22 @@ xlator_dynload_apis(xlator_t *xl) void *handle = NULL; volume_opt_list_t *vol_opt = NULL; xlator_api_t *xlapi = NULL; + int i = 0; handle = xl->dlhandle; xlapi = dlsym(handle, "xlator_api"); if (!xlapi) { - gf_msg("xlator", GF_LOG_ERROR, 0, LG_MSG_DLSYM_ERROR, - "dlsym(xlator_api) missing: %s", dlerror()); + gf_smsg("xlator", GF_LOG_ERROR, 0, LG_MSG_DLSYM_ERROR, "dlsym=%s", + dlerror(), NULL); ret = -1; goto out; } xl->fops = xlapi->fops; if (!xl->fops) { - gf_msg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, - "%s: struct missing (fops)", xl->name); + gf_smsg("xlator", GF_LOG_WARNING, 0, LG_MSG_STRUCT_MISS, "name=%s", + xl->name, NULL); goto out; } @@ -271,8 +286,8 @@ xlator_dynload_apis(xlator_t *xl) xl->init = xlapi->init; if (!xl->init) { - gf_msg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, - "%s: method missing (init)", xl->name); + gf_smsg("xlator", GF_LOG_WARNING, 0, LG_MSG_METHOD_MISS, "name=%s", + xl->name, NULL); goto out; } @@ -343,6 +358,10 @@ xlator_dynload_apis(xlator_t *xl) memcpy(xl->op_version, xlapi->op_version, sizeof(uint32_t) * GF_MAX_RELEASES); + for (i = 0; i < GF_FOP_MAXVALUE; i++) { + gf_latency_reset(&xl->stats.interval.latencies[i]); + } + ret = 0; out: return ret; @@ -370,8 +389,8 @@ xlator_dynload(xlator_t *xl) handle = dlopen(name, RTLD_NOW); if (!handle) { - gf_msg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, "%s", - dlerror()); + gf_smsg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, "error=%s", + dlerror(), NULL); goto out; } xl->dlhandle = handle; @@ -438,10 +457,8 @@ xlator_set_inode_lru_limit(xlator_t *this, void *data) if (this->itable) { if (!data) { - gf_msg(this->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY, - "input data is NULL. " - "Cannot update the lru limit of the inode" - " table. Continuing with older value"); + gf_smsg(this->name, GF_LOG_WARNING, 0, LG_MSG_INPUT_DATA_NULL, + NULL); goto out; } inode_lru_limit = *(int *)data; @@ -615,18 +632,15 @@ xlator_init(xlator_t *xl) xl->instance_name = NULL; GF_ATOMIC_INIT(xl->xprtrefcnt, 0); if (!xl->init) { - gf_msg(xl->name, GF_LOG_WARNING, 0, LG_MSG_INIT_FAILED, - "No init() found"); + gf_smsg(xl->name, GF_LOG_WARNING, 0, LG_MSG_INIT_FAILED, NULL); goto out; } ret = __xlator_init(xl); if (ret) { - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_VOLUME_ERROR, - "Initialization of volume '%s' failed," - " review your volfile again", - xl->name); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_VOLUME_ERROR, "name=%s", + xl->name, NULL); goto out; } @@ -812,7 +826,7 @@ xlator_members_free(xlator_t *xl) GF_FREE(xl->name); GF_FREE(xl->type); - if (!(xl->ctx && xl->ctx->cmd_args.valgrind) && xl->dlhandle) + if (!(xl->ctx && xl->ctx->cmd_args.vgtool != _gf_none) && xl->dlhandle) dlclose(xl->dlhandle); if (xl->options) dict_unref(xl->options); @@ -862,8 +876,7 @@ xlator_tree_free_members(xlator_t *tree) xlator_t *prev = tree; if (!tree) { - gf_msg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, - "Translator tree not found"); + gf_smsg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, NULL); return -1; } @@ -883,8 +896,7 @@ xlator_tree_free_memacct(xlator_t *tree) xlator_t *prev = tree; if (!tree) { - gf_msg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, - "Translator tree not found"); + gf_smsg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, NULL); return -1; } @@ -945,6 +957,8 @@ xlator_mem_cleanup(xlator_t *this) xlator_list_t **trav_p = NULL; xlator_t *top = NULL; xlator_t *victim = NULL; + glusterfs_graph_t *graph = NULL; + gf_boolean_t graph_cleanup = _gf_false; if (this->call_cleanup || !this->ctx) return; @@ -952,6 +966,12 @@ xlator_mem_cleanup(xlator_t *this) this->call_cleanup = 1; ctx = this->ctx; + inode_table = this->itable; + if (inode_table) { + inode_table_destroy(inode_table); + this->itable = NULL; + } + xlator_call_fini(trav); while (prev) { @@ -960,12 +980,6 @@ xlator_mem_cleanup(xlator_t *this) prev = trav; } - inode_table = this->itable; - if (inode_table) { - inode_table_destroy(inode_table); - this->itable = NULL; - } - if (this->fini) { this->fini(this); } @@ -975,17 +989,28 @@ xlator_mem_cleanup(xlator_t *this) if (ctx->active) { top = ctx->active->first; LOCK(&ctx->volfile_lock); - /* TODO here we have leak for xlator node in a graph */ - /* Need to move only top xlator from a graph */ for (trav_p = &top->children; *trav_p; trav_p = &(*trav_p)->next) { victim = (*trav_p)->xlator; if (victim->call_cleanup && !strcmp(victim->name, this->name)) { + graph_cleanup = _gf_true; (*trav_p) = (*trav_p)->next; break; } } UNLOCK(&ctx->volfile_lock); } + + if (graph_cleanup) { + prev = this; + graph = ctx->active; + pthread_mutex_lock(&graph->mutex); + while (prev) { + trav = prev->next; + GF_FREE(prev); + prev = trav; + } + pthread_mutex_unlock(&graph->mutex); + } } void @@ -1344,9 +1369,9 @@ is_gf_log_command(xlator_t *this, const char *name, char *value, size_t size) /* Some crude way to change the log-level of process */ if (!strcmp(name, "trusted.glusterfs.set-log-level")) { - gf_msg("glusterfs", gf_log_get_loglevel(), 0, LG_MSG_SET_LOG_LEVEL, - "setting log level to %d (old-value=%d)", log_level, - gf_log_get_loglevel()); + gf_smsg("glusterfs", gf_log_get_loglevel(), 0, LG_MSG_SET_LOG_LEVEL, + "new-value=%d", log_level, "old-value=%d", + gf_log_get_loglevel(), NULL); gf_log_set_loglevel(this->ctx, log_level); ret = 0; goto out; @@ -1354,9 +1379,9 @@ is_gf_log_command(xlator_t *this, const char *name, char *value, size_t size) if (!strcmp(name, "trusted.glusterfs.fuse.set-log-level")) { /* */ - gf_msg(this->name, gf_log_get_xl_loglevel(this), 0, - LG_MSG_SET_LOG_LEVEL, "setting log level to %d (old-value=%d)", - log_level, gf_log_get_xl_loglevel(this)); + gf_smsg(this->name, gf_log_get_xl_loglevel(this), 0, + LG_MSG_SET_LOG_LEVEL, "new-value=%d", log_level, "old-value=%d", + gf_log_get_xl_loglevel(this), NULL); gf_log_set_xl_loglevel(this, log_level); ret = 0; goto out; @@ -1372,10 +1397,9 @@ is_gf_log_command(xlator_t *this, const char *name, char *value, size_t size) while (trav) { snprintf(key, 1024, "trusted.glusterfs.%s.set-log-level", trav->name); if (fnmatch(name, key, FNM_NOESCAPE) == 0) { - gf_msg(trav->name, gf_log_get_xl_loglevel(trav), 0, - LG_MSG_SET_LOG_LEVEL, - "setting log level to %d (old-value=%d)", log_level, - gf_log_get_xl_loglevel(trav)); + gf_smsg(trav->name, gf_log_get_xl_loglevel(trav), 0, + LG_MSG_SET_LOG_LEVEL, "new-value%d", log_level, + "old-value=%d", gf_log_get_xl_loglevel(trav), NULL); gf_log_set_xl_loglevel(trav, log_level); ret = 0; } @@ -1407,9 +1431,7 @@ glusterd_check_log_level(const char *value) } if (log_level == -1) - gf_msg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INIT_FAILED, - "Invalid log-level. possible values are " - "DEBUG|WARNING|ERROR|CRITICAL|NONE|TRACE"); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_INIT, NULL); return log_level; } @@ -1486,8 +1508,7 @@ gluster_graph_take_reference(xlator_t *tree) xlator_t *prev = tree; if (!tree) { - gf_msg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, - "Translator tree not found"); + gf_smsg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, NULL); return; } @@ -1524,15 +1545,15 @@ xlator_is_cleanup_starting(xlator_t *this) xlator_t *xl = NULL; if (!this) { - gf_msg("xlator", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG, - "xlator object is null, returning false"); + gf_smsg("xlator", GF_LOG_WARNING, EINVAL, LG_MSG_OBJECT_NULL, "xlator", + NULL); goto out; } graph = this->graph; if (!graph) { - gf_msg("xlator", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG, - "Graph is not set for xlator %s", this->name); + gf_smsg("xlator", GF_LOG_WARNING, EINVAL, LG_MSG_GRAPH_NOT_SET, + "name=%s", this->name, NULL); goto out; } @@ -1550,12 +1571,17 @@ graph_total_client_xlator(glusterfs_graph_t *graph) int count = 0; if (!graph) { - gf_msg("xlator", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG, - "graph object is null"); + gf_smsg("xlator", GF_LOG_WARNING, EINVAL, LG_MSG_OBJECT_NULL, "graph", + NULL); goto out; } xl = graph->first; + if (!strcmp(xl->type, "protocol/server")) { + gf_msg_debug(xl->name, 0, "Return because it is a server graph"); + return 0; + } + while (xl) { if (strcmp(xl->type, "protocol/client") == 0) { count++; @@ -4,7 +4,29 @@ # i.e. where we are interested in the result of a command, # we have to run the command in an if-statement. -ORIGIN=${GLUSTER_ORIGIN:-origin} +UPSTREAM=${GLUSTER_UPSTREAM} +if [ "x$UPSTREAM" -eq "x" ]; then + for rmt in $(git remote); do + rmt_repo=$(git remote show $rmt -n | grep Fetch | awk '{ print $3 }'); + if [ $rmt_repo -eq "git@github:gluster/glusterfs" ]; then + UPSTREAM=$rmt + echo "Picked $rmt as upstream remote" + break + fi + done +fi + +USER_REPO=${GLUSTER_USER_REPO:-origin} +if [ "x${USER_REPO}" -eq "x${UPSTREAM}" ] ; then + echo "When you submit patches, it should get submitted to your fork, not to upstream directly" + echo "If you are not sure, check `for rmt in $(git remote); do git remote show $rmt -n; done`" + echo "And pick the correct remote you would like to push to and do `export GLUSTER_USER_REPO=$rmt`" + echo "" + echo "Exiting..." + exit 1 +fi + + while getopts "v" opt; do case $opt in @@ -18,7 +40,7 @@ done shift $((OPTIND-1)) -branch="master"; +branch="devel"; set_hooks_commit_msg() { @@ -50,21 +72,21 @@ is_num() backport_id_message() { echo "" - echo "This commit is to a non-master branch, and hence is treated as a backport." + echo "This commit is to a non-devel branch, and hence is treated as a backport." echo "" echo "For backports we would like to retain the same gerrit Change-Id across" echo "branches. On auto inspection it is found that a gerrit Change-Id is" - echo "missing, or the Change-Id is not found on your local master" + echo "missing, or the Change-Id is not found on your local devel branch" echo "" echo "This could mean a few things:" echo " 1. This is not a backport, hence choose Y on the prompt to proceed" - echo " 2. Your $ORIGIN master is not up to date, hence the script is unable" - echo " to find the corresponding Change-Id on master. Either choose N," + echo " 2. Your $USER_REPO/devel is not up to date, hence the script is unable" + echo " to find the corresponding Change-Id on devel. Either choose N," echo " 'git fetch', and try again, OR if you are sure you used the" echo " same Change-Id, choose Y at the prompt to proceed" echo " 3. You commented or removed the Change-Id in your commit message after" echo " cherry picking the commit. Choose N, fix the commit message to" - echo " use the same Change-Id as master (git commit --amend), resubmit" + echo " use the same Change-Id as 'devel' (git commit --amend), resubmit" echo "" } @@ -72,8 +94,8 @@ check_backport() { moveon='N' - # Backports are never made to master - if [ $branch = "master" ]; then + # Backports are never made to 'devel' + if [ $branch = "devel" ]; then return; fi @@ -86,22 +108,22 @@ check_backport() echo -n "Did not find a Change-Id for a possible backport. Continue (y/N): " read moveon else - # Search master for the same change ID (rebase_changes has run, so we + # Search 'devel' for the same change ID (rebase_changes has run, so we # should never not find a Change-Id) - mchangeid=$(git log $ORIGIN/master --format='%b' --grep="^Change-Id: ${changeid}" | grep ${changeid} | awk '{print $2}') + mchangeid=$(git log $UPSTREAM/devel --format='%b' --grep="^Change-Id: ${changeid}" | grep ${changeid} | awk '{print $2}') - # Check if we found the change ID on master, else throw a message to + # Check if we found the change ID on 'devel', else throw a message to # decide if we should continue. - # NOTE: If master was not rebased, we will not find the Change-ID and + # NOTE: If 'devel' was not rebased, we will not find the Change-ID and # could hit a false positive case here (or if someone checks out some - # other branch as master). + # other branch as 'devel'). if [ "${mchangeid}" = "${changeid}" ]; then moveon="Y" else backport_id_message; echo "Change-Id of commit: $changeid" - echo "Change-Id on master: $mchangeid" - echo -n "Did not find mentioned Change-Id on master for a possible backport. Continue (y/N): " + echo "Change-Id on devel: $mchangeid" + echo -n "Did not find mentioned Change-Id on 'devel' for a possible backport. Continue (y/N): " read moveon fi fi @@ -116,7 +138,7 @@ check_backport() rebase_changes() { - GIT_EDITOR=$0 git rebase -i $ORIGIN/$branch; + GIT_EDITOR=$0 git rebase -i $UPSTREAM/$branch; } @@ -154,15 +176,12 @@ rebase_changes() # [[:space:]]+ # Followed by 1 or more spaces # -# (gluster\/glusterfs|bz)? -# Followed by nothing, 'gluster/glusterfs' or 'bz' -# # # # Followed by # # # [[:digit:]]+ # Followed by 1 or more digits -REFRE="^[[:space:]]*(Fixes|Updates)(:)?[[:space:]]+(gluster\/glusterfs|bz)?#[[:digit:]]+" +REFRE="^[[:space:]]*(Fixes|Updates)(:)?[[:space:]]+#[[:digit:]]+" editor_mode() { @@ -181,22 +200,17 @@ editor_mode() while true; do echo Commit: "\"$(head -n 1 $1)\"" - echo -n "Reference (Bugzilla ID or Github Issue ID): " - read bug - if [ -z "$bug" ]; then + echo -n "Github Issue ID: " + read issue + if [ -z "$issue" ]; then return; fi - if ! is_num "$bug"; then - echo "Invalid reference ID ($bug)!!!"; + if ! is_num "$issue"; then + echo "Invalid Github Issue ID!!!"; continue; fi - bz_string="bz" - if [ $bug -lt 742000 ]; then - bz_string="" - fi - - echo "Select yes '(y)' if this patch fixes the bug/feature completely," + echo "Select yes '(y)' if this patch fixes the issue/feature completely," echo -n "or is the last of the patchset which brings feature (Y/n): " read fixes fixes_string="Fixes" @@ -204,7 +218,7 @@ editor_mode() fixes_string="Updates" fi - sed "/^Change-Id:/{p; s/^.*$/${fixes_string}: ${bz_string}#${bug}/;}" $1 > $1.new && \ + sed "/^Change-Id:/{p; s/^.*$/${fixes_string}: #${issue}/;}" $1 > $1.new && \ mv $1.new $1; return; done @@ -220,7 +234,7 @@ EOF assert_diverge() { - git diff $ORIGIN/$branch..HEAD | grep -q .; + git diff $UPSTREAM/$branch..HEAD | grep -q .; } @@ -229,34 +243,24 @@ warn_reference_missing() echo "" echo "=== Missing a reference in commit! ===" echo "" - echo "Gluster commits are made with a reference to a bug or a github issue" - echo "" - echo "Submissions that are enhancements (IOW, not functional" - echo "bug fixes, but improvements of any nature to the code) are tracked" - echo "using github issues [1]." + echo "Gluster commits are made with a reference to a github issue" echo "" - echo "Submissions that are bug fixes are tracked using Bugzilla [2]." + echo "A check on the commit message, reveals that there is no " + echo "github issue referenced in the commit message." echo "" - echo "A check on the commit message, reveals that there is no bug or" - echo "github issue referenced in the commit message" + echo "https://github.com/gluster/glusterfs/issues/new" echo "" - echo "[1] https://github.com/gluster/glusterfs/issues/new" - echo "[2] https://bugzilla.redhat.com/enter_bug.cgi?product=GlusterFS" + echo "Please open an issue and reference the same in the commit message " + echo "using the following tags:" echo "" - echo "Please file an issue or a bug report and reference the same in the" - echo "commit message using the following tags:" - echo "GitHub Issues:" - echo "\"Fixes: gluster/glusterfs#n\" OR \"Updates: gluster/glusterfs#n\"," - echo "\"Fixes: #n\" OR \"Updates: #n\"," - echo "Bugzilla ID:" - echo "\"Fixes: bz#n\" OR \"Updates: bz#n\"," - echo "where n is the issue or bug number" + echo "\"Fixes: #NNNN\" OR \"Updates: #NNNN\"," + echo "where NNNN is the issue id" echo "" echo "You may abort the submission choosing 'N' below and use" echo "'git commit --amend' to add the issue reference before posting" echo "to gerrit." echo "" - echo -n "Missing reference to a bug or a github issue. Continue (y/N): " + echo -n "Missing reference to a github issue. Continue (y/N): " read moveon if [ "${moveon}" = 'Y' ] || [ "${moveon}" = 'y' ]; then return; @@ -276,7 +280,7 @@ main() return; fi - git fetch $ORIGIN; + git fetch $UPSTREAM; rebase_changes; @@ -287,9 +291,9 @@ main() # see note above variable REFRE for regex elaboration reference=$(git log -n1 --format='%b' | grep -iow -E "${REFRE}" | awk -F '#' '{print $2}'); - # If this is a commit against master and does not have a bug ID or a github + # If this is a commit against 'devel' and does not have a github # issue reference. Warn the contributor that one of the 2 is required - if [ -z "${reference}" ] && [ $branch = "master" ]; then + if [ -z "${reference}" ] && [ $branch = "devel" ]; then warn_reference_missing; fi @@ -317,9 +321,9 @@ main() fi if [ -z "${reference}" ]; then - $drier git push $ORIGIN HEAD:refs/for/$branch/rfc; + $drier git push $USER_REPO HEAD:temp_${branch}/$(date +%Y-%m-%d_%s); else - $drier git push $ORIGIN HEAD:refs/for/$branch/ref-${reference}; + $drier git push $USER_REPO HEAD:issue${reference}_${branch}; fi } diff --git a/rpc/rpc-lib/src/Makefile.am b/rpc/rpc-lib/src/Makefile.am index 81a96476883..35c9db07e7f 100644 --- a/rpc/rpc-lib/src/Makefile.am +++ b/rpc/rpc-lib/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libgfrpc.la libgfrpc_la_SOURCES = auth-unix.c rpcsvc-auth.c rpcsvc.c auth-null.c \ rpc-transport.c xdr-rpc.c xdr-rpcclnt.c rpc-clnt.c auth-glusterfs.c \ - rpc-drc.c $(CONTRIBDIR)/sunrpc/xdr_sizeof.c rpc-clnt-ping.c \ + rpc-drc.c rpc-clnt-ping.c \ autoscale-threads.c mgmt-pmap.c EXTRA_DIST = libgfrpc.sym diff --git a/rpc/rpc-lib/src/libgfrpc.sym b/rpc/rpc-lib/src/libgfrpc.sym index 54d1be1112f..e026d80259b 100644 --- a/rpc/rpc-lib/src/libgfrpc.sym +++ b/rpc/rpc-lib/src/libgfrpc.sym @@ -65,3 +65,4 @@ rpc_transport_unix_options_build rpc_transport_unref rpc_clnt_mgmt_pmap_signout rpcsvc_autoscale_threads +rpcsvc_statedump diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index 7275d7568b6..0cb5862e9a9 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -309,6 +309,7 @@ enum glusterd_mgmt_v3_procnum { GLUSTERD_MGMT_V3_PRE_VALIDATE, GLUSTERD_MGMT_V3_BRICK_OP, GLUSTERD_MGMT_V3_COMMIT, + GLUSTERD_MGMT_V3_POST_COMMIT, GLUSTERD_MGMT_V3_POST_VALIDATE, GLUSTERD_MGMT_V3_UNLOCK, GLUSTERD_MGMT_V3_MAXVALUE, diff --git a/rpc/rpc-lib/src/rpc-clnt-ping.c b/rpc/rpc-lib/src/rpc-clnt-ping.c index 2298ef6394f..31f17841bea 100644 --- a/rpc/rpc-lib/src/rpc-clnt-ping.c +++ b/rpc/rpc-lib/src/rpc-clnt-ping.c @@ -122,7 +122,7 @@ rpc_clnt_ping_timer_expired(void *rpc_ptr) goto out; } - clock_gettime(CLOCK_REALTIME, ¤t); + timespec_now_realtime(¤t); pthread_mutex_lock(&conn->lock); { unref = rpc_clnt_remove_ping_timer_locked(rpc); diff --git a/rpc/rpc-lib/src/rpc-clnt.c b/rpc/rpc-lib/src/rpc-clnt.c index dac707664df..517037c4a5d 100644 --- a/rpc/rpc-lib/src/rpc-clnt.c +++ b/rpc/rpc-lib/src/rpc-clnt.c @@ -97,7 +97,7 @@ call_bail(void *data) struct saved_frame *saved_frame = NULL; struct saved_frame *trav = NULL; struct saved_frame *tmp = NULL; - char frame_sent[256] = { + char frame_sent[GF_TIMESTR_SIZE] = { 0, }; struct timespec timeout = { @@ -105,7 +105,6 @@ call_bail(void *data) }; char peerid[UNIX_PATH_MAX] = {0}; gf_boolean_t need_unref = _gf_false; - int len; GF_VALIDATE_OR_GOTO("client", data, out); @@ -165,11 +164,8 @@ call_bail(void *data) list_for_each_entry_safe(trav, tmp, &list, list) { - gf_time_fmt(frame_sent, sizeof frame_sent, trav->saved_at.tv_sec, - gf_timefmt_FT); - len = strlen(frame_sent); - snprintf(frame_sent + len, sizeof(frame_sent) - len, - ".%" GF_PRI_SUSECONDS, trav->saved_at.tv_usec); + gf_time_fmt_tv(frame_sent, sizeof frame_sent, &trav->saved_at, + gf_timefmt_FT); gf_log(conn->name, GF_LOG_ERROR, "bailing out frame type(%s), op(%s(%d)), xid = 0x%x, " @@ -317,20 +313,15 @@ saved_frames_unwind(struct saved_frames *saved_frames) { struct saved_frame *trav = NULL; struct saved_frame *tmp = NULL; - char timestr[1024] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; - int len; list_splice_init(&saved_frames->lk_sf.list, &saved_frames->sf.list); list_for_each_entry_safe(trav, tmp, &saved_frames->sf.list, list) { - gf_time_fmt(timestr, sizeof timestr, trav->saved_at.tv_sec, - gf_timefmt_FT); - len = strlen(timestr); - snprintf(timestr + len, sizeof(timestr) - len, ".%" GF_PRI_SUSECONDS, - trav->saved_at.tv_usec); + gf_time_fmt_tv(timestr, sizeof timestr, &trav->saved_at, gf_timefmt_FT); if (!trav->rpcreq || !trav->rpcreq->prog) continue; @@ -928,7 +919,7 @@ rpc_clnt_notify(rpc_transport_t *trans, void *mydata, } case RPC_TRANSPORT_MSG_RECEIVED: { - clock_gettime(CLOCK_REALTIME, &conn->last_received); + timespec_now_realtime(&conn->last_received); pollin = data; if (pollin->is_reply) @@ -942,8 +933,7 @@ rpc_clnt_notify(rpc_transport_t *trans, void *mydata, } case RPC_TRANSPORT_MSG_SENT: { - clock_gettime(CLOCK_REALTIME, &conn->last_sent); - + timespec_now_realtime(&conn->last_sent); ret = 0; break; } @@ -960,6 +950,7 @@ rpc_clnt_notify(rpc_transport_t *trans, void *mydata, conn->config.remote_port = 0; conn->connected = 1; conn->disconnected = 0; + pthread_cond_broadcast(&conn->cond); } pthread_mutex_unlock(&conn->lock); @@ -1005,6 +996,7 @@ rpc_clnt_connection_init(struct rpc_clnt *clnt, glusterfs_ctx_t *ctx, conn = &clnt->conn; pthread_mutex_init(&clnt->conn.lock, NULL); + pthread_cond_init(&clnt->conn.cond, NULL); conn->name = gf_strdup(name); if (!conn->name) { @@ -1830,6 +1822,7 @@ rpc_clnt_destroy(struct rpc_clnt *rpc) saved_frames_destroy(saved_frames); pthread_mutex_destroy(&rpc->lock); pthread_mutex_destroy(&rpc->conn.lock); + pthread_cond_destroy(&rpc->conn.cond); /* mem-pool should be destroyed, otherwise, it will cause huge memory leaks */ diff --git a/rpc/rpc-lib/src/rpc-clnt.h b/rpc/rpc-lib/src/rpc-clnt.h index 0d0b115578c..2945265200b 100644 --- a/rpc/rpc-lib/src/rpc-clnt.h +++ b/rpc/rpc-lib/src/rpc-clnt.h @@ -127,6 +127,7 @@ struct rpc_clnt_config { struct rpc_clnt_connection { pthread_mutex_t lock; + pthread_cond_t cond; rpc_transport_t *trans; struct rpc_clnt_config config; gf_timer_t *reconnect; diff --git a/rpc/rpc-lib/src/rpc-drc.c b/rpc/rpc-lib/src/rpc-drc.c index d083db24fc5..de8dc630626 100644 --- a/rpc/rpc-lib/src/rpc-drc.c +++ b/rpc/rpc-lib/src/rpc-drc.c @@ -190,7 +190,7 @@ rpcsvc_get_drc_client(rpcsvc_drc_globals_t *drc, if (!client) goto out; - client->ref = 0; + GF_ATOMIC_INIT(client->ref, 0); client->sock_union = (union gf_sock_union) * sockaddr; client->op_count = 0; INIT_LIST_HEAD(&client->client_list); @@ -246,7 +246,7 @@ static drc_client_t * rpcsvc_drc_client_ref(drc_client_t *client) { GF_ASSERT(client); - client->ref++; + GF_ATOMIC_INC(client->ref); return client; } @@ -261,11 +261,12 @@ rpcsvc_drc_client_ref(drc_client_t *client) static drc_client_t * rpcsvc_drc_client_unref(rpcsvc_drc_globals_t *drc, drc_client_t *client) { + uint32_t refcount; + GF_ASSERT(drc); - GF_ASSERT(client->ref); - client->ref--; - if (!client->ref) { + refcount = GF_ATOMIC_DEC(client->ref); + if (!refcount) { drc->client_count--; rpcsvc_remove_drc_client(client); client = NULL; @@ -589,7 +590,7 @@ rpcsvc_drc_priv(rpcsvc_drc_globals_t *drc) } gf_proc_dump_build_key(key, "client", "%d.ref_count", i); - gf_proc_dump_write(key, "%d", client->ref); + gf_proc_dump_write(key, "%" PRIu32, GF_ATOMIC_GET(client->ref)); gf_proc_dump_build_key(key, "client", "%d.op_count", i); gf_proc_dump_write(key, "%d", client->op_count); i++; diff --git a/rpc/rpc-lib/src/rpc-drc.h b/rpc/rpc-lib/src/rpc-drc.h index 6aaede0828a..ce66430809b 100644 --- a/rpc/rpc-lib/src/rpc-drc.h +++ b/rpc/rpc-lib/src/rpc-drc.h @@ -24,7 +24,7 @@ struct drc_client { struct rb_table *rbtree; /* no. of ops currently cached */ uint32_t op_count; - uint32_t ref; + gf_atomic_uint32_t ref; struct list_head client_list; }; diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c index 623523c09d2..39910d481bf 100644 --- a/rpc/rpc-lib/src/rpcsvc.c +++ b/rpc/rpc-lib/src/rpcsvc.c @@ -13,6 +13,7 @@ #include <glusterfs/dict.h> #include <glusterfs/byte-order.h> #include <glusterfs/compat-errno.h> +#include <glusterfs/statedump.h> #include "xdr-rpc.h" #include <glusterfs/iobuf.h> #include "xdr-common.h" @@ -41,6 +42,10 @@ #include "xdr-rpcclnt.h" #include <glusterfs/glusterfs-acl.h> +#ifndef PTHREAD_MUTEX_ADAPTIVE_NP +#define PTHREAD_MUTEX_ADAPTIVE_NP PTHREAD_MUTEX_DEFAULT +#endif + static struct rpcsvc_program gluster_dump_prog; #define rpcsvc_alloc_request(svc, request) \ @@ -66,59 +71,33 @@ rpcsvc_request_handler(void *arg); static int rpcsvc_match_subnet_v4(const char *addrtok, const char *ipaddr); -void +static void rpcsvc_toggle_queue_status(rpcsvc_program_t *prog, - rpcsvc_request_queue_t *queue, char status[]) + rpcsvc_request_queue_t *queue, + unsigned long status[]) { - int queue_index = 0, status_index = 0, set_bit = 0; - - if (queue != &prog->request_queue[0]) { - queue_index = (queue - &prog->request_queue[0]); - } - - status_index = queue_index / 8; - set_bit = queue_index % 8; - - status[status_index] ^= (1 << set_bit); + unsigned queue_index = queue - prog->request_queue; - return; + status[queue_index / __BITS_PER_LONG] ^= (1UL << (queue_index % + __BITS_PER_LONG)); } int rpcsvc_get_free_queue_index(rpcsvc_program_t *prog) { - int queue_index = 0, max_index = 0, i = 0; - unsigned int right_most_unset_bit = 0; - - right_most_unset_bit = 8; + unsigned i, j = 0; - max_index = gf_roof(EVENT_MAX_THREADS, 8) / 8; - for (i = 0; i < max_index; i++) { - if (prog->request_queue_status[i] == 0) { - right_most_unset_bit = 0; + for (i = 0; i < EVENT_MAX_THREADS / __BITS_PER_LONG; i++) + if (prog->request_queue_status[i] != ULONG_MAX) { + j = __builtin_ctzl(~prog->request_queue_status[i]); break; - } else { - /* get_rightmost_set_bit (sic)*/ - right_most_unset_bit = __builtin_ctz( - ~prog->request_queue_status[i]); - if (right_most_unset_bit < 8) { - break; - } } - } - - if (right_most_unset_bit > 7) { - queue_index = -1; - } else { - queue_index = i * 8; - queue_index += right_most_unset_bit; - } - if (queue_index != -1) { - prog->request_queue_status[i] |= (0x1 << right_most_unset_bit); - } + if (i == EVENT_MAX_THREADS / __BITS_PER_LONG) + return -1; - return queue_index; + prog->request_queue_status[i] |= (1UL << j); + return i * __BITS_PER_LONG + j; } rpcsvc_notify_wrapper_t * @@ -363,6 +342,10 @@ rpcsvc_program_actor(rpcsvc_request_t *req) goto err; } + if (svc->xl->ctx->measure_latency) { + timespec_now(&req->begin); + } + req->ownthread = program->ownthread; req->synctask = program->synctask; @@ -1512,10 +1495,18 @@ rpcsvc_submit_generic(rpcsvc_request_t *req, struct iovec *proghdr, size_t hdrlen = 0; char new_iobref = 0; rpcsvc_drc_globals_t *drc = NULL; + gf_latency_t *lat = NULL; if ((!req) || (!req->trans)) return -1; + if (req->prog && req->begin.tv_sec) { + if ((req->procnum >= 0) && (req->procnum < req->prog->numactors)) { + timespec_now(&req->end); + lat = &req->prog->latencies[req->procnum]; + gf_latency_update(lat, &req->begin, &req->end); + } + } trans = req->trans; for (i = 0; i < hdrcount; i++) { @@ -1846,6 +1837,15 @@ rpcsvc_submit_message(rpcsvc_request_t *re |