Commit Graph

22 Commits

Author SHA1 Message Date
Christian Brauner
4b59093844 btrfs-progs: fix btrfs send & receive with -e flag
The old check here tried to ensure that empty streams are not considered valid.
The old check however, will always fail when only one run through the while(1)
loop is needed and honor_end_cmd is set. So this:

btrfs send /some/subvol | btrfs receive -e /some/

will consistently fail because -e causes honor_cmd_to be set and
btrfs_read_and_process_send_stream() to correctly return 1. So the command will
be successful but btrfs receive will error out because the send - receive
concluded in one run through the while(1) loop.

If we want to exclude empty streams we need a way to tell the difference between
btrfs_read_and_process_send_stream() returning 1 because read_buf() did not
detect any data and read_and_process_cmd() returning 1 because honor_end_cmd was
set. Without introducing too many changes the best way to me seems to have
btrfs_read_and_process_send_stream() return -ENODATA in the first case. The rest
stays the same. We can then check for -ENODATA in do_receive() and report a
proper error in this case. This should also be backwards compatible to previous
versions of btrfs receive. They will fail on empty streams because a negative
value is returned. The only thing that they will lack is a nice error message.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2017-04-07 18:51:19 +02:00
David Sterba
71f220034d btrfs-progs: receive: properly detect end of stream conditions
Read buffer helper mistakenly reported end of data as an error. Next, we
have to check if the first stream exists as an empty file is not a valid
stream.

Reported-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-30 12:42:22 +01:00
David Sterba
bb2c0e23d8 btrfs-progs: send-stream: track the read position in the stream
Can be later used for more precise error reporting.

Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:50:35 +01:00
David Sterba
fefbab7520 btrfs-progs: send-stream: check number of read bytes from stream
The read_buf does not verify that we've read the expected number of
bytes.  A corrupted of malformated stream will not be detdcted.

Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:50:20 +01:00
David Sterba
028476f19c btrfs-progs: send-stream: document return values of some functions
Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:50:16 +01:00
David Sterba
bcf81d9457 btrfs-progs: send-stream: use proper type for cmd in read_cmd
We just read and assign the value, there's no reason to use different
types.

Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:50:13 +01:00
David Sterba
f9834e87d4 btrfs-progs: send-stream: don't use single letter variable in tlv_get
Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:50:10 +01:00
David Sterba
4c06613842 btrfs-progs: send-stream: use proper types for tlv header values
Switch types to unsigned and adjust the checks.

Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:50:08 +01:00
David Sterba
d13168cebf btrfs-progs: send-stream: use proper type for read return value
Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:50:05 +01:00
David Sterba
2513dfed8f btrfs-progs: send-stream: change length type to unsigned
The command length is unsigned, use the right type, also to make the
length checks work.

Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:50:01 +01:00
David Sterba
23ac27781e btrfs-progs: send-stream: check command length before reading from stream
The command + header length could not fit to the intermediate buffer.

Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:49:57 +01:00
David Sterba
d63854d1b6 btrfs-progs: send-stream: pass char buffer to read_buf
Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:49:51 +01:00
David Sterba
194666a672 btrfs-progs: send-stream: fix size types passed to read_buf
Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:49:49 +01:00
David Sterba
7b794974ba btrfs-progs: send-stream: rename single letter variable
Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:49:46 +01:00
David Sterba
eb4cfd8921 btrfs-progs: send-stream: switch to common message helpers
Signed-off-by: David Sterba <dsterba@suse.com>
2016-11-23 10:49:41 +01:00
Christian Hesse
5676e94ad8 btrfs-progs: fix compiler warning
gcc 4.9.0 gives warnings about possibly uninitialized values when
compiling with function inlining and optimization level two enabled
(CFLAGS="-finline-functions -O2").

Initializing the values fixes the warning. Hope this is correct.

Signed-off-by: Christian Hesse <mail@eworm.de>
Signed-off-by: David Sterba <dsterba@suse.cz>
2014-11-07 18:14:38 +01:00
Zach Brown
dace60fc82 btrfs-progs: fix unaligned loads in receive
A user reported corruption after receiving subvolumes.  Turning up the
logging during the receive showed that the commands and string
attributes were being received correctly but the u64 attrbutes were
sometimes corrupted by having variable number of low order bytes
introduced.

It turned out they were on a platform that corrupts unaligned userspace
loads.  Loading the u64s from the unaligned pointers into the received
command stream with get_unaligned() fixed the problem.

Reported-By: Klaus Holler <kho@gmx.at>
Tested-By: Klaus Holler <kho@gmx.at>
Signed-off-by: Zach Brown <zab@zabbo.net>
Signed-off-by: David Sterba <dsterba@suse.cz>
2014-08-22 16:09:55 +02:00
Filipe David Borba Manana
909131939f Btrfs-progs: receive, allow to continue after errors happen
Due to either bugs in send (kernel) that generate a command against
a wrong path for example, or transient errors on the receiving side,
we stopped processing the send stream immediately and exited with
an error.

It's often desirable to continue processing the send stream even if an
error happens while processing a single command from the send stream.

This change just adds a --max-errors <N> parameter, whose default value
is 1 (preserving current behaviour), that allows to tolerate N errors
before stopping. A value of 0 means to never stop no matter how many
errors we get into while processing the send stream. Regardless of its
value, errors are always printed to stderr when they happen, just like
before this change.

Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
2014-08-22 14:39:32 +02:00
Stefan Behrens
e6e1209254 Btrfs-progs: remove some unused code
Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
2013-04-23 18:56:25 +02:00
Stefan Behrens
46de1a6ec3 Btrfs-progs: btrfs-receive optionally honors the end-cmd
A new option is added to btrfs-receive to change the behavior when
an <end cmd> is received in the Btrfs send stream.

The traditional behavior (which still is the default) is to continue
to read the stream until an EOF condition is encountered. If an
<end cmd> is received, afterwards either an EOF or a new
<stream header> is expected.

The new behavior (if the -e option is set on the command line) is
to terminate after an <end cmd> is read without the need for an EOF.
This allows the stream (e.g. a single TCP stream) to carry additional
data or even multiple Btrfs send streams.

Old btrfs-send tools used to encode multiple snapshots like this
(with 2 snapshots in this example):
<stream header> + <sequence of commands> + <end cmd> +
<stream header> + <sequence of commands> + <end cmd> + EOF

If the new -e option is set, the expected format is like this:
<stream header> + <sequence of commands> +
                  <sequence of commands> + <end cmd>

The btrfs-send tool is changed in a seperate commit to always use
the new format, i.e. to send an <end cmd> only at the end.

Note that the currently existing receivers treat <end cmd> only as
an indication that a new <stream header> is following. This means,
you can just skip the sequence <end cmd> <stream header> without
loosing compatibility. As long as an EOF is following, the currently
existing receivers handle the new format (if the two new flags are
used) exactly as the old one.

The goal of changing the semantic of <end cmd> is to be able to use
a single stream (one TCP connection) to multiplex a request/response
handshake plus Btrfs send streams, all in the same stream. In this
case you cannot evaluate an EOF condition as an end of the Btrfs send
stream. You need something else, and the <end cmd> is just perfect
for this purpose.

Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
2013-04-23 18:56:24 +02:00
Mark Fasheh
fac5b559a7 btrfs-progs: Add support for BTRFS_SEND_FLAG_NO_FILE_DATA
The flag and command are synced from kernel to user. Also, this patch adds a
callback for the BTRFS_SEND_C_UPDATE_EXTENT in struct btrfs_send_ops.
read_and_process_cmd() is updated to decode BTRFS_SEND_C_UPDATE_EXTENT and
send the values through the right callback. I did not add a callback
definition to cmds-receive.c as that code never uses
BTRFS_SEND_FLAG_NO_FILE_DATA.

Signed-off-by: Mark Fasheh <mfasheh@suse.de>
2013-02-12 23:46:15 +01:00
Alexander Block
f1c24cd80d Btrfs-progs: add btrfs send/receive commands
Add user space commands for btrfs send/receive.

Signed-off-by: Alexander Block <ablock84@googlemail.com>
Reviewed-by: David Sterba <dave@jikos.cz>
Reviewed-by: Arne Jansen <sensille@gmx.net>
Reviewed-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Reviewed-by: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
2012-07-26 14:51:27 -04:00