summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Changes.txt14
-rw-r--r--PKG-INFO2
-rwxr-xr-xcontrib/benchmark.py99
-rwxr-xr-xcontrib/clone_fs.py1
-rw-r--r--contrib/expire_backups.110
-rwxr-xr-xcontrib/expire_backups.py1
-rw-r--r--contrib/pcp.110
-rwxr-xr-xcontrib/pcp.py1
-rwxr-xr-xcontrib/remove_objects.py1
-rwxr-xr-xcontrib/scramble_db.py1
-rw-r--r--debian/changelog6
-rw-r--r--debian/patches/auto-gitignore15
-rw-r--r--debian/patches/series1
-rw-r--r--debian/patches/show_pdflatex_output.diff4
-rw-r--r--doc/latex/manual.aux259
-rw-r--r--doc/latex/manual.idx2
-rw-r--r--doc/latex/manual.tex132
-rw-r--r--doc/latex/manual.toc106
-rw-r--r--doc/latex/sphinxhighlight.sty104
-rw-r--r--doc/man/fsck.s3ql.12
-rw-r--r--doc/man/mkfs.s3ql.110
-rw-r--r--doc/man/mount.s3ql.17
-rw-r--r--doc/man/s3ql_oauth_client.110
-rw-r--r--doc/man/s3ql_verify.110
-rw-r--r--doc/man/s3qladm.14
-rw-r--r--doc/man/s3qlcp.110
-rw-r--r--doc/man/s3qlctrl.110
-rw-r--r--doc/man/s3qllock.110
-rw-r--r--doc/man/s3qlrm.110
-rw-r--r--doc/man/s3qlstat.110
-rw-r--r--doc/man/umount.s3ql.110
-rw-r--r--doc/manual.pdfbin304501 -> 310192 bytes
-rw-r--r--rst/backends.rst8
-rw-r--r--rst/installation.rst6
-rw-r--r--rst/man/adm.rst2
-rw-r--r--setup.cfg3
-rwxr-xr-xsetup.py19
-rw-r--r--src/s3ql.egg-info/PKG-INFO2
-rw-r--r--src/s3ql.egg-info/requires.txt2
-rw-r--r--src/s3ql/__init__.py2
-rw-r--r--src/s3ql/backends/gs.py94
-rw-r--r--src/s3ql/backends/s3.py6
-rw-r--r--src/s3ql/block_cache.py6
-rw-r--r--src/s3ql/cp.py1
-rw-r--r--src/s3ql/ctrl.py1
-rw-r--r--src/s3ql/lock.py1
-rw-r--r--src/s3ql/mkfs.py1
-rw-r--r--src/s3ql/mount.py12
-rw-r--r--src/s3ql/oauth_client.py53
-rw-r--r--src/s3ql/remove.py1
-rw-r--r--src/s3ql/statfs.py1
-rw-r--r--src/s3ql/umount.py1
-rw-r--r--src/s3ql/verify.py1
-rw-r--r--tests/.pytest_cache/v/cache/lastfailed23
-rw-r--r--tests/.pytest_cache/v/cache/nodeids117
56 files changed, 750 insertions, 486 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..26a7c92
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/.pc/
diff --git a/Changes.txt b/Changes.txt
index a2f9148..f2ed854 100644
--- a/Changes.txt
+++ b/Changes.txt
@@ -1,3 +1,17 @@
+2019-03-31, S3QL 3.1
+
+ * Added a new `--fs-name` option to `mount.s3ql` allowing users
+ to specify a name for the fuse mount (This name is visible
+ in the first column of the system `mount` command output).
+
+ * Added support for "Onezone-IA" to the S3 backend.
+
+ * The `s3ql_oauth_client` command is working again now (it was
+ broken due to changes in Google's OAuth2 workflow).
+
+ * Fixed refresh of Google Storage authentication tokens (expired
+ tokens were resulting in crashes).
+
2019-02-09, S3QL 3.0
* Added a new `--systemd` option to simplify running mount.s3ql
diff --git a/PKG-INFO b/PKG-INFO
index 05cde60..fd4c4fd 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: s3ql
-Version: 3.0
+Version: 3.1
Summary: a full-featured file system for online data storage
Home-page: https://bitbucket.org/nikratio/s3ql/
Author: Nikolaus Rath
diff --git a/contrib/benchmark.py b/contrib/benchmark.py
index 2af39a9..3391a68 100755
--- a/contrib/benchmark.py
+++ b/contrib/benchmark.py
@@ -12,7 +12,7 @@ This work can be distributed under the terms of the GNU GPLv3.
'''
import argparse
-import atexit
+import contextlib
import os
import shutil
import subprocess
@@ -34,7 +34,6 @@ from s3ql.logging import logging, setup_logging, QuietError
from s3ql.common import get_backend
from s3ql.backends.common import DanglingStorageURLError
from s3ql.backends.comprenc import ComprencBackend
-from s3ql.backends.local import Backend
from s3ql import BUFSIZE
from s3ql.parse_args import ArgumentParser
@@ -50,6 +49,7 @@ def parse_args(args):
'compression speed and determine limiting factor.')
parser.add_quiet()
+ parser.add_log()
parser.add_debug()
parser.add_backend_options()
parser.add_version()
@@ -63,6 +63,58 @@ def parse_args(args):
return parser.parse_args(args)
+def test_write_speed(size, blocksize, cachedir, rnd_fh):
+
+ with contextlib.ExitStack() as mgr:
+ mnt_dir = tempfile.mkdtemp(prefix='s3ql-mnt')
+ mgr.callback(shutil.rmtree, mnt_dir)
+
+ backend_dir = tempfile.mkdtemp(prefix='s3ql-benchmark-')
+ mgr.callback(shutil.rmtree, backend_dir)
+
+ subprocess.check_call([exec_prefix + 'mkfs.s3ql', '--plain', 'local://%s' % backend_dir,
+ '--quiet', '--cachedir', cachedir])
+ subprocess.check_call([exec_prefix + 'mount.s3ql', '--threads', '1', '--quiet',
+ '--cachesize', '%d' % (2 * size / 1024), '--log',
+ '%s/mount.log' % backend_dir, '--cachedir', cachedir,
+ 'local://%s' % backend_dir, mnt_dir])
+ try:
+ write_time = 0
+ while write_time < 3:
+ log.debug('Write took %.3g seconds, retrying', write_time)
+ size *= 2
+ with open('%s/bigfile' % mnt_dir, 'wb', 0) as dst:
+ rnd_fh.seek(0)
+ write_time = time.time()
+ copied = 0
+ while copied < size:
+ buf = rnd_fh.read(blocksize)
+ if not buf:
+ rnd_fh.seek(0)
+ continue
+ dst.write(buf)
+ copied += len(buf)
+ write_time = time.time() - write_time
+ os.unlink('%s/bigfile' % mnt_dir)
+ finally:
+ subprocess.check_call([exec_prefix + 'umount.s3ql', mnt_dir])
+
+ return copied / write_time
+
+
+class MockBackend:
+ def open_write(key, metadata=None, is_compressed=False):
+ return MockFH()
+
+
+class MockFH:
+ def write(self, buf):
+ pass
+
+ def close(self):
+ pass
+
+
def main(args=None):
if args is None:
args = sys.argv[1:]
@@ -81,43 +133,10 @@ def main(args=None):
copied += len(buf)
log.info('Measuring throughput to cache...')
- backend_dir = tempfile.mkdtemp(prefix='s3ql-benchmark-')
- mnt_dir = tempfile.mkdtemp(prefix='s3ql-mnt')
- atexit.register(shutil.rmtree, backend_dir)
- atexit.register(shutil.rmtree, mnt_dir)
-
block_sizes = [ 2**b for b in range(12, 18) ]
for blocksize in block_sizes:
- write_time = 0
size = 50 * 1024 * 1024
- while write_time < 3:
- log.debug('Write took %.3g seconds, retrying', write_time)
- subprocess.check_call([exec_prefix + 'mkfs.s3ql', '--plain', 'local://%s' % backend_dir,
- '--quiet', '--force', '--cachedir', options.cachedir])
- subprocess.check_call([exec_prefix + 'mount.s3ql', '--threads', '1', '--quiet',
- '--cachesize', '%d' % (2 * size / 1024), '--log',
- '%s/mount.log' % backend_dir, '--cachedir', options.cachedir,
- 'local://%s' % backend_dir, mnt_dir])
- try:
- size *= 2
- with open('%s/bigfile' % mnt_dir, 'wb', 0) as dst:
- rnd_fh.seek(0)
- write_time = time.time()
- copied = 0
- while copied < size:
- buf = rnd_fh.read(blocksize)
- if not buf:
- rnd_fh.seek(0)
- continue
- dst.write(buf)
- copied += len(buf)
-
- write_time = time.time() - write_time
- os.unlink('%s/bigfile' % mnt_dir)
- finally:
- subprocess.check_call([exec_prefix + 'umount.s3ql', mnt_dir])
-
- fuse_speed = copied / write_time
+ fuse_speed = test_write_speed(size, blocksize, options.cachedir, rnd_fh)
log.info('Cache throughput with %3d KiB blocks: %d KiB/sec',
blocksize / 1024, fuse_speed / 1024)
@@ -159,7 +178,7 @@ def main(args=None):
out_speed = dict()
for alg in ALGS:
log.info('compressing with %s-6...', alg)
- backend = ComprencBackend(b'pass', (alg, 6),Backend(argparse.Namespace(storage_url='local://' + backend_dir)))
+ backend = ComprencBackend(b'pass', (alg, 6), MockBackend())
def do_write(dst): #pylint: disable=E0102
src.seek(0)
stamp = time.time()
@@ -188,7 +207,7 @@ def main(args=None):
threads.add(options.threads)
print('%-26s' % 'Threads:',
- ('%12d' * len(threads)) % tuple(sorted(threads)))
+ ('%16d' * len(threads)) % tuple(sorted(threads)))
for alg in ALGS:
speeds = []
@@ -209,9 +228,9 @@ def main(args=None):
speeds.append(speed / 1024)
print('%-26s' % ('Max FS throughput (%s):' % alg),
- ('%7d KiB/s' * len(threads)) % tuple(speeds))
+ ('%10d KiB/s' * len(threads)) % tuple(speeds))
print('%-26s' % '..limited by:',
- ('%12s' * len(threads)) % tuple(limits))
+ ('%16s' * len(threads)) % tuple(limits))
print('')
print('All numbers assume that the test file is representative and that',
diff --git a/contrib/clone_fs.py b/contrib/clone_fs.py
index 389630c..6b78d55 100755
--- a/contrib/clone_fs.py
+++ b/contrib/clone_fs.py
@@ -39,6 +39,7 @@ def parse_args(args):
description='Clone an S3QL file system.')
parser.add_quiet()
+ parser.add_log()
parser.add_debug()
parser.add_backend_options()
parser.add_version()
diff --git a/contrib/expire_backups.1 b/contrib/expire_backups.1
index 940edb2..2903214 100644
--- a/contrib/expire_backups.1
+++ b/contrib/expire_backups.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "EXPIRE_BACKUPS" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "EXPIRE_BACKUPS" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
expire_backups \- Intelligently expire old backups
.
@@ -130,6 +130,14 @@ The \fBexpire_backups\fP command accepts the following options:
.B \-\-quiet
be really quiet
.TP
+.BI \-\-log \ <target>
+Destination for log messages. Specify \fBnone\fP for
+standard output or \fBsyslog\fP for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\fBNone\fP
+.TP
.BI \-\-debug\-modules \ <modules>
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
diff --git a/contrib/expire_backups.py b/contrib/expire_backups.py
index 3f7c159..aebab85 100755
--- a/contrib/expire_backups.py
+++ b/contrib/expire_backups.py
@@ -51,6 +51,7 @@ def parse_args(args):
'''))
parser.add_quiet()
+ parser.add_log()
parser.add_debug()
parser.add_version()
diff --git a/contrib/pcp.1 b/contrib/pcp.1
index 3018d30..c420988 100644
--- a/contrib/pcp.1
+++ b/contrib/pcp.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "PCP" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "PCP" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
pcp \- Recursive, parallel copy of directory trees
.
@@ -58,6 +58,14 @@ The \fBpcp\fP command accepts the following options:
.INDENT 3.5
.INDENT 0.0
.TP
+.BI \-\-log \ <target>
+Destination for log messages. Specify \fBnone\fP for
+standard output or \fBsyslog\fP for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\fBNone\fP
+.TP
.B \-\-quiet
be really quiet
.TP
diff --git a/contrib/pcp.py b/contrib/pcp.py
index f18699a..c192add 100755
--- a/contrib/pcp.py
+++ b/contrib/pcp.py
@@ -33,6 +33,7 @@ def parse_args(args):
description='Recursively copy source(s) to destination using multiple '
'parallel rsync processes.')
+ parser.add_log()
parser.add_quiet()
parser.add_debug()
parser.add_version()
diff --git a/contrib/remove_objects.py b/contrib/remove_objects.py
index 3e53def..1d96a2f 100755
--- a/contrib/remove_objects.py
+++ b/contrib/remove_objects.py
@@ -32,6 +32,7 @@ def parse_args(args):
parser.add_storage_url()
parser.add_quiet()
+ parser.add_log()
parser.add_debug()
parser.add_backend_options()
parser.add_version()
diff --git a/contrib/scramble_db.py b/contrib/scramble_db.py
index 11ba09d..70fcf4c 100755
--- a/contrib/scramble_db.py
+++ b/contrib/scramble_db.py
@@ -44,6 +44,7 @@ def parse_args(args):
"This is intended to preserve privacy when a metadata copy "
"needs to be provided to the developers for debugging.")
+ parser.add_log()
parser.add_debug()
parser.add_quiet()
parser.add_version()
diff --git a/debian/changelog b/debian/changelog
index 1dde460..c2947e0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+s3ql (3.1+dfsg-1) unstable; urgency=medium
+
+ * New upstream release.
+
+ -- Nikolaus Rath <Nikolaus@rath.org> Sat, 06 Apr 2019 16:28:05 +0100
+
s3ql (3.0+dfsg-1) unstable; urgency=medium
* New upstream release.
diff --git a/debian/patches/auto-gitignore b/debian/patches/auto-gitignore
new file mode 100644
index 0000000..a7a4674
--- /dev/null
+++ b/debian/patches/auto-gitignore
@@ -0,0 +1,15 @@
+Subject: Update .gitignore from Debian packaging branch
+
+The Debian packaging git branch contains these updates to the upstream
+.gitignore file(s). This patch is autogenerated, to provide these
+updates to users of the official Debian archive view of the package.
+
+[dgit (3.11~deb9u1) update-gitignore]
+---
+diff --git a/.gitignore b/.gitignore
+new file mode 100644
+index 0000000..26a7c92
+--- /dev/null
++++ b/.gitignore
+@@ -0,0 +1 @@
++/.pc/
diff --git a/debian/patches/series b/debian/patches/series
index 05b8717..f349004 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,4 @@
proc_mount.diff
clock-granularity.diff
show_pdflatex_output.diff
+auto-gitignore
diff --git a/debian/patches/show_pdflatex_output.diff b/debian/patches/show_pdflatex_output.diff
index 9e49722..b8269f3 100644
--- a/debian/patches/show_pdflatex_output.diff
+++ b/debian/patches/show_pdflatex_output.diff
@@ -12,10 +12,10 @@ Upstream is not interested in this patch.
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/setup.py b/setup.py
-index 4f28bd3..7d2dc48 100755
+index 02964e1..ee7a257 100755
--- a/setup.py
+++ b/setup.py
-@@ -98,9 +98,8 @@ class build_docs(setuptools.Command):
+@@ -99,9 +99,8 @@ class build_docs(setuptools.Command):
print('Running pdflatex...')
for _ in range(3):
diff --git a/doc/latex/manual.aux b/doc/latex/manual.aux
index 2ee1ba1..50e86ad 100644
--- a/doc/latex/manual.aux
+++ b/doc/latex/manual.aux
@@ -65,24 +65,25 @@
\newlabel{backends:cmdoption-s3-backend-arg-tcp-timeout}{{3.2}{8}{Amazon S3}{section*.7}{}}
\newlabel{backends:cmdoption-s3-backend-arg-sse}{{3.2}{8}{Amazon S3}{section*.8}{}}
\newlabel{backends:cmdoption-s3-backend-arg-ia}{{3.2}{8}{Amazon S3}{section*.9}{}}
-\newlabel{backends:cmdoption-s3-backend-arg-rrs}{{3.2}{8}{Amazon S3}{section*.10}{}}
+\newlabel{backends:cmdoption-s3-backend-arg-oia}{{3.2}{8}{Amazon S3}{section*.10}{}}
+\newlabel{backends:cmdoption-s3-backend-arg-rrs}{{3.2}{8}{Amazon S3}{section*.11}{}}
\@writefile{toc}{\contentsline {section}{\numberline {3.3}OpenStack/Swift}{9}{section.3.3}}
\newlabel{backends:openstack-swift}{{3.3}{9}{OpenStack/Swift}{section.3.3}{}}
\newlabel{backends:openstack-backend}{{3.3}{9}{OpenStack/Swift}{section.3.3}{}}
-\newlabel{backends:cmdoption-swift-backend-arg-no-ssl}{{3.3}{9}{OpenStack/Swift}{section*.11}{}}
-\newlabel{backends:cmdoption-swift-backend-arg-ssl-ca-path}{{3.3}{9}{OpenStack/Swift}{section*.12}{}}
-\newlabel{backends:cmdoption-swift-backend-arg-tcp-timeout}{{3.3}{9}{OpenStack/Swift}{section*.13}{}}
-\newlabel{backends:cmdoption-swift-backend-arg-disable-expect100}{{3.3}{9}{OpenStack/Swift}{section*.14}{}}
-\newlabel{backends:cmdoption-swift-backend-arg-no-feature-detection}{{3.3}{9}{OpenStack/Swift}{section*.15}{}}
+\newlabel{backends:cmdoption-swift-backend-arg-no-ssl}{{3.3}{9}{OpenStack/Swift}{section*.12}{}}
+\newlabel{backends:cmdoption-swift-backend-arg-ssl-ca-path}{{3.3}{9}{OpenStack/Swift}{section*.13}{}}
+\newlabel{backends:cmdoption-swift-backend-arg-tcp-timeout}{{3.3}{9}{OpenStack/Swift}{section*.14}{}}
+\newlabel{backends:cmdoption-swift-backend-arg-disable-expect100}{{3.3}{9}{OpenStack/Swift}{section*.15}{}}
+\newlabel{backends:cmdoption-swift-backend-arg-no-feature-detection}{{3.3}{9}{OpenStack/Swift}{section*.16}{}}
\@writefile{toc}{\contentsline {section}{\numberline {3.4}Rackspace CloudFiles}{10}{section.3.4}}
\newlabel{backends:rackspace-cloudfiles}{{3.4}{10}{Rackspace CloudFiles}{section.3.4}{}}
\@writefile{toc}{\contentsline {section}{\numberline {3.5}S3 compatible}{10}{section.3.5}}
\newlabel{backends:s3-compatible}{{3.5}{10}{S3 compatible}{section.3.5}{}}
-\newlabel{backends:cmdoption-s3c-backend-arg-no-ssl}{{3.5}{10}{S3 compatible}{section*.16}{}}
-\newlabel{backends:cmdoption-s3c-backend-arg-ssl-ca-path}{{3.5}{10}{S3 compatible}{section*.17}{}}
-\newlabel{backends:cmdoption-s3c-backend-arg-tcp-timeout}{{3.5}{10}{S3 compatible}{section*.18}{}}
-\newlabel{backends:cmdoption-s3c-backend-arg-disable-expect100}{{3.5}{10}{S3 compatible}{section*.19}{}}
-\newlabel{backends:cmdoption-s3c-backend-arg-dumb-copy}{{3.5}{10}{S3 compatible}{section*.20}{}}
+\newlabel{backends:cmdoption-s3c-backend-arg-no-ssl}{{3.5}{10}{S3 compatible}{section*.17}{}}
+\newlabel{backends:cmdoption-s3c-backend-arg-ssl-ca-path}{{3.5}{10}{S3 compatible}{section*.18}{}}
+\newlabel{backends:cmdoption-s3c-backend-arg-tcp-timeout}{{3.5}{10}{S3 compatible}{section*.19}{}}
+\newlabel{backends:cmdoption-s3c-backend-arg-disable-expect100}{{3.5}{10}{S3 compatible}{section*.20}{}}
+\newlabel{backends:cmdoption-s3c-backend-arg-dumb-copy}{{3.5}{10}{S3 compatible}{section*.21}{}}
\@writefile{toc}{\contentsline {section}{\numberline {3.6}Local}{11}{section.3.6}}
\newlabel{backends:local}{{3.6}{11}{Local}{section.3.6}{}}
\@writefile{toc}{\contentsline {chapter}{\numberline {4}Important Rules to Avoid Losing Data}{13}{chapter.4}}
@@ -275,8 +276,8 @@
\newlabel{man/adm::doc}{{16.2}{52}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qladm}} command}{section.16.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.2.1}Synopsis}{52}{subsection.16.2.1}}
\newlabel{man/adm:synopsis}{{16.2.1}{52}{Synopsis}{subsection.16.2.1}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.2.2}Description}{52}{subsection.16.2.2}}
-\newlabel{man/adm:description}{{16.2.2}{52}{Description}{subsection.16.2.2}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.2.2}Description}{53}{subsection.16.2.2}}
+\newlabel{man/adm:description}{{16.2.2}{53}{Description}{subsection.16.2.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.2.3}Options}{53}{subsection.16.2.3}}
\newlabel{man/adm:options}{{16.2.3}{53}{Options}{subsection.16.2.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.2.4}Actions}{53}{subsection.16.2.4}}
@@ -303,8 +304,8 @@
\newlabel{man/stat::doc}{{16.4}{56}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlstat}} command}{section.16.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.4.1}Synopsis}{56}{subsection.16.4.1}}
\newlabel{man/stat:synopsis}{{16.4.1}{56}{Synopsis}{subsection.16.4.1}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.4.2}Description}{56}{subsection.16.4.2}}
-\newlabel{man/stat:description}{{16.4.2}{56}{Description}{subsection.16.4.2}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.4.2}Description}{57}{subsection.16.4.2}}
+\newlabel{man/stat:description}{{16.4.2}{57}{Description}{subsection.16.4.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.4.3}Options}{57}{subsection.16.4.3}}
\newlabel{man/stat:options}{{16.4.3}{57}{Options}{subsection.16.4.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.4.4}Exit Codes}{57}{subsection.16.4.4}}
@@ -316,27 +317,27 @@
\newlabel{man/ctrl::doc}{{16.5}{57}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlctrl}} command}{section.16.5}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.5.1}Synopsis}{57}{subsection.16.5.1}}
\newlabel{man/ctrl:synopsis}{{16.5.1}{57}{Synopsis}{subsection.16.5.1}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.5.2}Description}{57}{subsection.16.5.2}}
-\newlabel{man/ctrl:description}{{16.5.2}{57}{Description}{subsection.16.5.2}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.5.2}Description}{58}{subsection.16.5.2}}
+\newlabel{man/ctrl:description}{{16.5.2}{58}{Description}{subsection.16.5.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.5.3}Options}{58}{subsection.16.5.3}}
\newlabel{man/ctrl:options}{{16.5.3}{58}{Options}{subsection.16.5.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.5.4}Exit Codes}{58}{subsection.16.5.4}}
\newlabel{man/ctrl:exit-codes}{{16.5.4}{58}{Exit Codes}{subsection.16.5.4}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.5.5}See Also}{58}{subsection.16.5.5}}
-\newlabel{man/ctrl:see-also}{{16.5.5}{58}{See Also}{subsection.16.5.5}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {16.6}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{58}{section.16.6}}
-\newlabel{man/cp:the-command-command}{{16.6}{58}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{section.16.6}{}}
-\newlabel{man/cp::doc}{{16.6}{58}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{section.16.6}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.1}Synopsis}{58}{subsection.16.6.1}}
-\newlabel{man/cp:synopsis}{{16.6.1}{58}{Synopsis}{subsection.16.6.1}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.5.5}See Also}{59}{subsection.16.5.5}}
+\newlabel{man/ctrl:see-also}{{16.5.5}{59}{See Also}{subsection.16.5.5}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {16.6}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{59}{section.16.6}}
+\newlabel{man/cp:the-command-command}{{16.6}{59}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{section.16.6}{}}
+\newlabel{man/cp::doc}{{16.6}{59}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{section.16.6}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.1}Synopsis}{59}{subsection.16.6.1}}
+\newlabel{man/cp:synopsis}{{16.6.1}{59}{Synopsis}{subsection.16.6.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.2}Description}{59}{subsection.16.6.2}}
\newlabel{man/cp:description}{{16.6.2}{59}{Description}{subsection.16.6.2}{}}
-\@writefile{toc}{\contentsline {subsubsection}{Snapshotting vs Hardlinking}{59}{subsubsection*.21}}
-\newlabel{man/cp:snapshotting-vs-hardlinking}{{16.6.2}{59}{Snapshotting vs Hardlinking}{subsubsection*.21}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.3}Options}{59}{subsection.16.6.3}}
-\newlabel{man/cp:options}{{16.6.3}{59}{Options}{subsection.16.6.3}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.4}Exit Codes}{59}{subsection.16.6.4}}
-\newlabel{man/cp:exit-codes}{{16.6.4}{59}{Exit Codes}{subsection.16.6.4}{}}
+\@writefile{toc}{\contentsline {subsubsection}{Snapshotting vs Hardlinking}{59}{subsubsection*.22}}
+\newlabel{man/cp:snapshotting-vs-hardlinking}{{16.6.2}{59}{Snapshotting vs Hardlinking}{subsubsection*.22}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.3}Options}{60}{subsection.16.6.3}}
+\newlabel{man/cp:options}{{16.6.3}{60}{Options}{subsection.16.6.3}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.4}Exit Codes}{60}{subsection.16.6.4}}
+\newlabel{man/cp:exit-codes}{{16.6.4}{60}{Exit Codes}{subsection.16.6.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.5}See Also}{60}{subsection.16.6.5}}
\newlabel{man/cp:see-also}{{16.6.5}{60}{See Also}{subsection.16.6.5}{}}
\@writefile{toc}{\contentsline {section}{\numberline {16.7}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlrm}} command}{60}{section.16.7}}
@@ -346,10 +347,10 @@
\newlabel{man/rm:synopsis}{{16.7.1}{60}{Synopsis}{subsection.16.7.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.7.2}Description}{60}{subsection.16.7.2}}
\newlabel{man/rm:description}{{16.7.2}{60}{Description}{subsection.16.7.2}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.7.3}Options}{60}{subsection.16.7.3}}
-\newlabel{man/rm:options}{{16.7.3}{60}{Options}{subsection.16.7.3}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.7.4}Exit Codes}{60}{subsection.16.7.4}}
-\newlabel{man/rm:exit-codes}{{16.7.4}{60}{Exit Codes}{subsection.16.7.4}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.7.3}Options}{61}{subsection.16.7.3}}
+\newlabel{man/rm:options}{{16.7.3}{61}{Options}{subsection.16.7.3}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.7.4}Exit Codes}{61}{subsection.16.7.4}}
+\newlabel{man/rm:exit-codes}{{16.7.4}{61}{Exit Codes}{subsection.16.7.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.7.5}See Also}{61}{subsection.16.7.5}}
\newlabel{man/rm:see-also}{{16.7.5}{61}{See Also}{subsection.16.7.5}{}}
\@writefile{toc}{\contentsline {section}{\numberline {16.8}The \sphinxstyleliteralstrong {\sphinxupquote {s3qllock}} command}{61}{section.16.8}}
@@ -359,114 +360,114 @@
\newlabel{man/lock:synopsis}{{16.8.1}{61}{Synopsis}{subsection.16.8.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.8.2}Description}{61}{subsection.16.8.2}}
\newlabel{man/lock:description}{{16.8.2}{61}{Description}{subsection.16.8.2}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.8.3}Rationale}{61}{subsection.16.8.3}}
-\newlabel{man/lock:rationale}{{16.8.3}{61}{Rationale}{subsection.16.8.3}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.8.4}Options}{61}{subsection.16.8.4}}
-\newlabel{man/lock:options}{{16.8.4}{61}{Options}{subsection.16.8.4}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.8.3}Rationale}{62}{subsection.16.8.3}}
+\newlabel{man/lock:rationale}{{16.8.3}{62}{Rationale}{subsection.16.8.3}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.8.4}Options}{62}{subsection.16.8.4}}
+\newlabel{man/lock:options}{{16.8.4}{62}{Options}{subsection.16.8.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.8.5}Exit Codes}{62}{subsection.16.8.5}}
\newlabel{man/lock:exit-codes}{{16.8.5}{62}{Exit Codes}{subsection.16.8.5}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.8.6}See Also}{62}{subsection.16.8.6}}
\newlabel{man/lock:see-also}{{16.8.6}{62}{See Also}{subsection.16.8.6}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {16.9}The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{62}{section.16.9}}
-\newlabel{man/umount:the-command-command}{{16.9}{62}{The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{section.16.9}{}}
-\newlabel{man/umount::doc}{{16.9}{62}{The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{section.16.9}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.1}Synopsis}{62}{subsection.16.9.1}}
-\newlabel{man/umount:synopsis}{{16.9.1}{62}{Synopsis}{subsection.16.9.1}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.2}Description}{62}{subsection.16.9.2}}
-\newlabel{man/umount:description}{{16.9.2}{62}{Description}{subsection.16.9.2}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.3}Options}{62}{subsection.16.9.3}}
-\newlabel{man/umount:options}{{16.9.3}{62}{Options}{subsection.16.9.3}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {16.9}The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{63}{section.16.9}}
+\newlabel{man/umount:the-command-command}{{16.9}{63}{The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{section.16.9}{}}
+\newlabel{man/umount::doc}{{16.9}{63}{The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{section.16.9}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.1}Synopsis}{63}{subsection.16.9.1}}
+\newlabel{man/umount:synopsis}{{16.9.1}{63}{Synopsis}{subsection.16.9.1}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.2}Description}{63}{subsection.16.9.2}}
+\newlabel{man/umount:description}{{16.9.2}{63}{Description}{subsection.16.9.2}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.3}Options}{63}{subsection.16.9.3}}
+\newlabel{man/umount:options}{{16.9.3}{63}{Options}{subsection.16.9.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.4}Exit Codes}{63}{subsection.16.9.4}}
\newlabel{man/umount:exit-codes}{{16.9.4}{63}{Exit Codes}{subsection.16.9.4}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.5}See Also}{63}{subsection.16.9.5}}
-\newlabel{man/umount:see-also}{{16.9.5}{63}{See Also}{subsection.16.9.5}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {16.10}The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{63}{section.16.10}}
-\newlabel{man/fsck:the-command-command}{{16.10}{63}{The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{section.16.10}{}}
-\newlabel{man/fsck::doc}{{16.10}{63}{The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{section.16.10}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.1}Synopsis}{63}{subsection.16.10.1}}
-\newlabel{man/fsck:synopsis}{{16.10.1}{63}{Synopsis}{subsection.16.10.1}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.2}Description}{63}{subsection.16.10.2}}
-\newlabel{man/fsck:description}{{16.10.2}{63}{Description}{subsection.16.10.2}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.3}Options}{63}{subsection.16.10.3}}
-\newlabel{man/fsck:options}{{16.10.3}{63}{Options}{subsection.16.10.3}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.4}Exit Codes}{64}{subsection.16.10.4}}
-\newlabel{man/fsck:exit-codes}{{16.10.4}{64}{Exit Codes}{subsection.16.10.4}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.5}See Also}{64}{subsection.16.9.5}}
+\newlabel{man/umount:see-also}{{16.9.5}{64}{See Also}{subsection.16.9.5}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {16.10}The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{64}{section.16.10}}
+\newlabel{man/fsck:the-command-command}{{16.10}{64}{The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{section.16.10}{}}
+\newlabel{man/fsck::doc}{{16.10}{64}{The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{section.16.10}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.1}Synopsis}{64}{subsection.16.10.1}}
+\newlabel{man/fsck:synopsis}{{16.10.1}{64}{Synopsis}{subsection.16.10.1}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.2}Description}{64}{subsection.16.10.2}}
+\newlabel{man/fsck:description}{{16.10.2}{64}{Description}{subsection.16.10.2}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.3}Options}{64}{subsection.16.10.3}}
+\newlabel{man/fsck:options}{{16.10.3}{64}{Options}{subsection.16.10.3}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.4}Exit Codes}{65}{subsection.16.10.4}}
+\newlabel{man/fsck:exit-codes}{{16.10.4}{65}{Exit Codes}{subsection.16.10.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.5}See Also}{65}{subsection.16.10.5}}
\newlabel{man/fsck:see-also}{{16.10.5}{65}{See Also}{subsection.16.10.5}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {16.11}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{65}{section.16.11}}
-\newlabel{man/oauth_client:the-command-command}{{16.11}{65}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}}
-\newlabel{man/oauth_client:oauth-client}{{16.11}{65}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}}
-\newlabel{man/oauth_client::doc}{{16.11}{65}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.1}Synopsis}{65}{subsection.16.11.1}}
-\newlabel{man/oauth_client:synopsis}{{16.11.1}{65}{Synopsis}{subsection.16.11.1}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.2}Description}{65}{subsection.16.11.2}}
-\newlabel{man/oauth_client:description}{{16.11.2}{65}{Description}{subsection.16.11.2}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.3}Options}{65}{subsection.16.11.3}}
-\newlabel{man/oauth_client:options}{{16.11.3}{65}{Options}{subsection.16.11.3}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.4}Exit Codes}{65}{subsection.16.11.4}}
-\newlabel{man/oauth_client:exit-codes}{{16.11.4}{65}{Exit Codes}{subsection.16.11.4}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {16.11}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{66}{section.16.11}}
+\newlabel{man/oauth_client:the-command-command}{{16.11}{66}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}}
+\newlabel{man/oauth_client:oauth-client}{{16.11}{66}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}}
+\newlabel{man/oauth_client::doc}{{16.11}{66}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.1}Synopsis}{66}{subsection.16.11.1}}
+\newlabel{man/oauth_client:synopsis}{{16.11.1}{66}{Synopsis}{subsection.16.11.1}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.2}Description}{66}{subsection.16.11.2}}
+\newlabel{man/oauth_client:description}{{16.11.2}{66}{Description}{subsection.16.11.2}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.3}Options}{66}{subsection.16.11.3}}
+\newlabel{man/oauth_client:options}{{16.11.3}{66}{Options}{subsection.16.11.3}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.4}Exit Codes}{66}{subsection.16.11.4}}
+\newlabel{man/oauth_client:exit-codes}{{16.11.4}{66}{Exit Codes}{subsection.16.11.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.5}See Also}{66}{subsection.16.11.5}}
\newlabel{man/oauth_client:see-also}{{16.11.5}{66}{See Also}{subsection.16.11.5}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {16.12}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{66}{section.16.12}}
-\newlabel{man/verify:the-command-command}{{16.12}{66}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{section.16.12}{}}
-\newlabel{man/verify::doc}{{16.12}{66}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{section.16.12}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.1}Synopsis}{66}{subsection.16.12.1}}
-\newlabel{man/verify:synopsis}{{16.12.1}{66}{Synopsis}{subsection.16.12.1}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.2}Description}{66}{subsection.16.12.2}}
-\newlabel{man/verify:description}{{16.12.2}{66}{Description}{subsection.16.12.2}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.3}Options}{66}{subsection.16.12.3}}
-\newlabel{man/verify:options}{{16.12.3}{66}{Options}{subsection.16.12.3}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {16.12}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{67}{section.16.12}}
+\newlabel{man/verify:the-command-command}{{16.12}{67}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{section.16.12}{}}
+\newlabel{man/verify::doc}{{16.12}{67}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{section.16.12}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.1}Synopsis}{67}{subsection.16.12.1}}
+\newlabel{man/verify:synopsis}{{16.12.1}{67}{Synopsis}{subsection.16.12.1}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.2}Description}{67}{subsection.16.12.2}}
+\newlabel{man/verify:description}{{16.12.2}{67}{Description}{subsection.16.12.2}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.3}Options}{67}{subsection.16.12.3}}
+\newlabel{man/verify:options}{{16.12.3}{67}{Options}{subsection.16.12.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.4}Exit Codes}{67}{subsection.16.12.4}}
\newlabel{man/verify:exit-codes}{{16.12.4}{67}{Exit Codes}{subsection.16.12.4}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.5}See Also}{67}{subsection.16.12.5}}
-\newlabel{man/verify:see-also}{{16.12.5}{67}{See Also}{subsection.16.12.5}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {16.13}The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{67}{section.16.13}}
-\newlabel{man/pcp:the-command-command}{{16.13}{67}{The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{section.16.13}{}}
-\newlabel{man/pcp::doc}{{16.13}{67}{The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{section.16.13}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.1}Synopsis}{67}{subsection.16.13.1}}
-\newlabel{man/pcp:synopsis}{{16.13.1}{67}{Synopsis}{subsection.16.13.1}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.2}Description}{67}{subsection.16.13.2}}
-\newlabel{man/pcp:description}{{16.13.2}{67}{Description}{subsection.16.13.2}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.3}Options}{68}{subsection.16.13.3}}
-\newlabel{man/pcp:options}{{16.13.3}{68}{Options}{subsection.16.13.3}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.4}Exit Codes}{68}{subsection.16.13.4}}
-\newlabel{man/pcp:exit-codes}{{16.13.4}{68}{Exit Codes}{subsection.16.13.4}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.5}See Also}{68}{subsection.16.13.5}}
-\newlabel{man/pcp:see-also}{{16.13.5}{68}{See Also}{subsection.16.13.5}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {16.14}The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{68}{section.16.14}}
-\newlabel{man/expire_backups:the-command-command}{{16.14}{68}{The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{section.16.14}{}}
-\newlabel{man/expire_backups::doc}{{16.14}{68}{The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{section.16.14}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.1}Synopsis}{68}{subsection.16.14.1}}
-\newlabel{man/expire_backups:synopsis}{{16.14.1}{68}{Synopsis}{subsection.16.14.1}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.2}Description}{68}{subsection.16.14.2}}
-\newlabel{man/expire_backups:description}{{16.14.2}{68}{Description}{subsection.16.14.2}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.3}Options}{69}{subsection.16.14.3}}
-\newlabel{man/expire_backups:options}{{16.14.3}{69}{Options}{subsection.16.14.3}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.4}Exit Codes}{70}{subsection.16.14.4}}
-\newlabel{man/expire_backups:exit-codes}{{16.14.4}{70}{Exit Codes}{subsection.16.14.4}{}}
-\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.5}See Also}{70}{subsection.16.14.5}}
-\newlabel{man/expire_backups:see-also}{{16.14.5}{70}{See Also}{subsection.16.14.5}{}}
-\@writefile{toc}{\contentsline {chapter}{\numberline {17}Further Resources / Getting Help}{71}{chapter.17}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.5}See Also}{68}{subsection.16.12.5}}
+\newlabel{man/verify:see-also}{{16.12.5}{68}{See Also}{subsection.16.12.5}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {16.13}The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{68}{section.16.13}}
+\newlabel{man/pcp:the-command-command}{{16.13}{68}{The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{section.16.13}{}}
+\newlabel{man/pcp::doc}{{16.13}{68}{The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{section.16.13}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.1}Synopsis}{68}{subsection.16.13.1}}
+\newlabel{man/pcp:synopsis}{{16.13.1}{68}{Synopsis}{subsection.16.13.1}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.2}Description}{68}{subsection.16.13.2}}
+\newlabel{man/pcp:description}{{16.13.2}{68}{Description}{subsection.16.13.2}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.3}Options}{69}{subsection.16.13.3}}
+\newlabel{man/pcp:options}{{16.13.3}{69}{Options}{subsection.16.13.3}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.4}Exit Codes}{69}{subsection.16.13.4}}
+\newlabel{man/pcp:exit-codes}{{16.13.4}{69}{Exit Codes}{subsection.16.13.4}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.5}See Also}{69}{subsection.16.13.5}}
+\newlabel{man/pcp:see-also}{{16.13.5}{69}{See Also}{subsection.16.13.5}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {16.14}The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{69}{section.16.14}}
+\newlabel{man/expire_backups:the-command-command}{{16.14}{69}{The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{section.16.14}{}}
+\newlabel{man/expire_backups::doc}{{16.14}{69}{The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{section.16.14}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.1}Synopsis}{69}{subsection.16.14.1}}
+\newlabel{man/expire_backups:synopsis}{{16.14.1}{69}{Synopsis}{subsection.16.14.1}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.2}Description}{69}{subsection.16.14.2}}
+\newlabel{man/expire_backups:description}{{16.14.2}{69}{Description}{subsection.16.14.2}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.3}Options}{70}{subsection.16.14.3}}
+\newlabel{man/expire_backups:options}{{16.14.3}{70}{Options}{subsection.16.14.3}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.4}Exit Codes}{71}{subsection.16.14.4}}
+\newlabel{man/expire_backups:exit-codes}{{16.14.4}{71}{Exit Codes}{subsection.16.14.4}{}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.5}See Also}{71}{subsection.16.14.5}}
+\newlabel{man/expire_backups:see-also}{{16.14.5}{71}{See Also}{subsection.16.14.5}{}}
+\@writefile{toc}{\contentsline {chapter}{\numberline {17}Further Resources / Getting Help}{73}{chapter.17}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
-\newlabel{resources:further-resources-getting-help}{{17}{71}{Further Resources / Getting Help}{chapter.17}{}}
-\newlabel{resources:resources}{{17}{71}{Further Resources / Getting Help}{chapter.17}{}}
-\newlabel{resources::doc}{{17}{71}{Further Resources / Getting Help}{chapter.17}{}}
-\@writefile{toc}{\contentsline {chapter}{\numberline {18}Implementation Details}{73}{chapter.18}}
+\newlabel{resources:further-resources-getting-help}{{17}{73}{Further Resources / Getting Help}{chapter.17}{}}
+\newlabel{resources:resources}{{17}{73}{Further Resources / Getting Help}{chapter.17}{}}
+\newlabel{resources::doc}{{17}{73}{Further Resources / Getting Help}{chapter.17}{}}
+\@writefile{toc}{\contentsline {chapter}{\numberline {18}Implementation Details}{75}{chapter.18}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
-\newlabel{impl_details:implementation-details}{{18}{73}{Implementation Details}{chapter.18}{}}
-\newlabel{impl_details:impl-details}{{18}{73}{Implementation Details}{chapter.18}{}}
-\newlabel{impl_details::doc}{{18}{73}{Implementation Details}{chapter.18}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {18.1}Metadata Storage}{73}{section.18.1}}
-\newlabel{impl_details:metadata-storage}{{18.1}{73}{Metadata Storage}{section.18.1}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {18.2}Data Storage}{73}{section.18.2}}
-\newlabel{impl_details:data-storage}{{18.2}{73}{Data Storage}{section.18.2}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {18.3}Data De-Duplication}{74}{section.18.3}}
-\newlabel{impl_details:data-de-duplication}{{18.3}{74}{Data De-Duplication}{section.18.3}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {18.4}Caching}{74}{section.18.4}}
-\newlabel{impl_details:caching}{{18.4}{74}{Caching}{section.18.4}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {18.5}Eventual Consistency Handling}{74}{section.18.5}}
-\newlabel{impl_details:eventual-consistency-handling}{{18.5}{74}{Eventual Consistency Handling}{section.18.5}{}}
-\@writefile{toc}{\contentsline {section}{\numberline {18.6}Encryption}{74}{section.18.6}}
-\newlabel{impl_details:encryption}{{18.6}{74}{Encryption}{section.18.6}{}}
+\newlabel{impl_details:implementation-details}{{18}{75}{Implementation Details}{chapter.18}{}}
+\newlabel{impl_details:impl-details}{{18}{75}{Implementation Details}{chapter.18}{}}
+\newlabel{impl_details::doc}{{18}{75}{Implementation Details}{chapter.18}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {18.1}Metadata Storage}{75}{section.18.1}}
+\newlabel{impl_details:metadata-storage}{{18.1}{75}{Metadata Storage}{section.18.1}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {18.2}Data Storage}{75}{section.18.2}}
+\newlabel{impl_details:data-storage}{{18.2}{75}{Data Storage}{section.18.2}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {18.3}Data De-Duplication}{76}{section.18.3}}
+\newlabel{impl_details:data-de-duplication}{{18.3}{76}{Data De-Duplication}{section.18.3}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {18.4}Caching}{76}{section.18.4}}
+\newlabel{impl_details:caching}{{18.4}{76}{Caching}{section.18.4}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {18.5}Eventual Consistency Handling}{76}{section.18.5}}
+\newlabel{impl_details:eventual-consistency-handling}{{18.5}{76}{Eventual Consistency Handling}{section.18.5}{}}
+\@writefile{toc}{\contentsline {section}{\numberline {18.6}Encryption}{76}{section.18.6}}
+\newlabel{impl_details:encryption}{{18.6}{76}{Encryption}{section.18.6}{}}
diff --git a/doc/latex/manual.idx b/doc/latex/manual.idx
index eacdd97..6ae3180 100644
--- a/doc/latex/manual.idx
+++ b/doc/latex/manual.idx
@@ -12,6 +12,8 @@
\indexentry{sse!s3\_backend command line option|hyperpage}{8}
\indexentry{s3\_backend command line option!ia|hyperpage}{8}
\indexentry{ia!s3\_backend command line option|hyperpage}{8}
+\indexentry{s3\_backend command line option!oia|hyperpage}{8}
+\indexentry{oia!s3\_backend command line option|hyperpage}{8}
\indexentry{s3\_backend command line option!rrs|hyperpage}{8}
\indexentry{rrs!s3\_backend command line option|hyperpage}{8}
\indexentry{swift\_backend command line option!no-ssl|hyperpage}{9}
diff --git a/doc/latex/manual.tex b/doc/latex/manual.tex
index 2bb572f..6ec86e8 100644
--- a/doc/latex/manual.tex
+++ b/doc/latex/manual.tex
@@ -52,8 +52,8 @@
\title{S3QL Documentation}
-\date{Feb 09, 2019}
-\release{3.0}
+\date{Mar 31, 2019}
+\release{3.1}
\author{Nikolaus Rath}
\newcommand{\sphinxlogo}{\vbox{}}
\renewcommand{\releasename}{Release}
@@ -228,7 +228,7 @@ version between 1.0 (inclusive) and 2.0 (exclusive)
version between 3.4 (inclusive) and 4.0 (exclusive)
\item {}
-\sphinxhref{http://pytest.org/}{pytest}, version 2.7 or newer (optional, to run unit tests)
+\sphinxhref{http://pytest.org/}{pytest}, version 3.7 or newer (optional, to run unit tests)
\item {}
\sphinxhref{https://github.com/systemd/python-systemd}{systemd} (optional,
@@ -244,6 +244,10 @@ required for OAuth2 authentication with Google Storage)
\sphinxhref{https://pypi.python.org/project/google-auth/}{google-auth}
(optional, required for ADC authentication with Google Storage)
+\item {}
+\sphinxhref{https://pypi.python.org/project/google-auth-oauthlib/}{google-auth-oauthlib}
+(optional, required for browser-based authentication with Google Storage)
+
\end{itemize}
To check if a specific module \sphinxcode{\sphinxupquote{\textless{}module\textgreater{}}} is installed, execute
@@ -315,7 +319,7 @@ tested with
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{l}{python3 setup.py build\PYGZus{}cython}
\PYG{l}{python3 setup.py build\PYGZus{}ext \PYGZhy{}\PYGZhy{}inplace}
-\PYG{l}{python3 \PYGZhy{}m pytest tests/}
+\PYG{l}{python3 \PYGZhy{}m pytest test}
\end{sphinxVerbatim}
Note that when building from the Mercurial or Git repository, building
@@ -554,7 +558,17 @@ side encryption are probably rather small, and this option does
\begin{fulllineitems}
\phantomsection\label{\detokenize{backends:cmdoption-s3-backend-arg-ia}}\pysigline{\sphinxbfcode{\sphinxupquote{ia}}\sphinxcode{\sphinxupquote{}}}
-Use infrequent access storage class for new objects.
+Use STANDARD\_IA (infrequent access) storage class for new objects.
+See {\color{red}\bfseries{}{}`AWS S3 Storage classes\textless{}https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html\textgreater{}{}`\_}
+
+\end{fulllineitems}
+
+\index{s3\_backend command line option!oia}\index{oia!s3\_backend command line option}
+
+\begin{fulllineitems}
+\phantomsection\label{\detokenize{backends:cmdoption-s3-backend-arg-oia}}\pysigline{\sphinxbfcode{\sphinxupquote{oia}}\sphinxcode{\sphinxupquote{}}}
+Use ONEZONE\_IA (infrequent access) storage class for new objects.
+See {\color{red}\bfseries{}{}`AWS S3 Storage classes\textless{}https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html\textgreater{}{}`\_}
\end{fulllineitems}
@@ -1116,6 +1130,13 @@ This command accepts the following options:
\item [-{-}cachedir \textless{}path\textgreater{}]
Store cached data in this directory (default:
\sphinxcode{\sphinxupquote{\textasciitilde{}/.s3ql)}}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -1382,6 +1403,10 @@ Like \sphinxcode{\sphinxupquote{-{-}allow-other}}, but restrict access to the
mounting user and the root user.
\item [-{-}fg]
Do not daemonize, stay in foreground
+\item [-{-}fs-name FS\_NAME]
+Mount name passed to fuse, the name will be shown in
+the first column of the system mount command output.
+If not specified your storage url is used.
\item [-{-}systemd]
Run as systemd unit. Consider specifying \textendash{}log none as
well to make use of journald.
@@ -1816,6 +1841,13 @@ system.
The \sphinxstyleliteralstrong{\sphinxupquote{umount.s3ql}} command accepts the following options:
\begin{quote}
\begin{optionlist}{3cm}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -1965,6 +1997,13 @@ The \sphinxstyleliteralstrong{\sphinxupquote{s3ql\_verify}} command has the foll
This command accepts the following options:
\begin{quote}
\begin{optionlist}{3cm}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -2796,6 +2835,13 @@ The \sphinxstyleliteralstrong{\sphinxupquote{mkfs.s3ql}} command accepts the fol
\item [-{-}cachedir \textless{}path\textgreater{}]
Store cached data in this directory (default:
\sphinxcode{\sphinxupquote{\textasciitilde{}/.s3ql)}}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -2955,7 +3001,7 @@ Changes the encryption passphrase of the file system.
\item[{upgrade}] \leavevmode
Upgrade the file system to the newest revision.
-\item[{delete}] \leavevmode
+\item[{clear}] \leavevmode
Delete the file system with all the stored data.
\item[{download-metadata}] \leavevmode
@@ -3103,6 +3149,10 @@ Like \sphinxcode{\sphinxupquote{-{-}allow-other}}, but restrict access to the
mounting user and the root user.
\item [-{-}fg]
Do not daemonize, stay in foreground
+\item [-{-}fs-name FS\_NAME]
+Mount name passed to fuse, the name will be shown in
+the first column of the system mount command output.
+If not specified your storage url is used.
\item [-{-}systemd]
Run as systemd unit. Consider specifying \textendash{}log none as
well to make use of journald.
@@ -3240,6 +3290,13 @@ and (if the file system was mounted with \sphinxcode{\sphinxupquote{-{-}allow-ot
The \sphinxstyleliteralstrong{\sphinxupquote{s3qlstat}} command accepts the following options:
\begin{quote}
\begin{optionlist}{3cm}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -3357,6 +3414,13 @@ The \sphinxstyleliteralstrong{\sphinxupquote{s3qlctrl}} command also accepts the
what specific action is being invoked:
\begin{quote}
\begin{optionlist}{3cm}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -3483,6 +3547,13 @@ any backup program.
The \sphinxstyleliteralstrong{\sphinxupquote{s3qlcp}} command accepts the following options:
\begin{quote}
\begin{optionlist}{3cm}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -3558,6 +3629,13 @@ and (if the file system was mounted with \sphinxcode{\sphinxupquote{-{-}allow-ot
The \sphinxstyleliteralstrong{\sphinxupquote{s3qlrm}} command accepts the following options:
\begin{quote}
\begin{optionlist}{3cm}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -3663,6 +3741,13 @@ changed after they have been made immutable.
The \sphinxstyleliteralstrong{\sphinxupquote{s3qllock}} command accepts the following options:
\begin{quote}
\begin{optionlist}{3cm}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -3738,6 +3823,13 @@ terminate before shutting down the system.
The \sphinxstyleliteralstrong{\sphinxupquote{umount.s3ql}} command accepts the following options.
\begin{quote}
\begin{optionlist}{3cm}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -3973,6 +4065,13 @@ backend.
The \sphinxstyleliteralstrong{\sphinxupquote{s3ql\_oauth\_client}} command accepts the following options:
\begin{quote}
\begin{optionlist}{3cm}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -4044,6 +4143,13 @@ the available backends.
The \sphinxstyleliteralstrong{\sphinxupquote{s3ql\_verify}} command accepts the following options.
\begin{quote}
\begin{optionlist}{3cm}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
@@ -4182,6 +4288,13 @@ using \sphinxstyleliteralstrong{\sphinxupquote{pcp}} is more likely to \sphinxst
The \sphinxstyleliteralstrong{\sphinxupquote{pcp}} command accepts the following options:
\begin{quote}
\begin{optionlist}{3cm}
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}quiet]
be really quiet
\item [-{-}debug-modules \textless{}modules\textgreater{}]
@@ -4324,6 +4437,13 @@ The \sphinxstyleliteralstrong{\sphinxupquote{expire\_backups}} command accepts t
\begin{optionlist}{3cm}
\item [-{-}quiet]
be really quiet
+\item [-{-}log \textless{}target\textgreater{}]
+Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for
+standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\sphinxcode{\sphinxupquote{None}}
\item [-{-}debug-modules \textless{}modules\textgreater{}]
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
diff --git a/doc/latex/manual.toc b/doc/latex/manual.toc
index 6b4b40c..2ab1b8b 100644
--- a/doc/latex/manual.toc
+++ b/doc/latex/manual.toc
@@ -84,7 +84,7 @@
\contentsline {subsection}{\numberline {16.1.5}See Also}{52}{subsection.16.1.5}
\contentsline {section}{\numberline {16.2}The \sphinxstyleliteralstrong {\sphinxupquote {s3qladm}} command}{52}{section.16.2}
\contentsline {subsection}{\numberline {16.2.1}Synopsis}{52}{subsection.16.2.1}
-\contentsline {subsection}{\numberline {16.2.2}Description}{52}{subsection.16.2.2}
+\contentsline {subsection}{\numberline {16.2.2}Description}{53}{subsection.16.2.2}
\contentsline {subsection}{\numberline {16.2.3}Options}{53}{subsection.16.2.3}
\contentsline {subsection}{\numberline {16.2.4}Actions}{53}{subsection.16.2.4}
\contentsline {subsection}{\numberline {16.2.5}Exit Codes}{53}{subsection.16.2.5}
@@ -97,77 +97,77 @@
\contentsline {subsection}{\numberline {16.3.5}See Also}{56}{subsection.16.3.5}
\contentsline {section}{\numberline {16.4}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlstat}} command}{56}{section.16.4}
\contentsline {subsection}{\numberline {16.4.1}Synopsis}{56}{subsection.16.4.1}
-\contentsline {subsection}{\numberline {16.4.2}Description}{56}{subsection.16.4.2}
+\contentsline {subsection}{\numberline {16.4.2}Description}{57}{subsection.16.4.2}
\contentsline {subsection}{\numberline {16.4.3}Options}{57}{subsection.16.4.3}
\contentsline {subsection}{\numberline {16.4.4}Exit Codes}{57}{subsection.16.4.4}
\contentsline {subsection}{\numberline {16.4.5}See Also}{57}{subsection.16.4.5}
\contentsline {section}{\numberline {16.5}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlctrl}} command}{57}{section.16.5}
\contentsline {subsection}{\numberline {16.5.1}Synopsis}{57}{subsection.16.5.1}
-\contentsline {subsection}{\numberline {16.5.2}Description}{57}{subsection.16.5.2}
+\contentsline {subsection}{\numberline {16.5.2}Description}{58}{subsection.16.5.2}
\contentsline {subsection}{\numberline {16.5.3}Options}{58}{subsection.16.5.3}
\contentsline {subsection}{\numberline {16.5.4}Exit Codes}{58}{subsection.16.5.4}
-\contentsline {subsection}{\numberline {16.5.5}See Also}{58}{subsection.16.5.5}
-\contentsline {section}{\numberline {16.6}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{58}{section.16.6}
-\contentsline {subsection}{\numberline {16.6.1}Synopsis}{58}{subsection.16.6.1}
+\contentsline {subsection}{\numberline {16.5.5}See Also}{59}{subsection.16.5.5}
+\contentsline {section}{\numberline {16.6}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{59}{section.16.6}
+\contentsline {subsection}{\numberline {16.6.1}Synopsis}{59}{subsection.16.6.1}
\contentsline {subsection}{\numberline {16.6.2}Description}{59}{subsection.16.6.2}
-\contentsline {subsubsection}{Snapshotting vs Hardlinking}{59}{subsubsection*.21}
-\contentsline {subsection}{\numberline {16.6.3}Options}{59}{subsection.16.6.3}
-\contentsline {subsection}{\numberline {16.6.4}Exit Codes}{59}{subsection.16.6.4}
+\contentsline {subsubsection}{Snapshotting vs Hardlinking}{59}{subsubsection*.22}
+\contentsline {subsection}{\numberline {16.6.3}Options}{60}{subsection.16.6.3}
+\contentsline {subsection}{\numberline {16.6.4}Exit Codes}{60}{subsection.16.6.4}
\contentsline {subsection}{\numberline {16.6.5}See Also}{60}{subsection.16.6.5}
\contentsline {section}{\numberline {16.7}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlrm}} command}{60}{section.16.7}
\contentsline {subsection}{\numberline {16.7.1}Synopsis}{60}{subsection.16.7.1}
\contentsline {subsection}{\numberline {16.7.2}Description}{60}{subsection.16.7.2}
-\contentsline {subsection}{\numberline {16.7.3}Options}{60}{subsection.16.7.3}
-\contentsline {subsection}{\numberline {16.7.4}Exit Codes}{60}{subsection.16.7.4}
+\contentsline {subsection}{\numberline {16.7.3}Options}{61}{subsection.16.7.3}
+\contentsline {subsection}{\numberline {16.7.4}Exit Codes}{61}{subsection.16.7.4}
\contentsline {subsection}{\numberline {16.7.5}See Also}{61}{subsection.16.7.5}
\contentsline {section}{\numberline {16.8}The \sphinxstyleliteralstrong {\sphinxupquote {s3qllock}} command}{61}{section.16.8}
\contentsline {subsection}{\numberline {16.8.1}Synopsis}{61}{subsection.16.8.1}
\contentsline {subsection}{\numberline {16.8.2}Description}{61}{subsection.16.8.2}
-\contentsline {subsection}{\numberline {16.8.3}Rationale}{61}{subsection.16.8.3}
-\contentsline {subsection}{\numberline {16.8.4}Options}{61}{subsection.16.8.4}
+\contentsline {subsection}{\numberline {16.8.3}Rationale}{62}{subsection.16.8.3}
+\contentsline {subsection}{\numberline {16.8.4}Options}{62}{subsection.16.8.4}
\contentsline {subsection}{\numberline {16.8.5}Exit Codes}{62}{subsection.16.8.5}
\contentsline {subsection}{\numberline {16.8.6}See Also}{62}{subsection.16.8.6}
-\contentsline {section}{\numberline {16.9}The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{62}{section.16.9}
-\contentsline {subsection}{\numberline {16.9.1}Synopsis}{62}{subsection.16.9.1}
-\contentsline {subsection}{\numberline {16.9.2}Description}{62}{subsection.16.9.2}
-\contentsline {subsection}{\numberline {16.9.3}Options}{62}{subsection.16.9.3}
+\contentsline {section}{\numberline {16.9}The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{63}{section.16.9}
+\contentsline {subsection}{\numberline {16.9.1}Synopsis}{63}{subsection.16.9.1}
+\contentsline {subsection}{\numberline {16.9.2}Description}{63}{subsection.16.9.2}
+\contentsline {subsection}{\numberline {16.9.3}Options}{63}{subsection.16.9.3}
\contentsline {subsection}{\numberline {16.9.4}Exit Codes}{63}{subsection.16.9.4}
-\contentsline {subsection}{\numberline {16.9.5}See Also}{63}{subsection.16.9.5}
-\contentsline {section}{\numberline {16.10}The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{63}{section.16.10}
-\contentsline {subsection}{\numberline {16.10.1}Synopsis}{63}{subsection.16.10.1}
-\contentsline {subsection}{\numberline {16.10.2}Description}{63}{subsection.16.10.2}
-\contentsline {subsection}{\numberline {16.10.3}Options}{63}{subsection.16.10.3}
-\contentsline {subsection}{\numberline {16.10.4}Exit Codes}{64}{subsection.16.10.4}
+\contentsline {subsection}{\numberline {16.9.5}See Also}{64}{subsection.16.9.5}
+\contentsline {section}{\numberline {16.10}The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{64}{section.16.10}
+\contentsline {subsection}{\numberline {16.10.1}Synopsis}{64}{subsection.16.10.1}
+\contentsline {subsection}{\numberline {16.10.2}Description}{64}{subsection.16.10.2}
+\contentsline {subsection}{\numberline {16.10.3}Options}{64}{subsection.16.10.3}
+\contentsline {subsection}{\numberline {16.10.4}Exit Codes}{65}{subsection.16.10.4}
\contentsline {subsection}{\numberline {16.10.5}See Also}{65}{subsection.16.10.5}
-\contentsline {section}{\numberline {16.11}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{65}{section.16.11}
-\contentsline {subsection}{\numberline {16.11.1}Synopsis}{65}{subsection.16.11.1}
-\contentsline {subsection}{\numberline {16.11.2}Description}{65}{subsection.16.11.2}
-\contentsline {subsection}{\numberline {16.11.3}Options}{65}{subsection.16.11.3}
-\contentsline {subsection}{\numberline {16.11.4}Exit Codes}{65}{subsection.16.11.4}
+\contentsline {section}{\numberline {16.11}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{66}{section.16.11}
+\contentsline {subsection}{\numberline {16.11.1}Synopsis}{66}{subsection.16.11.1}
+\contentsline {subsection}{\numberline {16.11.2}Description}{66}{subsection.16.11.2}
+\contentsline {subsection}{\numberline {16.11.3}Options}{66}{subsection.16.11.3}
+\contentsline {subsection}{\numberline {16.11.4}Exit Codes}{66}{subsection.16.11.4}
\contentsline {subsection}{\numberline {16.11.5}See Also}{66}{subsection.16.11.5}
-\contentsline {section}{\numberline {16.12}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{66}{section.16.12}
-\contentsline {subsection}{\numberline {16.12.1}Synopsis}{66}{subsection.16.12.1}
-\contentsline {subsection}{\numberline {16.12.2}Description}{66}{subsection.16.12.2}
-\contentsline {subsection}{\numberline {16.12.3}Options}{66}{subsection.16.12.3}
+\contentsline {section}{\numberline {16.12}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{67}{section.16.12}
+\contentsline {subsection}{\numberline {16.12.1}Synopsis}{67}{subsection.16.12.1}
+\contentsline {subsection}{\numberline {16.12.2}Description}{67}{subsection.16.12.2}
+\contentsline {subsection}{\numberline {16.12.3}Options}{67}{subsection.16.12.3}
\contentsline {subsection}{\numberline {16.12.4}Exit Codes}{67}{subsection.16.12.4}
-\contentsline {subsection}{\numberline {16.12.5}See Also}{67}{subsection.16.12.5}
-\contentsline {section}{\numberline {16.13}The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{67}{section.16.13}
-\contentsline {subsection}{\numberline {16.13.1}Synopsis}{67}{subsection.16.13.1}
-\contentsline {subsection}{\numberline {16.13.2}Description}{67}{subsection.16.13.2}
-\contentsline {subsection}{\numberline {16.13.3}Options}{68}{subsection.16.13.3}
-\contentsline {subsection}{\numberline {16.13.4}Exit Codes}{68}{subsection.16.13.4}
-\contentsline {subsection}{\numberline {16.13.5}See Also}{68}{subsection.16.13.5}
-\contentsline {section}{\numberline {16.14}The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{68}{section.16.14}
-\contentsline {subsection}{\numberline {16.14.1}Synopsis}{68}{subsection.16.14.1}
-\contentsline {subsection}{\numberline {16.14.2}Description}{68}{subsection.16.14.2}
-\contentsline {subsection}{\numberline {16.14.3}Options}{69}{subsection.16.14.3}
-\contentsline {subsection}{\numberline {16.14.4}Exit Codes}{70}{subsection.16.14.4}
-\contentsline {subsection}{\numberline {16.14.5}See Also}{70}{subsection.16.14.5}
-\contentsline {chapter}{\numberline {17}Further Resources / Getting Help}{71}{chapter.17}
-\contentsline {chapter}{\numberline {18}Implementation Details}{73}{chapter.18}
-\contentsline {section}{\numberline {18.1}Metadata Storage}{73}{section.18.1}
-\contentsline {section}{\numberline {18.2}Data Storage}{73}{section.18.2}
-\contentsline {section}{\numberline {18.3}Data De-Duplication}{74}{section.18.3}
-\contentsline {section}{\numberline {18.4}Caching}{74}{section.18.4}
-\contentsline {section}{\numberline {18.5}Eventual Consistency Handling}{74}{section.18.5}
-\contentsline {section}{\numberline {18.6}Encryption}{74}{section.18.6}
+\contentsline {subsection}{\numberline {16.12.5}See Also}{68}{subsection.16.12.5}
+\contentsline {section}{\numberline {16.13}The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{68}{section.16.13}
+\contentsline {subsection}{\numberline {16.13.1}Synopsis}{68}{subsection.16.13.1}
+\contentsline {subsection}{\numberline {16.13.2}Description}{68}{subsection.16.13.2}
+\contentsline {subsection}{\numberline {16.13.3}Options}{69}{subsection.16.13.3}
+\contentsline {subsection}{\numberline {16.13.4}Exit Codes}{69}{subsection.16.13.4}
+\contentsline {subsection}{\numberline {16.13.5}See Also}{69}{subsection.16.13.5}
+\contentsline {section}{\numberline {16.14}The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{69}{section.16.14}
+\contentsline {subsection}{\numberline {16.14.1}Synopsis}{69}{subsection.16.14.1}
+\contentsline {subsection}{\numberline {16.14.2}Description}{69}{subsection.16.14.2}
+\contentsline {subsection}{\numberline {16.14.3}Options}{70}{subsection.16.14.3}
+\contentsline {subsection}{\numberline {16.14.4}Exit Codes}{71}{subsection.16.14.4}
+\contentsline {subsection}{\numberline {16.14.5}See Also}{71}{subsection.16.14.5}
+\contentsline {chapter}{\numberline {17}Further Resources / Getting Help}{73}{chapter.17}
+\contentsline {chapter}{\numberline {18}Implementation Details}{75}{chapter.18}
+\contentsline {section}{\numberline {18.1}Metadata Storage}{75}{section.18.1}
+\contentsline {section}{\numberline {18.2}Data Storage}{75}{section.18.2}
+\contentsline {section}{\numberline {18.3}Data De-Duplication}{76}{section.18.3}
+\contentsline {section}{\numberline {18.4}Caching}{76}{section.18.4}
+\contentsline {section}{\numberline {18.5}Eventual Consistency Handling}{76}{section.18.5}
+\contentsline {section}{\numberline {18.6}Encryption}{76}{section.18.6}
diff --git a/doc/latex/sphinxhighlight.sty b/doc/latex/sphinxhighlight.sty
index 09da86a..2adf06d 100644
--- a/doc/latex/sphinxhighlight.sty
+++ b/doc/latex/sphinxhighlight.sty
@@ -13,73 +13,73 @@
\PYG@it{\PYG@bf{\PYG@ff{#1}}}}}}}
\def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+\PYG@do{#2}}
-\expandafter\def\csname PYG@tok@ss\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.67,0.40,0.00}{##1}}}
-\expandafter\def\csname PYG@tok@ne\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
-\expandafter\def\csname PYG@tok@bp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
-\expandafter\def\csname PYG@tok@c1\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
-\expandafter\def\csname PYG@tok@nv\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.60,0.40,0.20}{##1}}}
-\expandafter\def\csname PYG@tok@cpf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
+\expandafter\def\csname PYG@tok@cs\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.80,0.00,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@c\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
+\expandafter\def\csname PYG@tok@nl\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.60,0.47,0.00}{##1}}}
\expandafter\def\csname PYG@tok@il\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.87}{##1}}}
+\expandafter\def\csname PYG@tok@ow\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}}
\expandafter\def\csname PYG@tok@gs\endcsname{\let\PYG@bf=\textbf}
-\expandafter\def\csname PYG@tok@err\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.67,0.67}{\strut ##1}}}
-\expandafter\def\csname PYG@tok@gp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}
-\expandafter\def\csname PYG@tok@mh\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.33,0.53}{##1}}}
-\expandafter\def\csname PYG@tok@ni\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}}
-\expandafter\def\csname PYG@tok@gd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
-\expandafter\def\csname PYG@tok@s1\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
+\expandafter\def\csname PYG@tok@sx\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.87,0.13,0.00}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
+\expandafter\def\csname PYG@tok@sh\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
+\expandafter\def\csname PYG@tok@gi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
\expandafter\def\csname PYG@tok@no\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.20,0.40}{##1}}}
-\expandafter\def\csname PYG@tok@mo\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.27,0.00,0.93}{##1}}}
-\expandafter\def\csname PYG@tok@se\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
\expandafter\def\csname PYG@tok@ch\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
+\expandafter\def\csname PYG@tok@o\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.20}{##1}}}
+\expandafter\def\csname PYG@tok@ne\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@s\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
\expandafter\def\csname PYG@tok@vc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.40,0.60}{##1}}}
+\expandafter\def\csname PYG@tok@vm\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.60,0.40,0.20}{##1}}}
+\expandafter\def\csname PYG@tok@mb\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}}
+\expandafter\def\csname PYG@tok@ss\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.67,0.40,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@m\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}}
+\expandafter\def\csname PYG@tok@k\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@kd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@kc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@s1\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
\expandafter\def\csname PYG@tok@na\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.80}{##1}}}
-\expandafter\def\csname PYG@tok@sd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.87,0.27,0.13}{##1}}}
-\expandafter\def\csname PYG@tok@nt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.47,0.00}{##1}}}
-\expandafter\def\csname PYG@tok@ge\endcsname{\let\PYG@it=\textit}
-\expandafter\def\csname PYG@tok@cp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.33,0.47,0.60}{##1}}}
-\expandafter\def\csname PYG@tok@cs\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.80,0.00,0.00}{##1}}}
-\expandafter\def\csname PYG@tok@fm\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.40,0.73}{##1}}}
-\expandafter\def\csname PYG@tok@s\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
-\expandafter\def\csname PYG@tok@o\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.20}{##1}}}
-\expandafter\def\csname PYG@tok@gu\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
-\expandafter\def\csname PYG@tok@cm\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
-\expandafter\def\csname PYG@tok@sa\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
+\expandafter\def\csname PYG@tok@ni\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@err\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.67,0.67}{\strut ##1}}}
+\expandafter\def\csname PYG@tok@nv\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.60,0.40,0.20}{##1}}}
+\expandafter\def\csname PYG@tok@mo\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.27,0.00,0.93}{##1}}}
\expandafter\def\csname PYG@tok@sr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,1.00}{\strut ##1}}}
-\expandafter\def\csname PYG@tok@w\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
-\expandafter\def\csname PYG@tok@gr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
-\expandafter\def\csname PYG@tok@s2\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
-\expandafter\def\csname PYG@tok@dl\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
-\expandafter\def\csname PYG@tok@kn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}}
\expandafter\def\csname PYG@tok@gt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}}
-\expandafter\def\csname PYG@tok@mf\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}}
-\expandafter\def\csname PYG@tok@vm\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.60,0.40,0.20}{##1}}}
-\expandafter\def\csname PYG@tok@kd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@sa\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
+\expandafter\def\csname PYG@tok@kn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}}
\expandafter\def\csname PYG@tok@nc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.73,0.00,0.40}{##1}}}
-\expandafter\def\csname PYG@tok@m\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}}
-\expandafter\def\csname PYG@tok@nn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
-\expandafter\def\csname PYG@tok@sx\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.87,0.13,0.00}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
-\expandafter\def\csname PYG@tok@ow\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}}
-\expandafter\def\csname PYG@tok@si\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{0.93,0.93,0.93}{\strut ##1}}}
\expandafter\def\csname PYG@tok@nb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
-\expandafter\def\csname PYG@tok@kc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}}
-\expandafter\def\csname PYG@tok@kp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.20,0.53}{##1}}}
-\expandafter\def\csname PYG@tok@k\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}}
-\expandafter\def\csname PYG@tok@kt\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.60}{##1}}}
-\expandafter\def\csname PYG@tok@nd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}}
+\expandafter\def\csname PYG@tok@kr\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@nn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
+\expandafter\def\csname PYG@tok@w\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
+\expandafter\def\csname PYG@tok@gd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
\expandafter\def\csname PYG@tok@gh\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
-\expandafter\def\csname PYG@tok@nf\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.40,0.73}{##1}}}
\expandafter\def\csname PYG@tok@vi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.73}{##1}}}
-\expandafter\def\csname PYG@tok@gi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
-\expandafter\def\csname PYG@tok@vg\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.87,0.47,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@nt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.47,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@cm\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
+\expandafter\def\csname PYG@tok@mh\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.33,0.53}{##1}}}
+\expandafter\def\csname PYG@tok@gr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@mf\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}}
\expandafter\def\csname PYG@tok@mi\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.87}{##1}}}
-\expandafter\def\csname PYG@tok@nl\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.60,0.47,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@vg\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.87,0.47,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@nd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}}
\expandafter\def\csname PYG@tok@sc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}}
-\expandafter\def\csname PYG@tok@sb\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
-\expandafter\def\csname PYG@tok@mb\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}}
-\expandafter\def\csname PYG@tok@sh\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
-\expandafter\def\csname PYG@tok@c\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
+\expandafter\def\csname PYG@tok@ge\endcsname{\let\PYG@it=\textit}
\expandafter\def\csname PYG@tok@go\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
-\expandafter\def\csname PYG@tok@kr\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}}
+\expandafter\def\csname PYG@tok@nf\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.40,0.73}{##1}}}
+\expandafter\def\csname PYG@tok@gp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}
+\expandafter\def\csname PYG@tok@fm\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.40,0.73}{##1}}}
+\expandafter\def\csname PYG@tok@s2\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
+\expandafter\def\csname PYG@tok@cp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.33,0.47,0.60}{##1}}}
+\expandafter\def\csname PYG@tok@kt\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.60}{##1}}}
+\expandafter\def\csname PYG@tok@cpf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
+\expandafter\def\csname PYG@tok@si\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{0.93,0.93,0.93}{\strut ##1}}}
+\expandafter\def\csname PYG@tok@gu\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
+\expandafter\def\csname PYG@tok@sd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.87,0.27,0.13}{##1}}}
+\expandafter\def\csname PYG@tok@bp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
+\expandafter\def\csname PYG@tok@sb\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
+\expandafter\def\csname PYG@tok@dl\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
+\expandafter\def\csname PYG@tok@kp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.20,0.53}{##1}}}
+\expandafter\def\csname PYG@tok@c1\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
+\expandafter\def\csname PYG@tok@se\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
\def\PYGZbs{\char`\\}
\def\PYGZus{\char`\_}
diff --git a/doc/man/fsck.s3ql.1 b/doc/man/fsck.s3ql.1
index 233f61c..2376072 100644
--- a/doc/man/fsck.s3ql.1
+++ b/doc/man/fsck.s3ql.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "FSCK.S3QL" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "FSCK.S3QL" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
fsck.s3ql \- Check an S3QL file system for errors
.
diff --git a/doc/man/mkfs.s3ql.1 b/doc/man/mkfs.s3ql.1
index 8744b16..4550fda 100644
--- a/doc/man/mkfs.s3ql.1
+++ b/doc/man/mkfs.s3ql.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "MKFS.S3QL" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "MKFS.S3QL" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
mkfs.s3ql \- Create an S3QL file system
.
@@ -67,6 +67,14 @@ The \fBmkfs.s3ql\fP command accepts the following options.
Store cached data in this directory (default:
\fB~/.s3ql)\fP
.TP
+.BI \-\-log \ <target>
+Destination for log messages. Specify \fBnone\fP for
+standard output or \fBsyslog\fP for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\fBNone\fP
+.TP
.BI \-\-debug\-modules \ <modules>
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
diff --git a/doc/man/mount.s3ql.1 b/doc/man/mount.s3ql.1
index 57d69c1..5cb528a 100644
--- a/doc/man/mount.s3ql.1
+++ b/doc/man/mount.s3ql.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "MOUNT.S3QL" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "MOUNT.S3QL" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
mount.s3ql \- Mount an S3QL file system
.
@@ -125,6 +125,11 @@ mounting user and the root user.
.B \-\-fg
Do not daemonize, stay in foreground
.TP
+.BI \-\-fs\-name \ FS_NAME
+Mount name passed to fuse, the name will be shown in
+the first column of the system mount command output.
+If not specified your storage url is used.
+.TP
.B \-\-systemd
Run as systemd unit. Consider specifying \-\-log none as
well to make use of journald.
diff --git a/doc/man/s3ql_oauth_client.1 b/doc/man/s3ql_oauth_client.1
index 970e8f1..87a3a9d 100644
--- a/doc/man/s3ql_oauth_client.1
+++ b/doc/man/s3ql_oauth_client.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "S3QL_OAUTH_CLIENT" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "S3QL_OAUTH_CLIENT" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
s3ql_oauth_client \- Obtain Google Storage OAuth2 tokens
.
@@ -64,6 +64,14 @@ The \fBs3ql_oauth_client\fP command accepts the following options:
.INDENT 3.5
.INDENT 0.0
.TP
+.BI \-\-log \ <target>
+Destination for log messages. Specify \fBnone\fP for
+standard output or \fBsyslog\fP for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\fBNone\fP
+.TP
.BI \-\-debug\-modules \ <modules>
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
diff --git a/doc/man/s3ql_verify.1 b/doc/man/s3ql_verify.1
index 3b4f762..19e1060 100644
--- a/doc/man/s3ql_verify.1
+++ b/doc/man/s3ql_verify.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "S3QL_VERIFY" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "S3QL_VERIFY" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
s3ql_verify \- Verify data in an S3QL file system
.
@@ -62,6 +62,14 @@ The \fBs3ql_verify\fP command accepts the following options.
.INDENT 3.5
.INDENT 0.0
.TP
+.BI \-\-log \ <target>
+Destination for log messages. Specify \fBnone\fP for
+standard output or \fBsyslog\fP for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\fBNone\fP
+.TP
.BI \-\-debug\-modules \ <modules>
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
diff --git a/doc/man/s3qladm.1 b/doc/man/s3qladm.1
index 5e57c66..6f7ed40 100644
--- a/doc/man/s3qladm.1
+++ b/doc/man/s3qladm.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "S3QLADM" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "S3QLADM" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
s3qladm \- Manage S3QL file systems
.
@@ -116,7 +116,7 @@ Changes the encryption passphrase of the file system.
.B upgrade
Upgrade the file system to the newest revision.
.TP
-.B delete
+.B clear
Delete the file system with all the stored data.
.TP
.B download\-metadata
diff --git a/doc/man/s3qlcp.1 b/doc/man/s3qlcp.1
index 4767c14..c32804a 100644
--- a/doc/man/s3qlcp.1
+++ b/doc/man/s3qlcp.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "S3QLCP" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "S3QLCP" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
s3qlcp \- Copy-on-write replication on S3QL file systems
.
@@ -108,6 +108,14 @@ The \fBs3qlcp\fP command accepts the following options:
.INDENT 3.5
.INDENT 0.0
.TP
+.BI \-\-log \ <target>
+Destination for log messages. Specify \fBnone\fP for
+standard output or \fBsyslog\fP for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\fBNone\fP
+.TP
.BI \-\-debug\-modules \ <modules>
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
diff --git a/doc/man/s3qlctrl.1 b/doc/man/s3qlctrl.1
index 315b498..6ab455e 100644
--- a/doc/man/s3qlctrl.1
+++ b/doc/man/s3qlctrl.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "S3QLCTRL" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "S3QLCTRL" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
s3qlctrl \- Control a mounted S3QL file system
.
@@ -116,6 +116,14 @@ what specific action is being invoked:
.INDENT 3.5
.INDENT 0.0
.TP
+.BI \-\-log \ <target>
+Destination for log messages. Specify \fBnone\fP for
+standard output or \fBsyslog\fP for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\fBNone\fP
+.TP
.BI \-\-debug\-modules \ <modules>
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
diff --git a/doc/man/s3qllock.1 b/doc/man/s3qllock.1
index 258449f..f306844 100644
--- a/doc/man/s3qllock.1
+++ b/doc/man/s3qllock.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "S3QLLOCK" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "S3QLLOCK" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
s3qllock \- Make trees on an S3QL file system immutable
.
@@ -94,6 +94,14 @@ The \fBs3qllock\fP command accepts the following options:
.INDENT 3.5
.INDENT 0.0
.TP
+.BI \-\-log \ <target>
+Destination for log messages. Specify \fBnone\fP for
+standard output or \fBsyslog\fP for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\fBNone\fP
+.TP
.BI \-\-debug\-modules \ <modules>
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
diff --git a/doc/man/s3qlrm.1 b/doc/man/s3qlrm.1
index 6425676..1e31469 100644
--- a/doc/man/s3qlrm.1
+++ b/doc/man/s3qlrm.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "S3QLRM" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "S3QLRM" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
s3qlrm \- Fast tree removal on S3QL file systems
.
@@ -66,6 +66,14 @@ The \fBs3qlrm\fP command accepts the following options:
.INDENT 3.5
.INDENT 0.0
.TP
+.BI \-\-log \ <target>
+Destination for log messages. Specify \fBnone\fP for
+standard output or \fBsyslog\fP for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\fBNone\fP
+.TP
.BI \-\-debug\-modules \ <modules>
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
diff --git a/doc/man/s3qlstat.1 b/doc/man/s3qlstat.1
index 94d8368..a2a9080 100644
--- a/doc/man/s3qlstat.1
+++ b/doc/man/s3qlstat.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "S3QLSTAT" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "S3QLSTAT" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
s3qlstat \- Gather S3QL file system statistics
.
@@ -60,6 +60,14 @@ The \fBs3qlstat\fP command accepts the following options:
.INDENT 3.5
.INDENT 0.0
.TP
+.BI \-\-log \ <target>
+Destination for log messages. Specify \fBnone\fP for
+standard output or \fBsyslog\fP for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\fBNone\fP
+.TP
.BI \-\-debug\-modules \ <modules>
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
diff --git a/doc/man/umount.s3ql.1 b/doc/man/umount.s3ql.1
index d0708c8..81daa09 100644
--- a/doc/man/umount.s3ql.1
+++ b/doc/man/umount.s3ql.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "UMOUNT.S3QL" "1" "Feb 09, 2019" "3.0" "S3QL"
+.TH "UMOUNT.S3QL" "1" "Mar 31, 2019" "3.1" "S3QL"
.SH NAME
umount.s3ql \- Unmount an S3QL file system
.
@@ -66,6 +66,14 @@ The \fBumount.s3ql\fP command accepts the following options.
.INDENT 3.5
.INDENT 0.0
.TP
+.BI \-\-log \ <target>
+Destination for log messages. Specify \fBnone\fP for
+standard output or \fBsyslog\fP for the system logging
+daemon. Anything else will be interpreted as a file
+name. Log files will be rotated when they reach 1 MiB,
+and at most 5 old log files will be kept. Default:
+\fBNone\fP
+.TP
.BI \-\-debug\-modules \ <modules>
Activate debugging output from specified modules (use
commas to separate multiple modules). Debug messages
diff --git a/doc/manual.pdf b/doc/manual.pdf
index 9751a83..c17cb48 100644
--- a/doc/manual.pdf
+++ b/doc/manual.pdf
Binary files differ
diff --git a/rst/backends.rst b/rst/backends.rst
index 29b243f..46fd1a7 100644
--- a/rst/backends.rst
+++ b/rst/backends.rst
@@ -153,7 +153,13 @@ The Amazon S3 backend accepts the following backend options:
.. option:: ia
- Use infrequent access storage class for new objects.
+ Use STANDARD_IA (infrequent access) storage class for new objects.
+ See `AWS S3 Storage classes<https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html>`_
+
+.. option:: oia
+
+ Use ONEZONE_IA (infrequent access) storage class for new objects.
+ See `AWS S3 Storage classes<https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html>`_
.. option:: rrs
diff --git a/rst/installation.rst b/rst/installation.rst
index b212440..4c0edbf 100644
--- a/rst/installation.rst
+++ b/rst/installation.rst
@@ -43,7 +43,7 @@ that is not the case.
version between 1.0 (inclusive) and 2.0 (exclusive)
* `dugong <https://pypi.org/project/dugong/>`_, any
version between 3.4 (inclusive) and 4.0 (exclusive)
- * `pytest <http://pytest.org/>`_, version 2.7 or newer (optional, to run unit tests)
+ * `pytest <http://pytest.org/>`_, version 3.7 or newer (optional, to run unit tests)
* `systemd <https://github.com/systemd/python-systemd>`_ (optional,
for enabling systemd support). Do *not* install the module from
PyPi, this is from a third-party developer and incompatible with
@@ -52,6 +52,8 @@ that is not the case.
required for OAuth2 authentication with Google Storage)
* `google-auth <https://pypi.python.org/project/google-auth/>`_
(optional, required for ADC authentication with Google Storage)
+ * `google-auth-oauthlib <https://pypi.python.org/project/google-auth-oauthlib/>`_
+ (optional, required for browser-based authentication with Google Storage)
To check if a specific module :var:`<module>` is installed, execute
:samp:`python3 -c 'import {<module>};
@@ -102,7 +104,7 @@ tested with ::
python3 setup.py build_cython
python3 setup.py build_ext --inplace
- python3 -m pytest tests/
+ python3 -m pytest test
Note that when building from the Mercurial or Git repository, building
and testing is done with several additional checks. This may cause
diff --git a/rst/man/adm.rst b/rst/man/adm.rst
index 4c3af3a..086299f 100644
--- a/rst/man/adm.rst
+++ b/rst/man/adm.rst
@@ -46,7 +46,7 @@ passphrase
upgrade
Upgrade the file system to the newest revision.
-delete
+clear
Delete the file system with all the stored data.
download-metadata
diff --git a/setup.cfg b/setup.cfg
index b0475c1..548cee5 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,9 @@
[easy_install]
allow_hosts = None
+[aliases]
+test = pytest
+
[egg_info]
tag_build =
tag_date = 0
diff --git a/setup.py b/setup.py
index 7d2dc48..ee7a257 100755
--- a/setup.py
+++ b/setup.py
@@ -20,6 +20,7 @@ except ImportError:
raise SystemExit('Setuptools package not found. Please install from '
'https://pypi.python.org/pypi/setuptools')
from setuptools import Extension
+from setuptools.command.test import test as TestCommand
from distutils.version import LooseVersion
import os
@@ -104,6 +105,16 @@ class build_docs(setuptools.Command):
os.path.join(dest_dir, 'manual.pdf'))
+class pytest(TestCommand):
+
+ def run_tests(self):
+ # import here, cause outside the eggs aren't loaded
+ import pytest
+
+ errno = pytest.main(['tests'])
+ sys.exit(errno)
+
+
def main():
with open(os.path.join(basedir, 'README.rst'), 'r') as fh:
@@ -133,7 +144,9 @@ def main():
'requests',
'defusedxml',
'dugong >= 3.4, < 4.0',
- 'llfuse >= 1.0, < 2.0' ]
+ 'llfuse >= 1.0, < 2.0',
+ 'google-auth',
+ 'google-auth-oauthlib']
setuptools.setup(
name='s3ql',
@@ -182,9 +195,11 @@ def main():
]
},
install_requires=required_pkgs,
+ tests_require=['pytest >= 3.7'],
cmdclass={'upload_docs': upload_docs,
'build_cython': build_cython,
- 'build_sphinx': build_docs },
+ 'build_sphinx': build_docs,
+ 'pytest': pytest },
command_options={ 'sdist': { 'formats': ('setup.py', 'bztar') } },
)
diff --git a/src/s3ql.egg-info/PKG-INFO b/src/s3ql.egg-info/PKG-INFO
index 05cde60..fd4c4fd 100644
--- a/src/s3ql.egg-info/PKG-INFO
+++ b/src/s3ql.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: s3ql
-Version: 3.0
+Version: 3.1
Summary: a full-featured file system for online data storage
Home-page: https://bitbucket.org/nikratio/s3ql/
Author: Nikolaus Rath
diff --git a/src/s3ql.egg-info/requires.txt b/src/s3ql.egg-info/requires.txt
index 0337445..a4f4c64 100644
--- a/src/s3ql.egg-info/requires.txt
+++ b/src/s3ql.egg-info/requires.txt
@@ -4,3 +4,5 @@ requests
defusedxml
dugong<4.0,>=3.4
llfuse<2.0,>=1.0
+google-auth
+google-auth-oauthlib
diff --git a/src/s3ql/__init__.py b/src/s3ql/__init__.py
index 369a814..01c230c 100644
--- a/src/s3ql/__init__.py
+++ b/src/s3ql/__init__.py
@@ -38,7 +38,7 @@ assert logging.LOG_ONCE # prevent warnings about unused module
from llfuse import ROOT_INODE
-VERSION = '3.0'
+VERSION = '3.1'
RELEASE = '%s' % VERSION
# TODO: On next revision bump, remove upgrade code from backend/comprenc.py and
diff --git a/src/s3ql/backends/gs.py b/src/s3ql/backends/gs.py
index 2bb43cc..508e81e 100644
--- a/src/s3ql/backends/gs.py
+++ b/src/s3ql/backends/gs.py
@@ -20,7 +20,6 @@ from dugong import (HTTPConnection, is_temp_network_error, BodyFollowing, CaseIn
from base64 import b64encode, b64decode
from itertools import count
from ast import literal_eval
-from argparse import Namespace
import hashlib
import urllib.parse
@@ -88,65 +87,10 @@ class RequestError(Exception):
self.code, self.reason)
-class GAuthHTTPRequestor:
- '''Carries out HTTP requests for google.auth
-
- Implements https://google-auth.readthedocs.io/en/latest/reference/google.auth.transport.html#google.auth.transport.Request
+class AccessTokenExpired(Exception):
+ '''
+ Raised if the access token has expired.
'''
-
- def __init__(self, ssl_context: ssl.SSLContext):
- self.ssl_context = ssl_context
- self.proxy = get_proxy(ssl=False)
- self.ssl_proxy = get_proxy(ssl=True)
- self.conn_pool = dict() # type: Dict[Tuple[str,int], HTTPConnection]
-
- def __call__(self, url: str, method: str = 'GET', body=None,
- headers=None, timeout=None):
-
- # https://github.com/googleapis/google-auth-library-python/issues/318
- if not isinstance(body, bytes):
- body = str(body).encode('ascii')
-
- if timeout is not None:
- raise ValueError('*timeout* argument is not supported')
-
- hit = re.match(r'^(https?)://([^:/]+)(?::(\d+))?(.*)$', url)
- if not hit:
- raise ValueError('Unsupported URL: ' + url)
-
- if hit.group(1) == 'https':
- ssl_context = self.ssl_context
- proxy = self.ssl_proxy
- else:
- ssl_context = None
- proxy = self.proxy
- hostname = hit.group(2)
- if hit.group(3):
- port = int(hit.group(3))
- elif ssl_context:
- port = 443
- else:
- port = 80
-
- path = hit.group(4)
-
- try:
- conn = self.conn_pool[(hostname, port)]
- except KeyError:
- conn = HTTPConnection(hostname, port, proxy=proxy,
- ssl_context=ssl_context)
- self.conn_pool[(hostname, port)] = conn
-
- try:
- conn.send_request(method, path, headers=headers, body=body)
- resp = conn.read_response()
- except (dugong.ConnectionClosed, dugong.InvalidResponse, dugong.UnsupportedResponse,
- dugong.ConnectionTimedOut, dugong.HostnameNotResolvable,
- dugong.DNSUnavailable, ssl.SSLError) as exc:
- raise g_auth.exceptions.TransportError(exc)
-
- return Namespace(status=resp.status, headers=resp.headers,
- data=conn.readall())
class Backend(AbstractBackend, metaclass=ABCDocstMeta):
@@ -176,7 +120,13 @@ class Backend(AbstractBackend, metaclass=ABCDocstMeta):
if g_auth is None:
raise QuietError('ADC authentification requires the google.auth module')
elif self.adc is None:
- requestor = GAuthHTTPRequestor(self.ssl_context)
+ import google.auth.transport.urllib3
+ import urllib3
+
+ # Deliberately ignore proxy and SSL context when attemping
+ # to connect to Compute Engine Metadata server.
+ requestor = google.auth.transport.urllib3.Request(
+ urllib3.PoolManager())
try:
credentials, _ = g_auth.default(
request=requestor,
@@ -258,10 +208,17 @@ class Backend(AbstractBackend, metaclass=ABCDocstMeta):
500 <= exc.code <= 599 or exc.code == 408):
return True
+ elif isinstance(exc, AccessTokenExpired):
+ del self.access_token[self.refresh_token]
+ return True
+
# Not clear at all what is happening here, but in doubt we retry
elif isinstance(exc, ServerResponseError):
return True
+ if g_auth and isinstance(exc, g_auth.exceptions.TransportError):
+ return True
+
return False
def _assert_empty_response(self, resp):
@@ -469,10 +426,8 @@ class Backend(AbstractBackend, metaclass=ABCDocstMeta):
except ConnectionClosed: # No server response available
pass
else:
- if resp.status >= 400: # Got error response
- return resp
- log.warning('Server broke connection during upload, but signaled '
- '%d %s', resp.status, resp.reason)
+ log.warning('Server broke connection during upload, signaled '
+ '%d %s', resp.status, resp.reason)
# Re-raise first ConnectionClosed exception
raise
@@ -482,6 +437,10 @@ class Backend(AbstractBackend, metaclass=ABCDocstMeta):
resp = self.conn.read_response()
if resp.status != 200:
exc = self._parse_error_response(resp)
+ # If we're really unlucky, then the token has expired while we
+ # were uploading data.
+ if exc.message == 'Invalid Credentials':
+ raise AccessTokenExpired()
raise _map_request_error(exc, key) or exc
self._parse_json_response(resp)
@@ -672,6 +631,7 @@ class Backend(AbstractBackend, metaclass=ABCDocstMeta):
return resp
elif resp.status != 401:
raise self._parse_error_response(resp)
+ self.conn.discard()
# If we reach this point, then the access token must have
# expired, so we try to get a new one. We use a lock to prevent
@@ -736,9 +696,9 @@ def _map_request_error(exc: RequestError, key: str):
if exc.code == 404 and key:
return NoSuchObject(key)
elif exc.message == 'Forbidden':
- return AuthorizationError()
- elif exc.message == 'Login Required':
- return AuthenticationError()
+ return AuthorizationError(exc.message)
+ elif exc.message in ('Login Required', 'Invalid Credentials'):
+ return AuthenticationError(exc.message)
return None
diff --git a/src/s3ql/backends/s3.py b/src/s3ql/backends/s3.py
index fcb014a..501fc93 100644
--- a/src/s3ql/backends/s3.py
+++ b/src/s3ql/backends/s3.py
@@ -36,7 +36,7 @@ class Backend(s3c.Backend):
may or may not be available and can be queried for with instance methods.
"""
- known_options = ((s3c.Backend.known_options | { 'sse', 'rrs', 'ia' })
+ known_options = ((s3c.Backend.known_options | {'sse', 'rrs', 'ia', 'oia'})
- {'dumb-copy', 'disable-expect100'})
def __init__(self, options):
@@ -91,7 +91,9 @@ class Backend(s3c.Backend):
headers['x-amz-server-side-encryption'] = 'AES256'
if 'ia' in self.options:
- sc = 'STANDARD_IA'
+ sc = 'STANDARD_IA'
+ elif 'oia' in self.options:
+ sc = 'ONEZONE_IA'
elif 'rrs' in self.options:
sc = 'REDUCED_REDUNDANCY'
else:
diff --git a/src/s3ql/block_cache.py b/src/s3ql/block_cache.py
index 8f12ef6..8652d42 100644
--- a/src/s3ql/block_cache.py
+++ b/src/s3ql/block_cache.py
@@ -149,7 +149,7 @@ class CacheEntry(object):
:pos: current position in file
"""
- __slots__ = [ 'dirty', 'inode', 'blockno', 'last_access',
+ __slots__ = [ 'dirty', 'inode', 'blockno', 'last_write',
'size', 'pos', 'fh', 'removed' ]
def __init__(self, inode, blockno, filename, mode='w+b'):
@@ -161,7 +161,7 @@ class CacheEntry(object):
self.dirty = False
self.inode = inode
self.blockno = blockno
- self.last_access = 0
+ self.last_write = 0
self.pos = self.fh.tell()
self.size = os.fstat(self.fh.fileno()).st_size
@@ -195,6 +195,7 @@ class CacheEntry(object):
self.fh.write(buf)
self.pos += len(buf)
self.size = max(self.pos, self.size)
+ self.last_write = time.time()
def close(self):
self.fh.close()
@@ -785,7 +786,6 @@ class BlockCache(object):
self._lock_entry(inode, blockno, release_global=True)
try:
el = self._get_entry(inode, blockno)
- el.last_access = time.time()
oldsize = el.size
try:
yield el
diff --git a/src/s3ql/cp.py b/src/s3ql/cp.py
index a6e31a4..1eea53a 100644
--- a/src/s3ql/cp.py
+++ b/src/s3ql/cp.py
@@ -32,6 +32,7 @@ def parse_args(args):
additional storage space.
'''))
+ parser.add_log()
parser.add_debug()
parser.add_quiet()
parser.add_version()
diff --git a/src/s3ql/ctrl.py b/src/s3ql/ctrl.py
index 35bd530..9433ccf 100644
--- a/src/s3ql/ctrl.py
+++ b/src/s3ql/ctrl.py
@@ -31,6 +31,7 @@ def parse_args(args):
type=(lambda x: x.rstrip('/')),
help='Mountpoint of the file system')
+ parser.add_log()
parser.add_debug()
parser.add_quiet()
parser.add_version()
diff --git a/src/s3ql/lock.py b/src/s3ql/lock.py
index 645e321..f829c28 100644
--- a/src/s3ql/lock.py
+++ b/src/s3ql/lock.py
@@ -26,6 +26,7 @@ def parse_args(args):
deleted with s3qlrm.
'''))
+ parser.add_log()
parser.add_debug()
parser.add_quiet()
parser.add_version()
diff --git a/src/s3ql/mkfs.py b/src/s3ql/mkfs.py
index cf03c6c..b271fd4 100644
--- a/src/s3ql/mkfs.py
+++ b/src/s3ql/mkfs.py
@@ -31,6 +31,7 @@ def parse_args(args):
description="Initializes an S3QL file system")
parser.add_cachedir()
+ parser.add_log()
parser.add_debug()
parser.add_quiet()
parser.add_backend_options()
diff --git a/src/s3ql/mount.py b/src/s3ql/mount.py
index 0237b4c..b769339 100644
--- a/src/s3ql/mount.py
+++ b/src/s3ql/mount.py
@@ -431,7 +431,11 @@ def mark_metadata_dirty(backend, cachepath, param):
def get_fuse_opts(options):
'''Return fuse options for given command line options'''
- fuse_opts = [ "nonempty", 'fsname=%s' % options.storage_url,
+ fsname=options.fs_name
+ if not fsname:
+ fsname = options.storage_url
+
+ fuse_opts = [ "nonempty", 'fsname=%s' % fsname,
'subtype=s3ql', 'big_writes', 'max_write=131072',
'no_remote_lock' ]
@@ -529,6 +533,10 @@ def parse_args(args):
'user and the root user.')
parser.add_argument("--fg", action="store_true", default=False,
help="Do not daemonize, stay in foreground")
+ parser.add_argument("--fs-name", default=None,
+ help="Mount name passed to fuse, the name will be shown in the first "
+ "column of the system mount command output. If not specified your "
+ "storage url is used.")
parser.add_argument("--systemd", action="store_true", default=False,
help="Run as systemd unit. Consider specifying --log none as well "
"to make use of journald.")
@@ -731,7 +739,7 @@ class CommitThread(Thread):
# ... number=500)/500 * 1e3
# 1.456586996000624
for el in list(self.block_cache.cache.values()):
- if self.stop_event.is_set() or stamp - el.last_access < 10:
+ if self.stop_event.is_set() or stamp - el.last_write < 10:
break
if el.dirty and el not in self.block_cache.in_transit:
self.block_cache.upload_if_dirty(el)
diff --git a/src/s3ql/oauth_client.py b/src/s3ql/oauth_client.py
index 854eb25..cdac8dd 100644
--- a/src/s3ql/oauth_client.py
+++ b/src/s3ql/oauth_client.py
@@ -9,10 +9,10 @@ This work can be distributed under the terms of the GNU GPLv3.
from .logging import logging, setup_logging, QuietError
from .parse_args import ArgumentParser
from .common import OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET
+from google_auth_oauthlib.flow import InstalledAppFlow
import sys
import textwrap
import requests
-import time
log = logging.getLogger(__name__)
@@ -25,6 +25,7 @@ def parse_args(args):
Obtain OAuth2 refresh token for Google Storage
'''))
+ parser.add_log()
parser.add_debug()
parser.add_quiet()
parser.add_version()
@@ -64,40 +65,20 @@ def main(args=None):
options = parse_args(args)
setup_logging(options)
- cli = requests.Session()
-
# We need full control in order to be able to update metadata
# cf. https://stackoverflow.com/questions/24718787
- r = cli.post('https://accounts.google.com/o/oauth2/device/code',
- data={ 'client_id': OAUTH_CLIENT_ID,
- 'scope': 'https://www.googleapis.com/auth/devstorage.full_control' },
- verify=True, allow_redirects=False, timeout=20)
- req_json = _parse_response(r)
-
- print(textwrap.fill('Please open %s in your browser and enter the following '
- 'user code: %s' % (req_json['verification_url'],
- req_json['user_code'])))
-
- while True:
- log.debug('polling..')
- time.sleep(req_json['interval'])
-
- r = cli.post('https://accounts.google.com/o/oauth2/token',
- data={ 'client_id': OAUTH_CLIENT_ID,
- 'client_secret': OAUTH_CLIENT_SECRET,
- 'code': req_json['device_code'],
- 'grant_type': 'http://oauth.net/grant_type/device/1.0' },
- verify=True, allow_redirects=False, timeout=20)
- resp_json = _parse_response(r)
- r.close()
-
- if 'error' in resp_json:
- if resp_json['error'] == 'authorization_pending':
- continue
- else:
- raise QuietError('Authentication failed: ' + resp_json['error'])
- else:
- break
-
- print('Success. Your refresh token is:\n',
- resp_json['refresh_token'])
+ flow = InstalledAppFlow.from_client_config(
+ client_config={
+ "installed": {
+ "client_id": OAUTH_CLIENT_ID,
+ "client_secret": OAUTH_CLIENT_SECRET,
+ "redirect_uris": ["http://localhost", "urn:ietf:wg:oauth:2.0:oob"],
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
+ "token_uri": "https://accounts.google.com/o/oauth2/token"
+ }
+ },
+ scopes=['https://www.googleapis.com/auth/devstorage.full_control'])
+
+ credentials = flow.run_local_server(open_browser=True)
+
+ print('Success. Your refresh token is:\n', credentials.refresh_token)
diff --git a/src/s3ql/remove.py b/src/s3ql/remove.py
index b0f1395..5a23576 100644
--- a/src/s3ql/remove.py
+++ b/src/s3ql/remove.py
@@ -25,6 +25,7 @@ def parse_args(args):
including immutable entries.
'''))
+ parser.add_log()
parser.add_debug()
parser.add_quiet()
parser.add_version()
diff --git a/src/s3ql/statfs.py b/src/s3ql/statfs.py
index 57c3408..d1f4248 100644
--- a/src/s3ql/statfs.py
+++ b/src/s3ql/statfs.py
@@ -21,6 +21,7 @@ def parse_args(args):
parser = ArgumentParser(
description="Print file system statistics.")
+ parser.add_log()
parser.add_debug()
parser.add_quiet()
parser.add_version()
diff --git a/src/s3ql/umount.py b/src/s3ql/umount.py
index 1513116..8a0ad1c 100644
--- a/src/s3ql/umount.py
+++ b/src/s3ql/umount.py
@@ -32,6 +32,7 @@ def parse_args(args):
Unmounts an S3QL file system. The command returns only after all data
has been uploaded to the backend.'''))
+ parser.add_log()
parser.add_debug()
parser.add_quiet()
parser.add_version()
diff --git a/src/s3ql/verify.py b/src/s3ql/verify.py
index b09470c..3ae62a0 100644
--- a/src/s3ql/verify.py
+++ b/src/s3ql/verify.py
@@ -48,6 +48,7 @@ def parse_args(args):
every object. It therefore takes a lot longer.
'''))
+ parser.add_log()
parser.add_debug()
parser.add_quiet()
parser.add_version()
diff --git a/tests/.pytest_cache/v/cache/lastfailed b/tests/.pytest_cache/v/cache/lastfailed
index 61889b5..a2c00e2 100644
--- a/tests/.pytest_cache/v/cache/lastfailed
+++ b/tests/.pytest_cache/v/cache/lastfailed
@@ -1,48 +1,25 @@
{
"t1_backends.py::test_clear[remote-gs/aes]": true,
- "t1_backends.py::test_complex_meta[remote-gs/raw]": true,
"t1_backends.py::test_complex_meta[remote-swiftks/raw]": true,
- "t1_backends.py::test_copy[remote-gs/raw]": true,
"t1_backends.py::test_copy[remote-swiftks/raw]": true,
- "t1_backends.py::test_copy_newmeta[remote-gs/raw]": true,
"t1_backends.py::test_copy_newmeta[remote-swiftks/raw]": true,
- "t1_backends.py::test_copy_special[remote-gs/raw]": true,
"t1_backends.py::test_copy_special[remote-swiftks/raw]": true,
- "t1_backends.py::test_delete[remote-gs/aes]": true,
"t1_backends.py::test_delete[remote-swiftks/aes]": true,
- "t1_backends.py::test_delete_multi[remote-gs/aes]": true,
"t1_backends.py::test_delete_multi[remote-swiftks/aes]": true,
- "t1_backends.py::test_list[remote-gs/aes]": true,
"t1_backends.py::test_list[remote-swiftks/aes]": true,
- "t1_backends.py::test_multi_packet[remote-gs/aes+zlib]": true,
- "t1_backends.py::test_multi_packet[remote-gs/aes]": true,
- "t1_backends.py::test_multi_packet[remote-gs/plain]": true,
- "t1_backends.py::test_multi_packet[remote-gs/raw]": true,
- "t1_backends.py::test_multi_packet[remote-gs/zlib]": true,
"t1_backends.py::test_multi_packet[remote-swiftks/aes+zlib]": true,
"t1_backends.py::test_multi_packet[remote-swiftks/aes]": true,
"t1_backends.py::test_multi_packet[remote-swiftks/plain]": true,
"t1_backends.py::test_multi_packet[remote-swiftks/raw]": true,
"t1_backends.py::test_multi_packet[remote-swiftks/zlib]": true,
"t1_backends.py::test_read_write[mock-gs/aes]": true,
- "t1_backends.py::test_read_write[remote-gs/aes+zlib]": true,
- "t1_backends.py::test_read_write[remote-gs/aes]": true,
- "t1_backends.py::test_read_write[remote-gs/bzip2]": true,
- "t1_backends.py::test_read_write[remote-gs/lzma]": true,
- "t1_backends.py::test_read_write[remote-gs/plain]": true,
- "t1_backends.py::test_read_write[remote-gs/raw]": true,
- "t1_backends.py::test_read_write[remote-gs/zlib]": true,
"t1_backends.py::test_read_write[remote-swiftks/aes+zlib]": true,
"t1_backends.py::test_read_write[remote-swiftks/bzip2]": true,
"t1_backends.py::test_read_write[remote-swiftks/lzma]": true,
"t1_backends.py::test_read_write[remote-swiftks/plain]": true,
"t1_backends.py::test_read_write[remote-swiftks/raw]": true,
"t1_backends.py::test_read_write[remote-swiftks/zlib]": true,
- "t1_backends.py::test_readslowly[remote-gs/raw]": true,
- "t1_backends.py::test_rename[remote-gs/raw]": true,
"t1_backends.py::test_rename[remote-swiftks/raw]": true,
- "t1_backends.py::test_rename_newmeta[remote-gs/raw]": true,
"t1_backends.py::test_rename_newmeta[remote-swiftks/raw]": true,
- "t1_backends.py::test_update_meta[remote-gs/raw]": true,
"t1_backends.py::test_update_meta[remote-swiftks/raw]": true
} \ No newline at end of file
diff --git a/tests/.pytest_cache/v/cache/nodeids b/tests/.pytest_cache/v/cache/nodeids
index 1961ce6..6771a25 100644
--- a/tests/.pytest_cache/v/cache/nodeids
+++ b/tests/.pytest_cache/v/cache/nodeids
@@ -1,42 +1,49 @@
[
"t1_backends.py::test_read_write[local/aes]",
"t1_backends.py::test_read_write[remote-s3/aes]",
+ "t1_backends.py::test_read_write[remote-gs/aes]",
"t1_backends.py::test_read_write[mock-s3c/aes]",
"t1_backends.py::test_read_write[mock-swift/aes0]",
"t1_backends.py::test_read_write[mock-swift/aes1]",
"t1_backends.py::test_read_write[mock-swift/aes2]",
"t1_backends.py::test_read_write[local/aes+zlib]",
"t1_backends.py::test_read_write[remote-s3/aes+zlib]",
+ "t1_backends.py::test_read_write[remote-gs/aes+zlib]",
"t1_backends.py::test_read_write[mock-s3c/aes+zlib]",
"t1_backends.py::test_read_write[mock-swift/aes+zlib0]",
"t1_backends.py::test_read_write[mock-swift/aes+zlib1]",
"t1_backends.py::test_read_write[mock-swift/aes+zlib2]",
"t1_backends.py::test_read_write[local/plain]",
"t1_backends.py::test_read_write[remote-s3/plain]",
+ "t1_backends.py::test_read_write[remote-gs/plain]",
"t1_backends.py::test_read_write[mock-s3c/plain]",
"t1_backends.py::test_read_write[mock-swift/plain0]",
"t1_backends.py::test_read_write[mock-swift/plain1]",
"t1_backends.py::test_read_write[mock-swift/plain2]",
"t1_backends.py::test_read_write[local/zlib]",
"t1_backends.py::test_read_write[remote-s3/zlib]",
+ "t1_backends.py::test_read_write[remote-gs/zlib]",
"t1_backends.py::test_read_write[mock-s3c/zlib]",
"t1_backends.py::test_read_write[mock-swift/zlib0]",
"t1_backends.py::test_read_write[mock-swift/zlib1]",
"t1_backends.py::test_read_write[mock-swift/zlib2]",
"t1_backends.py::test_read_write[local/bzip2]",
"t1_backends.py::test_read_write[remote-s3/bzip2]",
+ "t1_backends.py::test_read_write[remote-gs/bzip2]",
"t1_backends.py::test_read_write[mock-s3c/bzip2]",
"t1_backends.py::test_read_write[mock-swift/bzip20]",
"t1_backends.py::test_read_write[mock-swift/bzip21]",
"t1_backends.py::test_read_write[mock-swift/bzip22]",
"t1_backends.py::test_read_write[local/lzma]",
"t1_backends.py::test_read_write[remote-s3/lzma]",
+ "t1_backends.py::test_read_write[remote-gs/lzma]",
"t1_backends.py::test_read_write[mock-s3c/lzma]",
"t1_backends.py::test_read_write[mock-swift/lzma0]",
"t1_backends.py::test_read_write[mock-swift/lzma1]",
"t1_backends.py::test_read_write[mock-swift/lzma2]",
"t1_backends.py::test_read_write[local/raw]",
"t1_backends.py::test_read_write[remote-s3/raw]",
+ "t1_backends.py::test_read_write[remote-gs/raw]",
"t1_backends.py::test_read_write[mock-s3c/raw]",
"t1_backends.py::test_read_write[mock-swift/raw0]",
"t1_backends.py::test_read_write[mock-swift/raw1]",
@@ -46,6 +53,7 @@
"t1_backends.py::test_issue114[mock-swift/raw2]",
"t1_backends.py::test_complex_meta[local/raw]",
"t1_backends.py::test_complex_meta[remote-s3/raw]",
+ "t1_backends.py::test_complex_meta[remote-gs/raw]",
"t1_backends.py::test_complex_meta[mock-s3c/raw]",
"t1_backends.py::test_complex_meta[mock-swift/raw0]",
"t1_backends.py::test_complex_meta[mock-swift/raw1]",
@@ -55,11 +63,13 @@
"t1_backends.py::test_complex_meta[local/zlib]",
"t1_backends.py::test_list[local/aes]",
"t1_backends.py::test_list[remote-s3/aes]",
+ "t1_backends.py::test_list[remote-gs/aes]",
"t1_backends.py::test_list[mock-s3c/aes]",
"t1_backends.py::test_list[mock-swift/aes0]",
"t1_backends.py::test_list[mock-swift/aes1]",
"t1_backends.py::test_list[mock-swift/aes2]",
"t1_backends.py::test_readslowly[local/raw]",
+ "t1_backends.py::test_readslowly[remote-gs/raw]",
"t1_backends.py::test_readslowly[mock-s3c/raw]",
"t1_backends.py::test_readslowly[mock-swift/raw0]",
"t1_backends.py::test_readslowly[mock-swift/raw1]",
@@ -70,18 +80,21 @@
"t1_backends.py::test_readslowly[local/aes+zlib]",
"t1_backends.py::test_delete[local/aes]",
"t1_backends.py::test_delete[remote-s3/aes]",
+ "t1_backends.py::test_delete[remote-gs/aes]",
"t1_backends.py::test_delete[mock-s3c/aes]",
"t1_backends.py::test_delete[mock-swift/aes0]",
"t1_backends.py::test_delete[mock-swift/aes1]",
"t1_backends.py::test_delete[mock-swift/aes2]",
"t1_backends.py::test_delete_multi[local/aes]",
"t1_backends.py::test_delete_multi[remote-s3/aes]",
+ "t1_backends.py::test_delete_multi[remote-gs/aes]",
"t1_backends.py::test_delete_multi[mock-s3c/aes]",
"t1_backends.py::test_delete_multi[mock-swift/aes0]",
"t1_backends.py::test_delete_multi[mock-swift/aes1]",
"t1_backends.py::test_delete_multi[mock-swift/aes2]",
"t1_backends.py::test_copy[local/raw]",
"t1_backends.py::test_copy[remote-s3/raw]",
+ "t1_backends.py::test_copy[remote-gs/raw]",
"t1_backends.py::test_copy[mock-s3c/raw]",
"t1_backends.py::test_copy[mock-swift/raw0]",
"t1_backends.py::test_copy[mock-swift/raw1]",
@@ -91,12 +104,14 @@
"t1_backends.py::test_copy[local/zlib]",
"t1_backends.py::test_copy_special[local/raw]",
"t1_backends.py::test_copy_special[remote-s3/raw]",
+ "t1_backends.py::test_copy_special[remote-gs/raw]",
"t1_backends.py::test_copy_special[mock-s3c/raw]",
"t1_backends.py::test_copy_special[mock-swift/raw0]",
"t1_backends.py::test_copy_special[mock-swift/raw1]",
"t1_backends.py::test_copy_special[mock-swift/raw2]",
"t1_backends.py::test_copy_newmeta[local/raw]",
"t1_backends.py::test_copy_newmeta[remote-s3/raw]",
+ "t1_backends.py::test_copy_newmeta[remote-gs/raw]",
"t1_backends.py::test_copy_newmeta[mock-s3c/raw]",
"t1_backends.py::test_copy_newmeta[mock-swift/raw0]",
"t1_backends.py::test_copy_newmeta[mock-swift/raw1]",
@@ -105,6 +120,7 @@
"t1_backends.py::test_copy_newmeta[local/zlib]",
"t1_backends.py::test_rename[local/raw]",
"t1_backends.py::test_rename[remote-s3/raw]",
+ "t1_backends.py::test_rename[remote-gs/raw]",
"t1_backends.py::test_rename[mock-s3c/raw]",
"t1_backends.py::test_rename[mock-swift/raw0]",
"t1_backends.py::test_rename[mock-swift/raw1]",
@@ -113,6 +129,7 @@
"t1_backends.py::test_rename[local/zlib]",
"t1_backends.py::test_rename_newmeta[local/raw]",
"t1_backends.py::test_rename_newmeta[remote-s3/raw]",
+ "t1_backends.py::test_rename_newmeta[remote-gs/raw]",
"t1_backends.py::test_rename_newmeta[mock-s3c/raw]",
"t1_backends.py::test_rename_newmeta[mock-swift/raw0]",
"t1_backends.py::test_rename_newmeta[mock-swift/raw1]",
@@ -121,6 +138,7 @@
"t1_backends.py::test_rename_newmeta[local/zlib]",
"t1_backends.py::test_update_meta[local/raw]",
"t1_backends.py::test_update_meta[remote-s3/raw]",
+ "t1_backends.py::test_update_meta[remote-gs/raw]",
"t1_backends.py::test_update_meta[mock-s3c/raw]",
"t1_backends.py::test_update_meta[mock-swift/raw0]",
"t1_backends.py::test_update_meta[mock-swift/raw1]",
@@ -142,30 +160,35 @@
"t1_backends.py::test_extra_data[local/lzma]",
"t1_backends.py::test_multi_packet[local/raw]",
"t1_backends.py::test_multi_packet[remote-s3/raw]",
+ "t1_backends.py::test_multi_packet[remote-gs/raw]",
"t1_backends.py::test_multi_packet[mock-s3c/raw]",
"t1_backends.py::test_multi_packet[mock-swift/raw0]",
"t1_backends.py::test_multi_packet[mock-swift/raw1]",
"t1_backends.py::test_multi_packet[mock-swift/raw2]",
"t1_backends.py::test_multi_packet[local/plain]",
"t1_backends.py::test_multi_packet[remote-s3/plain]",
+ "t1_backends.py::test_multi_packet[remote-gs/plain]",
"t1_backends.py::test_multi_packet[mock-s3c/plain]",
"t1_backends.py::test_multi_packet[mock-swift/plain0]",
"t1_backends.py::test_multi_packet[mock-swift/plain1]",
"t1_backends.py::test_multi_packet[mock-swift/plain2]",
"t1_backends.py::test_multi_packet[local/aes]",
"t1_backends.py::test_multi_packet[remote-s3/aes]",
+ "t1_backends.py::test_multi_packet[remote-gs/aes]",
"t1_backends.py::test_multi_packet[mock-s3c/aes]",
"t1_backends.py::test_multi_packet[mock-swift/aes0]",
"t1_backends.py::test_multi_packet[mock-swift/aes1]",
"t1_backends.py::test_multi_packet[mock-swift/aes2]",
"t1_backends.py::test_multi_packet[local/aes+zlib]",
"t1_backends.py::test_multi_packet[remote-s3/aes+zlib]",
+ "t1_backends.py::test_multi_packet[remote-gs/aes+zlib]",
"t1_backends.py::test_multi_packet[mock-s3c/aes+zlib]",
"t1_backends.py::test_multi_packet[mock-swift/aes+zlib0]",
"t1_backends.py::test_multi_packet[mock-swift/aes+zlib1]",
"t1_backends.py::test_multi_packet[mock-swift/aes+zlib2]",
"t1_backends.py::test_multi_packet[local/zlib]",
"t1_backends.py::test_multi_packet[remote-s3/zlib]",
+ "t1_backends.py::test_multi_packet[remote-gs/zlib]",
"t1_backends.py::test_multi_packet[mock-s3c/zlib]",
"t1_backends.py::test_multi_packet[mock-swift/zlib0]",
"t1_backends.py::test_multi_packet[mock-swift/zlib1]",
@@ -320,51 +343,51 @@
"t4_authinfo.py::test_invalid_backend_option",
"t4_authinfo.py::test_option_precedence",
"t4_authinfo.py::test_passphrase",
- "t4_fuse.py::TestFuse::()::test",
- "t5_cache.py::TestPerstCache::()::test",
- "t5_cache.py::TestPerstCache::()::test_cache_upload",
- "t5_cache.py::TestPerstCache::()::test_cache_flush[True]",
- "t5_cache.py::TestPerstCache::()::test_cache_flush[False]",
- "t5_cache.py::TestPerstCache::()::test_cache_flush_unclean",
- "t5_cp.py::TestCp::()::test",
- "t5_ctrl.py::TestCtrl::()::test",
- "t5_failsafe.py::TestFailsafe::()::test",
- "t5_failsafe.py::TestNewerMetadata::()::test",
- "t5_fsck.py::TestFsck::()::test",
- "t5_full.py::TestFullgs::()::test",
- "t5_full.py::TestFullswiftks::()::test",
- "t5_full.py::TestFulls3c::()::test",
- "t5_full.py::TestFullrackspace::()::test",
- "t5_full.py::TestFulls3::()::test",
- "t5_full.py::TestFullswift::()::test",
- "t5_full.py::TestFull::()::test",
- "t5_lock_rm.py::TestLockRemove::()::test",
- "t6_upgrade.py::Tests3cUpgrade::()::test[True]",
- "t6_upgrade.py::Tests3cUpgrade::()::test[False]",
- "t6_upgrade.py::TestPlainswiftksUpgrade::()::test[True]",
- "t6_upgrade.py::TestPlainswiftksUpgrade::()::test[False]",
- "t6_upgrade.py::TestswiftUpgrade::()::test[True]",
- "t6_upgrade.py::TestswiftUpgrade::()::test[False]",
- "t6_upgrade.py::Tests3Upgrade::()::test[True]",
- "t6_upgrade.py::Tests3Upgrade::()::test[False]",
- "t6_upgrade.py::TestPlainswiftUpgrade::()::test[True]",
- "t6_upgrade.py::TestPlainswiftUpgrade::()::test[False]",
- "t6_upgrade.py::TestPlainrackspaceUpgrade::()::test[True]",
- "t6_upgrade.py::TestPlainrackspaceUpgrade::()::test[False]",
- "t6_upgrade.py::TestrackspaceUpgrade::()::test[True]",
- "t6_upgrade.py::TestrackspaceUpgrade::()::test[False]",
- "t6_upgrade.py::TestgsUpgrade::()::test[True]",
- "t6_upgrade.py::TestgsUpgrade::()::test[False]",
- "t6_upgrade.py::TestPlaingsUpgrade::()::test[True]",
- "t6_upgrade.py::TestPlaingsUpgrade::()::test[False]",
- "t6_upgrade.py::TestPlains3Upgrade::()::test[True]",
- "t6_upgrade.py::TestPlains3Upgrade::()::test[False]",
- "t6_upgrade.py::TestPlains3cUpgrade::()::test[True]",
- "t6_upgrade.py::TestPlains3cUpgrade::()::test[False]",
- "t6_upgrade.py::TestswiftksUpgrade::()::test[True]",
- "t6_upgrade.py::TestswiftksUpgrade::()::test[False]",
- "t6_upgrade.py::TestUpgrade::()::test[True]",
- "t6_upgrade.py::TestUpgrade::()::test[False]",
- "t6_upgrade.py::TestPlainUpgrade::()::test[True]",
- "t6_upgrade.py::TestPlainUpgrade::()::test[False]"
+ "t4_fuse.py::TestFuse::test",
+ "t5_cache.py::TestPerstCache::test",
+ "t5_cache.py::TestPerstCache::test_cache_upload",
+ "t5_cache.py::TestPerstCache::test_cache_flush[True]",
+ "t5_cache.py::TestPerstCache::test_cache_flush[False]",
+ "t5_cache.py::TestPerstCache::test_cache_flush_unclean",
+ "t5_cp.py::TestCp::test",
+ "t5_ctrl.py::TestCtrl::test",
+ "t5_failsafe.py::TestFailsafe::test",
+ "t5_failsafe.py::TestNewerMetadata::test",
+ "t5_fsck.py::TestFsck::test",
+ "t5_full.py::TestFullgs::test",
+ "t5_full.py::TestFullrackspace::test",
+ "t5_full.py::TestFullswiftks::test",
+ "t5_full.py::TestFulls3::test",
+ "t5_full.py::TestFullswift::test",
+ "t5_full.py::TestFulls3c::test",
+ "t5_full.py::TestFull::test",
+ "t5_lock_rm.py::TestLockRemove::test",
+ "t6_upgrade.py::TestswiftUpgrade::test[True]",
+ "t6_upgrade.py::TestswiftUpgrade::test[False]",
+ "t6_upgrade.py::TestgsUpgrade::test[True]",
+ "t6_upgrade.py::TestgsUpgrade::test[False]",
+ "t6_upgrade.py::TestPlaingsUpgrade::test[True]",
+ "t6_upgrade.py::TestPlaingsUpgrade::test[False]",
+ "t6_upgrade.py::Tests3Upgrade::test[True]",
+ "t6_upgrade.py::Tests3Upgrade::test[False]",
+ "t6_upgrade.py::TestrackspaceUpgrade::test[True]",
+ "t6_upgrade.py::TestrackspaceUpgrade::test[False]",
+ "t6_upgrade.py::TestPlainswiftksUpgrade::test[True]",
+ "t6_upgrade.py::TestPlainswiftksUpgrade::test[False]",
+ "t6_upgrade.py::TestPlains3cUpgrade::test[True]",
+ "t6_upgrade.py::TestPlains3cUpgrade::test[False]",
+ "t6_upgrade.py::TestPlainswiftUpgrade::test[True]",
+ "t6_upgrade.py::TestPlainswiftUpgrade::test[False]",
+ "t6_upgrade.py::TestswiftksUpgrade::test[True]",
+ "t6_upgrade.py::TestswiftksUpgrade::test[False]",
+ "t6_upgrade.py::TestPlains3Upgrade::test[True]",
+ "t6_upgrade.py::TestPlains3Upgrade::test[False]",
+ "t6_upgrade.py::TestPlainrackspaceUpgrade::test[True]",
+ "t6_upgrade.py::TestPlainrackspaceUpgrade::test[False]",
+ "t6_upgrade.py::Tests3cUpgrade::test[True]",
+ "t6_upgrade.py::Tests3cUpgrade::test[False]",
+ "t6_upgrade.py::TestUpgrade::test[True]",
+ "t6_upgrade.py::TestUpgrade::test[False]",
+ "t6_upgrade.py::TestPlainUpgrade::test[True]",
+ "t6_upgrade.py::TestPlainUpgrade::test[False]"
] \ No newline at end of file