size_t length;
bool doRead;
bool sparse;
+ bool isBlock;
int fdin;
char *fdinname;
int fdout;
static ssize_t
virFDStreamThreadDoRead(virFDStreamDataPtr fdst,
bool sparse,
+ bool isBlock,
const int fdin,
const int fdout,
const char *fdinname,
ssize_t got;
if (sparse && *dataLen == 0) {
- if (virFileInData(fdin, &inData, §ionLen) < 0)
- return -1;
+ if (isBlock) {
+ /* Block devices are always in data section by definition. The
+ * @sectionLen is slightly more tricky. While we could try and get
+ * how much bytes is there left until EOF, we can pretend there is
+ * always X bytes left and let the saferead() below hit EOF (which
+ * is then handled gracefully anyway). Worst case scenario, this
+ * branch is called more than once.
+ * X was chosen to be 1MiB but it has ho special meaning. */
+ inData = 1;
+ sectionLen = 1 * 1024 * 1024;
+ } else {
+ if (virFileInData(fdin, &inData, §ionLen) < 0)
+ return -1;
+ }
if (length &&
sectionLen > length - total)
virStreamPtr st = data->st;
size_t length = data->length;
bool sparse = data->sparse;
+ bool isBlock = data->isBlock;
VIR_AUTOCLOSE fdin = data->fdin;
char *fdinname = data->fdinname;
VIR_AUTOCLOSE fdout = data->fdout;
}
if (doRead)
- got = virFDStreamThreadDoRead(fdst, sparse,
+ got = virFDStreamThreadDoRead(fdst, sparse, isBlock,
fdin, fdout,
fdinname, fdoutname,
length, total,
threadData->st = virObjectRef(st);
threadData->length = length;
threadData->sparse = sparse;
+ threadData->isBlock = !!S_ISBLK(sb.st_mode);
if ((oflags & O_ACCMODE) == O_RDONLY) {
threadData->fdin = fd;