Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 93c052a3cd | |||
| 76d11fa6f4 | |||
| 9ced6ca681 | |||
| de11ec091e | |||
| 37b79d06f8 | |||
| 2f1147c7d6 | |||
| b5d1484314 | |||
| d0c5fa3ed6 | |||
| eac420791c | |||
| 6480b66bd6 | |||
| 30a2668b99 | |||
| 4ed15c4c04 | |||
| fc7a57f0dc | |||
| f0452119e0 | |||
| fb174704dd | |||
| 39663c8288 | |||
| 646a3c417b | |||
| 303126bad9 | |||
| f0a0cc2b7e | |||
| 2c7c667576 | |||
| 1846b685c4 | |||
| 7f56cfc602 | |||
| fd3aa6594f | |||
| 2731a001e5 | |||
| 608e7ab89c | |||
| a73dda48bd | |||
| 7c2550a7e4 |
@@ -0,0 +1,19 @@
|
||||
version: '{build}'
|
||||
|
||||
install:
|
||||
|
||||
# install WinFsp
|
||||
- appveyor DownloadFile https://github.com/billziss-gh/winfsp/releases/download/v1.4B2/winfsp-1.4.18211.msi
|
||||
- for %%f in ("winfsp-*.msi") do start /wait msiexec /i %%f /qn INSTALLLEVEL=1000
|
||||
|
||||
# install FUSE for Cygwin (64-bit and 32-bit)
|
||||
- C:\cygwin64\bin\env.exe -i PATH=/bin bash "%ProgramFiles(x86)%\WinFsp\opt\cygfuse\install.sh"
|
||||
- C:\cygwin\bin\env.exe -i PATH=/bin bash "%ProgramFiles(x86)%\WinFsp\opt\cygfuse\install.sh"
|
||||
|
||||
# install additional Cygwin packages (64-bit and 32-bit)
|
||||
- C:\cygwin64\setup-x86_64.exe -qnNdO -R C:\cygwin64 -s http://cygwin.mirror.constant.com -l C:\cygwin64\var\cache\setup -P libglib2.0-devel -P meson
|
||||
- C:\cygwin\setup-x86.exe -qnNdO -R C:\cygwin -s http://cygwin.mirror.constant.com -l C:\cygwin\var\cache\setup -P libglib2.0-devel -P meson
|
||||
|
||||
build_script:
|
||||
- C:\cygwin64\bin\env.exe -i PATH=/bin bash test\appveyor-build.sh
|
||||
- C:\cygwin\bin\env.exe -i PATH=/bin bash test\appveyor-build.sh
|
||||
@@ -14,8 +14,6 @@ addons:
|
||||
- gcc-6
|
||||
- python-docutils
|
||||
- python3-pip
|
||||
before_install:
|
||||
- sudo -H python3 -m pip install pip==8.1.1
|
||||
install: test/travis-install.sh
|
||||
script: test/travis-build.sh
|
||||
|
||||
|
||||
@@ -13,17 +13,22 @@ Miklos Szeredi <miklos@szeredi.hu> (until 12/2015)
|
||||
Contributors (autogenerated list)
|
||||
---------------------------------
|
||||
|
||||
|
||||
Alan Jenkins <alan.christopher.jenkins@gmail.com>
|
||||
Alexander Neumann <alexander@bumpern.de>
|
||||
Anatol Pomozov <anatol.pomozov@gmail.com>
|
||||
Benjamin Fleischer <fleiben@gmail.com>
|
||||
Berserker <berserker.troll@yandex.com>
|
||||
Bill Zissimopoulos <billziss@navimatics.com>
|
||||
Brandon Carter <b-carter@users.noreply.github.com>
|
||||
Chris Wolfe <cwolfe@chromium.org>
|
||||
Daniel Lublin <daniel@lublin.se>
|
||||
gala <gala132@users.noreply.github.com>
|
||||
George Vlahavas <vlahavas@gmail.com>
|
||||
G.raud Meyer <graud@gmx.com>
|
||||
harrim4n <git@harrim4n.com>
|
||||
Jakub Jelen <jjelen@redhat.com>
|
||||
Josh Triplett <josh@joshtriplett.org>
|
||||
Julio Merino <jmmv@google.com>
|
||||
Julio Merino <jmmv@meroh.net>
|
||||
Mike Kelly <mike@pair.com>
|
||||
@@ -32,6 +37,14 @@ Miklos Szeredi <mszeredi@suse.cz>
|
||||
Nikolaus Rath <Nikolaus@rath.org>
|
||||
Percy Jahn <email@percyjahn.de>
|
||||
Qais Patankar <qaisjp@gmail.com>
|
||||
Quentin Rameau <quinq@fifth.space>
|
||||
Reid Wagner <wagnerreid@gmail.com>
|
||||
Rian Hunter <rian@alum.mit.edu>
|
||||
Rian Hunter <rianhunter@users.noreply.github.com>
|
||||
Samuel Murray <samuel.murray@outlook.com>
|
||||
S. D. Cloudt <s.d.cloudt@student.tue.nl>
|
||||
smheidrich <smheidrich@weltenfunktion.de>
|
||||
Tim Harder <radhermit@gmail.com>
|
||||
Timo Savola <timo.savola@iki.fi>
|
||||
tpoindessous <thomas@poindessous.com>
|
||||
Zoltan Kuscsik <zoltan.kuscsik@linaro.org>
|
||||
|
||||
@@ -1,3 +1,37 @@
|
||||
Release 3.5.1 (2018-12-22)
|
||||
--------------------------
|
||||
|
||||
* Documentation updates
|
||||
* Build system updates
|
||||
* Added "BindInterface" as valid "-o" option.
|
||||
|
||||
Release 3.5.0 (2018-08-28)
|
||||
--------------------------
|
||||
|
||||
* Fixed error code returned by rename(), allowing proper fallback.
|
||||
* Port to Cygwin.
|
||||
|
||||
Release 3.4.0 (2018-06-29)
|
||||
--------------------------
|
||||
|
||||
* Make utimens(NULL) result in timestamp "now" -- no more touched files
|
||||
dated 1970-01-01
|
||||
* New `createmode` workaround.
|
||||
* Fix `fstat` workaround regression.
|
||||
|
||||
Release 3.3.2 (2018-04-29)
|
||||
--------------------------
|
||||
|
||||
* New `renamexdev` workaround.
|
||||
|
||||
Release 3.3.1 (2017-10-25)
|
||||
--------------------------
|
||||
|
||||
* Manpage is now installed in correct directory.
|
||||
* SSHFS now supports (or rather: ignores) some options that it may
|
||||
receive as result of being mounted from ``/etc/mtab``. This includes
|
||||
things like ``user``, ``netdev``, or ``auto``.
|
||||
|
||||
SSHFS 3.3.0 (2017-09-20)
|
||||
------------------------
|
||||
|
||||
|
||||
+7
-5
@@ -32,7 +32,7 @@ To unmount the filesystem::
|
||||
|
||||
fusermount -u mountpoint
|
||||
|
||||
On BSD and OS-X, to unmount the filesystem::
|
||||
On BSD and macOS, to unmount the filesystem::
|
||||
|
||||
umount mountpoint
|
||||
|
||||
@@ -42,7 +42,7 @@ Installation
|
||||
|
||||
First, download the latest SSHFS release from
|
||||
https://github.com/libfuse/sshfs/releases. On Linux and BSD, you will
|
||||
also need to install libfuse_ 3.1.0 or newer. On OS-X, you need
|
||||
also need to install libfuse_ 3.1.0 or newer. On macOS, you need
|
||||
OSXFUSE_ instead. Finally, you need the Glib_ library with development
|
||||
headers (which should be available from your operating system's
|
||||
package manager).
|
||||
@@ -51,7 +51,7 @@ To build and install, we recommend to use Meson_ (version 0.38 or
|
||||
newer) and Ninja_. After extracting the sshfs tarball, create a
|
||||
(temporary) build directory and run Meson::
|
||||
|
||||
$ md build; cd build
|
||||
$ mkdir build; cd build
|
||||
$ meson ..
|
||||
|
||||
Normally, the default build options will work fine. If you
|
||||
@@ -85,8 +85,10 @@ https://lists.sourceforge.net/lists/listinfo/fuse-sshfs).
|
||||
Please report any bugs on the GitHub issue tracker at
|
||||
https://github.com/libfuse/libfuse/issues.
|
||||
|
||||
|
||||
Professional Support
|
||||
--------------------
|
||||
|
||||
Professional support is available. Please contact Nikolaus Rath
|
||||
<Nikolaus@rath.org> for details.
|
||||
Professional support is offered via `Rath Consulting`_.
|
||||
|
||||
.. _`Rath Consulting`: http://www.rath-consulting.biz
|
||||
|
||||
@@ -19,7 +19,8 @@ git archive --format=tar "${TAG}" | tar -x "--directory=${TAG}"
|
||||
find "${TAG}" -name .gitignore -delete
|
||||
rm "${TAG}/make_release_tarball.sh" \
|
||||
"${TAG}/.travis.yml" \
|
||||
"${TAG}/test/travis-*.sh"
|
||||
"${TAG}/test/travis-build.sh" \
|
||||
"${TAG}/test/travis-install.sh"
|
||||
tar -cJf "${TAG}.tar.xz" "${TAG}/"
|
||||
gpg --armor --detach-sign "${TAG}.tar.xz"
|
||||
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
project('sshfs', 'c', version: '3.3.0',
|
||||
project('sshfs', 'c', version: '3.5.1',
|
||||
meson_version: '>= 0.38',
|
||||
default_options: [ 'buildtype=debugoptimized' ])
|
||||
|
||||
@@ -25,7 +25,7 @@ if not cc.compiles(code, args: [ '-O0', '-Werror=unused-result' ])
|
||||
endif
|
||||
|
||||
|
||||
rst2man = find_program('rst2man', required: false)
|
||||
rst2man = find_program('rst2man', 'rst2man.py', required: false)
|
||||
|
||||
cfg = configuration_data()
|
||||
|
||||
@@ -58,7 +58,7 @@ executable('sshfs', sshfs_sources,
|
||||
if rst2man.found()
|
||||
custom_target('manpages', input: [ 'sshfs.rst' ], output: [ 'sshfs.1' ],
|
||||
command: [rst2man, '@INPUT@', '@OUTPUT@'], install: true,
|
||||
install_dir: join_paths(get_option('mandir'), '1'))
|
||||
install_dir: join_paths(get_option('mandir'), 'man1'))
|
||||
else
|
||||
message('rst2man not found, not building manual page.')
|
||||
endif
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <fuse.h>
|
||||
#include <fuse_opt.h>
|
||||
#if !defined(__CYGWIN__)
|
||||
#include <fuse_lowlevel.h>
|
||||
# include <fuse_lowlevel.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
# include <fuse_darwin.h>
|
||||
@@ -214,10 +214,12 @@ struct sshfs {
|
||||
struct fuse_args ssh_args;
|
||||
char *workarounds;
|
||||
int rename_workaround;
|
||||
int renamexdev_workaround;
|
||||
int truncate_workaround;
|
||||
int buflimit_workaround;
|
||||
int unrel_append;
|
||||
int fstat_workaround;
|
||||
int createmode_workaround;
|
||||
int transform_symlinks;
|
||||
int follow_symlinks;
|
||||
int no_check_root;
|
||||
@@ -298,6 +300,7 @@ static const char *ssh_opts[] = {
|
||||
"AddressFamily",
|
||||
"BatchMode",
|
||||
"BindAddress",
|
||||
"BindInterface",
|
||||
"CertificateFile",
|
||||
"ChallengeResponseAuthentication",
|
||||
"CheckHostIP",
|
||||
@@ -428,9 +431,15 @@ static struct fuse_opt sshfs_opts[] = {
|
||||
FUSE_OPT_KEY("writeback_cache=no", FUSE_OPT_KEY_DISCARD),
|
||||
FUSE_OPT_KEY("unreliable_append", FUSE_OPT_KEY_DISCARD),
|
||||
|
||||
|
||||
FUSE_OPT_END
|
||||
/* These may come in from /etc/fstab - we just ignore them */
|
||||
FUSE_OPT_KEY("auto", FUSE_OPT_KEY_DISCARD),
|
||||
FUSE_OPT_KEY("noauto", FUSE_OPT_KEY_DISCARD),
|
||||
FUSE_OPT_KEY("user", FUSE_OPT_KEY_DISCARD),
|
||||
FUSE_OPT_KEY("nouser", FUSE_OPT_KEY_DISCARD),
|
||||
FUSE_OPT_KEY("users", FUSE_OPT_KEY_DISCARD),
|
||||
FUSE_OPT_KEY("_netdev", FUSE_OPT_KEY_DISCARD),
|
||||
|
||||
FUSE_OPT_END
|
||||
};
|
||||
|
||||
static struct fuse_opt workaround_opts[] = {
|
||||
@@ -440,12 +449,16 @@ static struct fuse_opt workaround_opts[] = {
|
||||
SSHFS_OPT("none", fstat_workaround, 0),
|
||||
SSHFS_OPT("rename", rename_workaround, 1),
|
||||
SSHFS_OPT("norename", rename_workaround, 0),
|
||||
SSHFS_OPT("renamexdev", renamexdev_workaround, 1),
|
||||
SSHFS_OPT("norenamexdev", renamexdev_workaround, 0),
|
||||
SSHFS_OPT("truncate", truncate_workaround, 1),
|
||||
SSHFS_OPT("notruncate", truncate_workaround, 0),
|
||||
SSHFS_OPT("buflimit", buflimit_workaround, 1),
|
||||
SSHFS_OPT("nobuflimit", buflimit_workaround, 0),
|
||||
SSHFS_OPT("fstat", fstat_workaround, 1),
|
||||
SSHFS_OPT("nofstat", fstat_workaround, 0),
|
||||
SSHFS_OPT("createmode", createmode_workaround, 1),
|
||||
SSHFS_OPT("nocreatemode", createmode_workaround, 0),
|
||||
FUSE_OPT_END
|
||||
};
|
||||
|
||||
@@ -2146,7 +2159,8 @@ static int sshfs_opendir(const char *path, struct fuse_file_info *fi)
|
||||
if (!err) {
|
||||
buf_finish(handle);
|
||||
fi->fh = (unsigned long) handle;
|
||||
}
|
||||
} else
|
||||
free(handle);
|
||||
buf_free(&buf);
|
||||
return err;
|
||||
}
|
||||
@@ -2303,7 +2317,7 @@ static int sshfs_rename(const char *from, const char *to, unsigned int flags)
|
||||
int err;
|
||||
|
||||
if(flags != 0)
|
||||
return EINVAL;
|
||||
return -EINVAL;
|
||||
|
||||
if (sshfs.ext_posix_rename)
|
||||
err = sshfs_ext_posix_rename(from, to);
|
||||
@@ -2326,6 +2340,8 @@ static int sshfs_rename(const char *from, const char *to, unsigned int flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (err == -EPERM && sshfs.renamexdev_workaround)
|
||||
err = -EXDEV;
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2458,6 +2474,14 @@ static int sshfs_utimens(const char *path, const struct timespec tv[2],
|
||||
int err;
|
||||
struct buffer buf;
|
||||
struct sshfs_file *sf = NULL;
|
||||
time_t asec = tv[0].tv_sec, msec = tv[1].tv_sec;
|
||||
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if (asec == 0)
|
||||
asec = now.tv_sec;
|
||||
if (msec == 0)
|
||||
msec = now.tv_sec;
|
||||
|
||||
if (fi != NULL) {
|
||||
sf = get_sshfs_file(fi);
|
||||
@@ -2471,8 +2495,8 @@ static int sshfs_utimens(const char *path, const struct timespec tv[2],
|
||||
else
|
||||
buf_add_buf(&buf, &sf->handle);
|
||||
buf_add_uint32(&buf, SSH_FILEXFER_ATTR_ACMODTIME);
|
||||
buf_add_uint32(&buf, tv[0].tv_sec);
|
||||
buf_add_uint32(&buf, tv[1].tv_sec);
|
||||
buf_add_uint32(&buf, asec);
|
||||
buf_add_uint32(&buf, msec);
|
||||
|
||||
err = sftp_request(sf == NULL ? SSH_FXP_SETSTAT : SSH_FXP_FSETSTAT,
|
||||
&buf, SSH_FXP_STATUS, NULL);
|
||||
@@ -3088,6 +3112,9 @@ static int sshfs_statfs(const char *path, struct statvfs *buf)
|
||||
static int sshfs_create(const char *path, mode_t mode,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
if (sshfs.createmode_workaround)
|
||||
mode = 0;
|
||||
|
||||
return sshfs_open_common(path, mode, fi);
|
||||
}
|
||||
|
||||
@@ -3132,7 +3159,7 @@ static int sshfs_getattr(const char *path, struct stat *stbuf,
|
||||
struct buffer outbuf;
|
||||
struct sshfs_file *sf = NULL;
|
||||
|
||||
if (fi != NULL || sshfs.fstat_workaround) {
|
||||
if (fi != NULL && !sshfs.fstat_workaround) {
|
||||
sf = get_sshfs_file(fi);
|
||||
if (!sshfs_file_is_conn(sf))
|
||||
return -EIO;
|
||||
@@ -3358,9 +3385,11 @@ static void usage(const char *progname)
|
||||
" -o workaround=LIST colon separated list of workarounds\n"
|
||||
" none no workarounds enabled\n"
|
||||
" [no]rename fix renaming to existing file (default: off)\n"
|
||||
" [no]renamexdev fix moving across filesystems (default: off)\n"
|
||||
" [no]truncate fix truncate for old servers (default: off)\n"
|
||||
" [no]buflimit fix buffer fillup bug in server (default: on)\n"
|
||||
" [no]fstat always use stat() instead of fstat() (default: off)\n"
|
||||
" [no]createmode always pass mode 0 to create (default: off)\n"
|
||||
" -o idmap=TYPE user/group ID mapping (default: " IDMAP_DEFAULT ")\n"
|
||||
" none no translation of the ID space\n"
|
||||
" user only translate UID/GID of connecting user\n"
|
||||
@@ -3424,7 +3453,39 @@ static int sshfs_opt_proc(void *data, const char *arg, int key,
|
||||
return 0;
|
||||
}
|
||||
else if (!sshfs.mountpoint) {
|
||||
#if defined(__CYGWIN__)
|
||||
/*
|
||||
* On FUSE for Cygwin the mountpoint may be a drive or directory.
|
||||
* Furthermore the mountpoint must NOT exist prior to mounting.
|
||||
* So we cannot use realpath(3).
|
||||
*/
|
||||
if ((('A' <= arg[0] && arg[0] <= 'Z') || ('a' <= arg[0] && arg[0] <= 'z'))
|
||||
&& ':' == arg[1] && '\0' == arg[2]) {
|
||||
/* drive: make a copy */
|
||||
sshfs.mountpoint = strdup(arg);
|
||||
} else {
|
||||
/* path: split into dirname, basename and check dirname */
|
||||
char *dir;
|
||||
const char *base;
|
||||
const char *slash = strrchr(arg, '/');
|
||||
if (slash) {
|
||||
char *tmp = strndup(arg, slash == arg ? 1 : slash - arg);
|
||||
dir = tmp ? realpath(tmp, NULL) : 0;
|
||||
base = slash + 1;
|
||||
free(tmp);
|
||||
} else {
|
||||
dir = realpath(".", NULL);
|
||||
base = arg;
|
||||
}
|
||||
if (dir) {
|
||||
slash = '/' == dir[0] && '\0' == dir[1] ? "" : "/";
|
||||
asprintf(&sshfs.mountpoint, "%s%s%s", dir, slash, base);
|
||||
free(dir);
|
||||
}
|
||||
}
|
||||
#else
|
||||
sshfs.mountpoint = realpath(arg, NULL);
|
||||
#endif
|
||||
if (!sshfs.mountpoint) {
|
||||
fprintf(stderr, "sshfs: bad mount point `%s': %s\n",
|
||||
arg, strerror(errno));
|
||||
@@ -3844,8 +3905,10 @@ int main(int argc, char *argv[])
|
||||
#else
|
||||
sshfs.rename_workaround = 0;
|
||||
#endif
|
||||
sshfs.renamexdev_workaround = 0;
|
||||
sshfs.truncate_workaround = 0;
|
||||
sshfs.buflimit_workaround = 1;
|
||||
sshfs.createmode_workaround = 0;
|
||||
sshfs.ssh_ver = 2;
|
||||
sshfs.progname = argv[0];
|
||||
sshfs.rfd = -1;
|
||||
@@ -3882,7 +3945,9 @@ int main(int argc, char *argv[])
|
||||
if (sshfs.show_version) {
|
||||
printf("SSHFS version %s\n", PACKAGE_VERSION);
|
||||
printf("FUSE library version %s\n", fuse_pkgversion());
|
||||
#if !defined(__CYGWIN__)
|
||||
fuse_lowlevel_version();
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -107,12 +107,16 @@ Options
|
||||
|
||||
:rename: Emulate overwriting an existing file by deleting and
|
||||
renaming.
|
||||
:renamexdev: Make rename fail with EXDEV instead of the default EPERM
|
||||
to allow moving files across remote filesystems.
|
||||
:truncate: Work around servers that don't support truncate by
|
||||
coping the whole file, truncating it locally, and sending it
|
||||
back.
|
||||
:fstat: Work around broken servers that don't support *fstat()* by
|
||||
using *stat* instead.
|
||||
:buflimit: Work around OpenSSH "buffer fillup" bug.
|
||||
:createmode: Work around broken servers that produce an error when passing a
|
||||
non-zero mode to create, by always passing a mode of 0.
|
||||
|
||||
-o idmap=TYPE
|
||||
How to map remote UID/GIDs to local values. Possible values are:
|
||||
@@ -228,8 +232,19 @@ removed it, but before SSHFS had the time to rename the old file. In
|
||||
this case, the rename will still fail.
|
||||
|
||||
|
||||
SSHFS hangs
|
||||
~~~~~~~~~~~
|
||||
Permission denied when moving files across remote filesystems
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Most SFTP servers return only a generic "failure" when failing to rename
|
||||
across filesystem boundaries (EXDEV). sshfs normally converts this generic
|
||||
failure to a permission denied error (EPERM). If the option ``-o
|
||||
workaround=renamexdev`` is given, generic failures will be considered EXDEV
|
||||
errors which will make programs like `mv(1)` attempt to actually move the
|
||||
file after the failed rename.
|
||||
|
||||
|
||||
SSHFS hangs for no apparent reason
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In some cases, attempts to access the SSHFS mountpoint may freeze if
|
||||
no filesystem activity has occured for some time. This is typically
|
||||
@@ -238,6 +253,34 @@ without SSHFS being informed about that. As a workaround, you can try
|
||||
to mount with ``-o ServerAliveInterval=15``. This will force the SSH
|
||||
connection to stay alive even if you have no activity.
|
||||
|
||||
|
||||
SSHFS hangs after the connection was interrupted
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By default, network operations in SSHFS run without timeouts, mirroring the
|
||||
default behavior of SSH itself. As a consequence, if the connection to the
|
||||
remote host is interrupted (e.g. because a network cable was removed),
|
||||
operations on files or directories under the mountpoint will block until the
|
||||
connection is either restored or closed altogether (e.g. manually).
|
||||
Applications that try to access such files or directories will generally appear
|
||||
to "freeze" when this happens.
|
||||
|
||||
If it is acceptable to discard data being read or written, a quick workaround
|
||||
is to kill the responsible ``sshfs`` process, which will make any blocking
|
||||
operations on the mounted filesystem error out and thereby "unfreeze" the
|
||||
relevant applications. Note that force unmounting with ``fusermount -zu``, on
|
||||
the other hand, does not help in this case and will leave read/write operations
|
||||
in the blocking state.
|
||||
|
||||
For a more automatic solution, one can use the ``-o ServerAliveInterval=15``
|
||||
option mentioned above, which will drop the connection after not receiving a
|
||||
response for 3 * 15 = 45 seconds from the remote host. By also supplying ``-o
|
||||
reconnect``, one can ensure that the connection is re-established as soon as
|
||||
possible afterwards. As before, this will naturally lead to loss of data that
|
||||
was in the process of being read or written at the time when the connection was
|
||||
interrupted.
|
||||
|
||||
|
||||
Mounting from /etc/fstab
|
||||
========================
|
||||
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
machine=$(uname -m)
|
||||
mkdir build-$machine
|
||||
cd build-$machine
|
||||
meson ..
|
||||
ninja
|
||||
+1
-1
@@ -2,7 +2,7 @@ test_scripts = [ 'conftest.py', 'pytest.ini', 'test_sshfs.py',
|
||||
'util.py' ]
|
||||
custom_target('test_scripts', input: test_scripts,
|
||||
output: test_scripts, build_by_default: true,
|
||||
command: ['cp', '-fP', '--preserve=mode',
|
||||
command: ['cp', '-fPp',
|
||||
'@INPUT@', meson.current_build_dir() ])
|
||||
|
||||
# Provide something helpful when running 'ninja test'
|
||||
|
||||
+14
-1
@@ -102,13 +102,14 @@ def test_sshfs(tmpdir, debug, cache_timeout, sync_rd, capfd):
|
||||
# SSHFS only supports one second resolution when setting
|
||||
# file timestamps.
|
||||
tst_utimens(mnt_dir, tol=1)
|
||||
tst_utimens_now(mnt_dir)
|
||||
|
||||
tst_link(mnt_dir, cache_timeout)
|
||||
tst_truncate_path(mnt_dir)
|
||||
tst_truncate_fd(mnt_dir)
|
||||
tst_open_unlink(mnt_dir)
|
||||
except:
|
||||
cleanup(mnt_dir)
|
||||
cleanup(mount_process, mnt_dir)
|
||||
raise
|
||||
else:
|
||||
umount(mount_process, mnt_dir)
|
||||
@@ -403,6 +404,18 @@ def tst_utimens(mnt_dir, tol=0):
|
||||
assert abs(fstat.st_atime_ns - atime_ns) < tol*1e9
|
||||
assert abs(fstat.st_mtime_ns - mtime_ns) < tol*1e9
|
||||
|
||||
def tst_utimens_now(mnt_dir):
|
||||
fullname = pjoin(mnt_dir, name_generator())
|
||||
|
||||
fd = os.open(fullname, os.O_CREAT | os.O_RDWR)
|
||||
os.close(fd)
|
||||
os.utime(fullname, None)
|
||||
|
||||
fstat = os.lstat(fullname)
|
||||
# We should get now-timestamps
|
||||
assert fstat.st_atime != 0
|
||||
assert fstat.st_mtime != 0
|
||||
|
||||
def tst_passthrough(src_dir, mnt_dir, cache_timeout):
|
||||
name = name_generator()
|
||||
src_name = pjoin(src_dir, name)
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
set -e
|
||||
|
||||
sudo python3 -m pip install pytest meson
|
||||
# Meson 0.45 requires Python 3.5 or newer
|
||||
sudo python3 -m pip install pytest meson==0.44
|
||||
wget https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-linux.zip
|
||||
unzip ninja-linux.zip
|
||||
chmod 755 ninja
|
||||
|
||||
+8
-2
@@ -20,13 +20,19 @@ def wait_for_mount(mount_process, mnt_dir,
|
||||
elapsed += 0.1
|
||||
pytest.fail("mountpoint failed to come up")
|
||||
|
||||
def cleanup(mnt_dir):
|
||||
def cleanup(mount_process, mnt_dir):
|
||||
subprocess.call(['fusermount', '-z', '-u', mnt_dir],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.STDOUT)
|
||||
mount_process.terminate()
|
||||
try:
|
||||
mount_process.wait(1)
|
||||
except subprocess.TimeoutExpired:
|
||||
mount_process.kill()
|
||||
|
||||
|
||||
def umount(mount_process, mnt_dir):
|
||||
subprocess.check_call(['fusermount', '-z', '-u', mnt_dir ])
|
||||
subprocess.check_call(['fusermount3', '-z', '-u', mnt_dir ])
|
||||
assert not os.path.ismount(mnt_dir)
|
||||
|
||||
# Give mount process a little while to terminate. Popen.wait(timeout)
|
||||
|
||||
Reference in New Issue
Block a user