Browse Source

Spawn "mount" on branches when waiting for mounts enabled

pull/1477/head
trapexit 1 week ago
committed by GitHub
parent
commit
1b167d34d8
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      DEPENDENCIES
  2. 25
      mkdocs/docs/config/branches-mount-timeout.md
  3. 9
      mkdocs/docs/config/branches.md
  4. 9
      mkdocs/docs/config/options.md
  5. 55
      mkdocs/docs/faq/why_isnt_it_working.md
  6. 2
      mkdocs/mkdocs.yml
  7. 10
      src/fs_mount.cpp
  8. 8
      src/fs_mount.hpp
  9. 20
      src/fs_wait_for_mount.cpp
  10. 2145
      src/subprocess.hpp

2
DEPENDENCIES

@ -7,9 +7,9 @@
* fmt: https://github.com/fmtlib/fmt * fmt: https://github.com/fmtlib/fmt
* concurrentqueue: https://github.com/cameron314/concurrentqueue * concurrentqueue: https://github.com/cameron314/concurrentqueue
* scope_guard: https://github.com/Neargye/scope_guard * scope_guard: https://github.com/Neargye/scope_guard
* subprocess: https://github.com/arun11299/cpp-subprocess
* boost * boost
* download boost * download boost
* ./bootstrap.sh * ./bootstrap.sh
* ./b2 tools/bcp * ./b2 tools/bcp
* ./dist/bin/bcp pool/pool.hpp <target_dir>
* ./dist/bin/bcp unordered/concurrent_flat_map.hpp <target_dir> * ./dist/bin/bcp unordered/concurrent_flat_map.hpp <target_dir>

25
mkdocs/docs/config/branches_mount_timeout.md → mkdocs/docs/config/branches-mount-timeout.md

@ -1,6 +1,7 @@
# branches-mount-timeout # branches-mount-timeout
Default: `0`
* type: `UINT` (seconds)
* default: `0`
mergerfs is compatible with any path, whether it be a mount point or a mergerfs is compatible with any path, whether it be a mount point or a
directory on your [root directory on your [root
@ -17,8 +18,10 @@ offers a way to enforce mount dependencies using the
option in /etc/fstab, applying this to every branch path is both option in /etc/fstab, applying this to every branch path is both
cumbersome and susceptible to errors. cumbersome and susceptible to errors.
`branches-mount-timeout` will cause mergerfs to wait for all branches
to become "mounted." The logic to determine "mounted" is as follows.
`branches-mount-timeout` will cause mergerfs to first attempt to mount
each branch if the branch appears to be on the same filesystem as the
`mergerfs` mount point and then wait for all branches to become
"mounted." The logic to determine "mounted" is as follows.
1. It is mounted if the branch directory has the extended attribute 1. It is mounted if the branch directory has the extended attribute
`user.mergerfs.branch` `user.mergerfs.branch`
@ -28,13 +31,25 @@ to become "mounted." The logic to determine "mounted" is as follows.
attribute `user.mergerfs.branch_mounts_here` attribute `user.mergerfs.branch_mounts_here`
4. It is **not** mounted if the branch directory contains 4. It is **not** mounted if the branch directory contains
a file named `.mergerfs.branch_mounts_here` a file named `.mergerfs.branch_mounts_here`
5. It is mounted if the `st_dev` value of the mergerfs mountpoint is
5. It is mounted if the `st_dev` value of the mergerfs mount point is
different from the branch path. different from the branch path.
These files and xattrs are used to help `mergerfs` know whether or not
a directory happens to be a branch or is the underlying directory
mount point.
**NOTE:** If on a `systemd` based system and using `fstab` it is a **NOTE:** If on a `systemd` based system and using `fstab` it is a
good idea to set the mount option good idea to set the mount option
[x-systemd.mount-timeout](https://www.freedesktop.org/software/systemd/man/latest/systemd.mount.html#x-systemd.mount-timeout=) [x-systemd.mount-timeout](https://www.freedesktop.org/software/systemd/man/latest/systemd.mount.html#x-systemd.mount-timeout=)
to some value longer than `branches-mount-timeout`.
to some value longer than `branches-mount-timeout` otherwise `systemd`
might kill `mergerfs` before it finishes waiting.
**NOTE:** The way `mergerfs` attempts to mount the branch is by
calling out to the system command `mount` with the branch as the
target. If that path is configured in `/etc/fstab` as a mount point
then `mount` should attempt to mount it with the settings defined in
`fstab`.
## branches-mount-timeout-fail ## branches-mount-timeout-fail

9
mkdocs/docs/config/branches.md

@ -66,8 +66,8 @@ A convenient way to configure branches is to use
## branch setup ## branch setup
mergerfs does not require any special setup of branch paths in order
to be used however here are some suggestions.
`mergerfs` does **not** require any special setup of branch paths in
order to be used however here are some suggestions.
### layout ### layout
@ -132,12 +132,13 @@ $ sudo chattr +i /mnt/hdd/10T-XYZ
``` ```
The extended attribute `user.mergerfs.branch_mounts_here` is used by The extended attribute `user.mergerfs.branch_mounts_here` is used by
the [branches-mount-timeout](branches_mount_timeout.md) option to
the [branches-mount-timeout](branches-mount-timeout.md) option to
recognize whether or not a mergerfs branch path points to the intended recognize whether or not a mergerfs branch path points to the intended
filesystem. filesystem.
The `chattr` is likely to only work on EXT{2,3,4} filesystems but will The `chattr` is likely to only work on EXT{2,3,4} filesystems but will
restrict even `root` from modifying the directory or its content.
restrict even `root` from modifying the directory or its content but
is still able to be a mount point.
#### mounted filesystems #### mounted filesystems

9
mkdocs/docs/config/options.md

@ -33,6 +33,12 @@ config file.
key=val / ini style format. key=val / ini style format.
* **[branches](branches.md)**: Colon delimited list of branches. Used * **[branches](branches.md)**: Colon delimited list of branches. Used
primarily in config file. primarily in config file.
* **[branches-mount-timeout](branches-mount-timeout.md)=UINT**: Number
of seconds to wait at startup for branches to be a mount other than
the mountpoint's filesystem. (default: 0)
* **[branches-mount-timeout-fail](branches-mount-timeout.md##branches-mount-timeout-fail)=BOOL**:
If set to `true` then if `branches-mount-timeout` expires it will
exit rather than continuing. (default: false)
* **[minfreespace](minfreespace.md)=SIZE**: The minimum available * **[minfreespace](minfreespace.md)=SIZE**: The minimum available
space of a branch necessary to be considered for a create space of a branch necessary to be considered for a create
[policy](functions_categories_policies.md). This is a default value [policy](functions_categories_policies.md). This is a default value
@ -102,9 +108,6 @@ config file.
* **nfsopenhack=off|git|all**: A workaround for exporting mergerfs * **nfsopenhack=off|git|all**: A workaround for exporting mergerfs
over NFS where there are issues with creating files for write while over NFS where there are issues with creating files for write while
setting the mode to read-only. (default: off) setting the mode to read-only. (default: off)
* **branches-mount-timeout=UINT**: Number of seconds to wait at
startup for branches to be a mount other than the mountpoint's
filesystem. (default: 0)
* **[follow-symlinks](follow-symlinks.md)=never|directory|regular|all**: * **[follow-symlinks](follow-symlinks.md)=never|directory|regular|all**:
Turns symlinks into what they point to. (default: never) Turns symlinks into what they point to. (default: never)
* **[link-exdev](link-exdev.md)=passthrough|rel-symlink|abs-base-symlink|abs-pool-symlink**: * **[link-exdev](link-exdev.md)=passthrough|rel-symlink|abs-base-symlink|abs-pool-symlink**:

55
mkdocs/docs/faq/why_isnt_it_working.md

@ -36,36 +36,27 @@ and [FAQ](configuration_and_policies.md) for policy recommendations.
## Why do I get an "out of space" / "no space left on device" / ENOSPC error even though there appears to be lots of space available? ## Why do I get an "out of space" / "no space left on device" / ENOSPC error even though there appears to be lots of space available?
First make sure you've read the sections about [policies, path
preservation, branch
filtering,](../config/functions_categories_policies.md) and the
options [minfreespace](../config/minfreespace.md),
[moveonenospc](../config/moveonenospc.md),
[statfs](../config/statfs.md), and
[statfs_ignore](../config/statfs.md#statfs_ignore).
mergerfs is simply presenting a union of the content within multiple
One or multiple of the below are likely causing branches
* [minfreespace](../config/minfreespace.md) could be filtering out
branches
* if using an `ep*`
[policy](../config/functions_categories_policies.md) there may not
be an available branch
* due to [branch modes](../config/branches.md#branch-mode) being set
to to `NC` or `RO` branches will be excluded from consideration
* if using `ext4` ensure you are not running into reserve limits (use
`tune2fs -m 0` to remove the reserve)
* it is possible that the filesystem selected by the policy has run
out of inodes (check with `df -i`)
mergerfs is presenting a union of the content within multiple
branches. The reported free space is an aggregate of space available branches. The reported free space is an aggregate of space available
within the pool (behavior modified by `statfs` and
`statfs_ignore`). It does not represent a contiguous space. In the
same way that read-only filesystems, those with quotas, or reserved
space report the full theoretical space available. Not the practical
usable space.
Due to using an `existing path` based policy, setting a [branch's
mode](../config/branches.md#branch-mode) to `NC` or `RO`, a
filesystems read-only status, and/or `minfreespace` setting it is
[perfectly
valid](../config/functions_categories_policies.md#filtering) that
`ENOSPC` / "out of space" / "no space left on device" be returned when
attempting to create a file despite there being actual space available
somewhere in the pool. It is doing what was asked of it: filtering
possible branches due to those settings. If that is not the behavior
you want you need to modify the settings accordingly.
It is also possible that the filesystem selected has run out of
inodes. Use `df -i` to list the total and available inodes per
filesystem.
within the pool (behavior modified by [statfs](../config/statfs.md)
and [statfs_ignore](../config/statfs.md#statfs_ignore)). It does not
represent a contiguous space. In the same way that read-only
filesystems, those with quotas, or reserved space report the full
theoretical space available. Not the practical usable space.
## Why isn't the create policy working? ## Why isn't the create policy working?
@ -76,7 +67,7 @@ First, confirm the policy is configured as expected by using the
[runtime interface](../runtime_interfaces.md). [runtime interface](../runtime_interfaces.md).
```shell ```shell
$ getfattr -n user.mergerfs.category.create /mnt/mergerfs/.mergerfs
$ sudo getfattr -n user.mergerfs.category.create /mnt/mergerfs/.mergerfs
# file: mnt/mergerfs/.mergerfs # file: mnt/mergerfs/.mergerfs
user.mergerfs.category.create="mfs" user.mergerfs.category.create="mfs"
``` ```
@ -87,8 +78,8 @@ where it was created.
```shell ```shell
$ touch /mnt/mergerfs/new-file
$ getfattr -n user.mergerfs.allpaths /mnt/mergerfs/new-file
$ sudo touch /mnt/mergerfs/new-file
$ sudo getfattr -n user.mergerfs.allpaths /mnt/mergerfs/new-file
# file: mnt/mergerfs/new-file # file: mnt/mergerfs/new-file
user.mergerfs.allpaths="/mnt/hdd/drive1/new-file" user.mergerfs.allpaths="/mnt/hdd/drive1/new-file"
``` ```

2
mkdocs/mkdocs.yml

@ -69,7 +69,7 @@ nav:
- config/options.md - config/options.md
- config/deprecated_options.md - config/deprecated_options.md
- config/branches.md - config/branches.md
- config/branches_mount_timeout.md
- config/branches-mount-timeout.md
- config/functions_categories_policies.md - config/functions_categories_policies.md
- config/minfreespace.md - config/minfreespace.md
- config/func_readdir.md - config/func_readdir.md

10
src/fs_mount.cpp

@ -0,0 +1,10 @@
#include "fs_mount.hpp"
#include "subprocess.hpp"
int
fs::mount(const std::string &tgt_)
{
return subprocess::call({"mount",tgt_});
}

8
src/fs_mount.hpp

@ -0,0 +1,8 @@
#pragma once
#include <string>
namespace fs
{
int mount(const std::string &tgt);
}

20
src/fs_wait_for_mount.cpp

@ -19,6 +19,7 @@
#include "fs_wait_for_mount.hpp" #include "fs_wait_for_mount.hpp"
#include "syslog.hpp" #include "syslog.hpp"
#include "fs_mount.hpp"
#include "fs_exists.hpp" #include "fs_exists.hpp"
#include "fs_lgetxattr.hpp" #include "fs_lgetxattr.hpp"
#include "fs_lstat.hpp" #include "fs_lstat.hpp"
@ -123,13 +124,13 @@ _wait_for_mount(const struct stat &src_st_,
for(const auto &path : successes) for(const auto &path : successes)
{ {
tgt_paths.erase(path); tgt_paths.erase(path);
SysLog::info("{} is mounted",path.string());
SysLog::info("{} is ready",path.string());
} }
if(first_loop) if(first_loop)
{ {
for(const auto &path : failures) for(const auto &path : failures)
SysLog::notice("{} is not mounted, waiting",path.string());
SysLog::notice("{} is not ready, waiting",path.string());
first_loop = false; first_loop = false;
} }
@ -138,7 +139,7 @@ _wait_for_mount(const struct stat &src_st_,
} }
for(auto const &path : failures) for(auto const &path : failures)
SysLog::notice("{} not mounted within timeout",path.string());
SysLog::notice("{} not ready within timeout",path.string());
return failures.size(); return failures.size();
} }
@ -157,5 +158,18 @@ fs::wait_for_mount(const fs::Path &src_path_,
src_path_.string(), src_path_.string(),
strerror(errno)); strerror(errno));
for(auto &tgt_path : tgt_paths_)
{
int rv;
if(_branch_is_mounted(src_st,tgt_path))
continue;
rv = fs::mount(tgt_path);
SysLog::notice("mount {}: {}",
tgt_path.string(),
((rv == 0) ? "success" : "fail"));
}
return ::_wait_for_mount(src_st,tgt_paths_,timeout_); return ::_wait_for_mount(src_st,tgt_paths_,timeout_);
} }

2145
src/subprocess.hpp
File diff suppressed because it is too large
View File

Loading…
Cancel
Save