1
0
mirror of https://github.com/facebook/zstd.git synced 2025-03-07 09:26:03 +02:00

Merge pull request #2613 from felixhandte/allow-block-device

Allow Reading from Block Devices with `--force`
This commit is contained in:
Felix Handte 2021-05-05 13:06:32 -04:00 committed by GitHub
commit 2d10544b84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 53 additions and 10 deletions

View File

@ -30,6 +30,9 @@ jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env:
DEVNULLRIGHTS: 1
READFROMBLOCKDEVICE: 1
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: make test - name: make test

View File

@ -324,6 +324,7 @@ struct FIO_prefs_s {
int excludeCompressedFiles; int excludeCompressedFiles;
int patchFromMode; int patchFromMode;
int contentSize; int contentSize;
int allowBlockDevices;
}; };
/*-************************************* /*-*************************************
@ -384,6 +385,7 @@ FIO_prefs_t* FIO_createPreferences(void)
ret->testMode = 0; ret->testMode = 0;
ret->literalCompressionMode = ZSTD_lcm_auto; ret->literalCompressionMode = ZSTD_lcm_auto;
ret->excludeCompressedFiles = 0; ret->excludeCompressedFiles = 0;
ret->allowBlockDevices = 0;
return ret; return ret;
} }
@ -451,6 +453,8 @@ void FIO_setNbWorkers(FIO_prefs_t* const prefs, int nbWorkers) {
void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompressedFiles) { prefs->excludeCompressedFiles = excludeCompressedFiles; } void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompressedFiles) { prefs->excludeCompressedFiles = excludeCompressedFiles; }
void FIO_setAllowBlockDevices(FIO_prefs_t* const prefs, int allowBlockDevices) { prefs->allowBlockDevices = allowBlockDevices; }
void FIO_setBlockSize(FIO_prefs_t* const prefs, int blockSize) { void FIO_setBlockSize(FIO_prefs_t* const prefs, int blockSize) {
if (blockSize && prefs->nbWorkers==0) if (blockSize && prefs->nbWorkers==0)
DISPLAYLEVEL(2, "Setting block size is useless in single-thread mode \n"); DISPLAYLEVEL(2, "Setting block size is useless in single-thread mode \n");
@ -593,11 +597,12 @@ static int FIO_removeFile(const char* path)
} }
/** FIO_openSrcFile() : /** FIO_openSrcFile() :
* condition : `srcFileName` must be non-NULL. * condition : `srcFileName` must be non-NULL. `prefs` may be NULL.
* @result : FILE* to `srcFileName`, or NULL if it fails */ * @result : FILE* to `srcFileName`, or NULL if it fails */
static FILE* FIO_openSrcFile(const char* srcFileName) static FILE* FIO_openSrcFile(const FIO_prefs_t* const prefs, const char* srcFileName)
{ {
stat_t statbuf; stat_t statbuf;
int allowBlockDevices = prefs != NULL ? prefs->allowBlockDevices : 0;
assert(srcFileName != NULL); assert(srcFileName != NULL);
if (!strcmp (srcFileName, stdinmark)) { if (!strcmp (srcFileName, stdinmark)) {
DISPLAYLEVEL(4,"Using stdin for input \n"); DISPLAYLEVEL(4,"Using stdin for input \n");
@ -613,6 +618,7 @@ static FILE* FIO_openSrcFile(const char* srcFileName)
if (!UTIL_isRegularFileStat(&statbuf) if (!UTIL_isRegularFileStat(&statbuf)
&& !UTIL_isFIFOStat(&statbuf) && !UTIL_isFIFOStat(&statbuf)
&& !(allowBlockDevices && UTIL_isBlockDevStat(&statbuf))
) { ) {
DISPLAYLEVEL(1, "zstd: %s is not a regular file -- ignored \n", DISPLAYLEVEL(1, "zstd: %s is not a regular file -- ignored \n",
srcFileName); srcFileName);
@ -1708,7 +1714,7 @@ FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx,
return 0; return 0;
} }
ress.srcFile = FIO_openSrcFile(srcFileName); ress.srcFile = FIO_openSrcFile(prefs, srcFileName);
if (ress.srcFile == NULL) return 1; /* srcFile could not be opened */ if (ress.srcFile == NULL) return 1; /* srcFile could not be opened */
result = FIO_compressFilename_dstFile(fCtx, prefs, ress, dstFileName, srcFileName, compressionLevel); result = FIO_compressFilename_dstFile(fCtx, prefs, ress, dstFileName, srcFileName, compressionLevel);
@ -2571,7 +2577,7 @@ static int FIO_decompressSrcFile(FIO_ctx_t* const fCtx, FIO_prefs_t* const prefs
return 1; return 1;
} }
srcFile = FIO_openSrcFile(srcFileName); srcFile = FIO_openSrcFile(prefs, srcFileName);
if (srcFile==NULL) return 1; if (srcFile==NULL) return 1;
ress.srcBufferLoaded = 0; ress.srcBufferLoaded = 0;
@ -2921,7 +2927,7 @@ static InfoError
getFileInfo_fileConfirmed(fileInfo_t* info, const char* inFileName) getFileInfo_fileConfirmed(fileInfo_t* info, const char* inFileName)
{ {
InfoError status; InfoError status;
FILE* const srcFile = FIO_openSrcFile(inFileName); FILE* const srcFile = FIO_openSrcFile(NULL, inFileName);
ERROR_IF(srcFile == NULL, info_file_error, "Error: could not open source file %s", inFileName); ERROR_IF(srcFile == NULL, info_file_error, "Error: could not open source file %s", inFileName);
info->compressedSize = UTIL_getFileSize(inFileName); info->compressedSize = UTIL_getFileSize(inFileName);

View File

@ -103,6 +103,7 @@ void FIO_setLiteralCompressionMode(
void FIO_setNoProgress(unsigned noProgress); void FIO_setNoProgress(unsigned noProgress);
void FIO_setNotificationLevel(int level); void FIO_setNotificationLevel(int level);
void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompressedFiles); void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompressedFiles);
void FIO_setAllowBlockDevices(FIO_prefs_t* const prefs, int allowBlockDevices);
void FIO_setPatchFromMode(FIO_prefs_t* const prefs, int value); void FIO_setPatchFromMode(FIO_prefs_t* const prefs, int value);
void FIO_setContentSize(FIO_prefs_t* const prefs, int value); void FIO_setContentSize(FIO_prefs_t* const prefs, int value);

View File

@ -269,6 +269,17 @@ int UTIL_isFIFOStat(const stat_t* statbuf)
return 0; return 0;
} }
/* UTIL_isBlockDevStat : distinguish named pipes */
int UTIL_isBlockDevStat(const stat_t* statbuf)
{
/* macro guards, as defined in : https://linux.die.net/man/2/lstat */
#if PLATFORM_POSIX_VERSION >= 200112L
if (S_ISBLK(statbuf->st_mode)) return 1;
#endif
(void)statbuf;
return 0;
}
int UTIL_isLink(const char* infilename) int UTIL_isLink(const char* infilename)
{ {
/* macro guards, as defined in : https://linux.die.net/man/2/lstat */ /* macro guards, as defined in : https://linux.die.net/man/2/lstat */

View File

@ -143,6 +143,7 @@ int UTIL_setFileStat(const char* filename, const stat_t* statbuf);
int UTIL_isRegularFileStat(const stat_t* statbuf); int UTIL_isRegularFileStat(const stat_t* statbuf);
int UTIL_isDirectoryStat(const stat_t* statbuf); int UTIL_isDirectoryStat(const stat_t* statbuf);
int UTIL_isFIFOStat(const stat_t* statbuf); int UTIL_isFIFOStat(const stat_t* statbuf);
int UTIL_isBlockDevStat(const stat_t* statbuf);
U64 UTIL_getFileSizeStat(const stat_t* statbuf); U64 UTIL_getFileSizeStat(const stat_t* statbuf);
/** /**

View File

@ -1,3 +1,5 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "ZSTD" "1" "May 2021" "zstd 1.4.10" "User Commands" .TH "ZSTD" "1" "May 2021" "zstd 1.4.10" "User Commands"
. .
@ -156,7 +158,7 @@ This is also used during compression when using with \-\-patch\-from=\. In this
\fB\-o FILE\fR: save result into \fBFILE\fR \fB\-o FILE\fR: save result into \fBFILE\fR
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-f\fR, \fB\-\-force\fR: disable input and output checks\. Allows overwriting existing files, input from console, output to stdout, operating on links, etc\. \fB\-f\fR, \fB\-\-force\fR: disable input and output checks\. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-c\fR, \fB\-\-stdout\fR: force write to standard output, even if it is the console \fB\-c\fR, \fB\-\-stdout\fR: force write to standard output, even if it is the console

View File

@ -202,7 +202,7 @@ the last one takes effect.
save result into `FILE` save result into `FILE`
* `-f`, `--force`: * `-f`, `--force`:
disable input and output checks. Allows overwriting existing files, input disable input and output checks. Allows overwriting existing files, input
from console, output to stdout, operating on links, etc. from console, output to stdout, operating on links, block devices, etc.
* `-c`, `--stdout`: * `-c`, `--stdout`:
force write to standard output, even if it is the console force write to standard output, even if it is the console
* `--[no-]sparse`: * `--[no-]sparse`:

View File

@ -148,7 +148,8 @@ static void usage(FILE* f, const char* programName)
DISPLAY_F(f, " -D DICT: use DICT as Dictionary for compression or decompression \n"); DISPLAY_F(f, " -D DICT: use DICT as Dictionary for compression or decompression \n");
DISPLAY_F(f, " -o file: result stored into `file` (only 1 output file) \n"); DISPLAY_F(f, " -o file: result stored into `file` (only 1 output file) \n");
DISPLAY_F(f, " -f : disable input and output checks. Allows overwriting existing files,\n"); DISPLAY_F(f, " -f : disable input and output checks. Allows overwriting existing files,\n");
DISPLAY_F(f, " input from console, output to stdout, operating on links, etc.\n"); DISPLAY_F(f, " input from console, output to stdout, operating on links,\n");
DISPLAY_F(f, " block devices, etc.\n");
DISPLAY_F(f, "--rm : remove source file(s) after successful de/compression \n"); DISPLAY_F(f, "--rm : remove source file(s) after successful de/compression \n");
DISPLAY_F(f, " -k : preserve source file(s) (default) \n"); DISPLAY_F(f, " -k : preserve source file(s) (default) \n");
DISPLAY_F(f, " -h/-H : display help/long help and exit \n"); DISPLAY_F(f, " -h/-H : display help/long help and exit \n");
@ -724,6 +725,7 @@ int main(int const argCount, const char* argv[])
{ {
int argNb, int argNb,
followLinks = 0, followLinks = 0,
allowBlockDevices = 0,
forceStdin = 0, forceStdin = 0,
forceStdout = 0, forceStdout = 0,
hasStdout = 0, hasStdout = 0,
@ -838,7 +840,7 @@ int main(int const argCount, const char* argv[])
if (!strcmp(argument, "--compress")) { operation=zom_compress; continue; } if (!strcmp(argument, "--compress")) { operation=zom_compress; continue; }
if (!strcmp(argument, "--decompress")) { operation=zom_decompress; continue; } if (!strcmp(argument, "--decompress")) { operation=zom_decompress; continue; }
if (!strcmp(argument, "--uncompress")) { operation=zom_decompress; continue; } if (!strcmp(argument, "--uncompress")) { operation=zom_decompress; continue; }
if (!strcmp(argument, "--force")) { FIO_overwriteMode(prefs); forceStdin=1; forceStdout=1; followLinks=1; continue; } if (!strcmp(argument, "--force")) { FIO_overwriteMode(prefs); forceStdin=1; forceStdout=1; followLinks=1; allowBlockDevices=1; continue; }
if (!strcmp(argument, "--version")) { printVersion(); CLEAN_RETURN(0); } if (!strcmp(argument, "--version")) { printVersion(); CLEAN_RETURN(0); }
if (!strcmp(argument, "--help")) { usage_advanced(programName); CLEAN_RETURN(0); } if (!strcmp(argument, "--help")) { usage_advanced(programName); CLEAN_RETURN(0); }
if (!strcmp(argument, "--verbose")) { g_displayLevel++; continue; } if (!strcmp(argument, "--verbose")) { g_displayLevel++; continue; }
@ -1024,7 +1026,7 @@ int main(int const argCount, const char* argv[])
case 'D': argument++; NEXT_FIELD(dictFileName); break; case 'D': argument++; NEXT_FIELD(dictFileName); break;
/* Overwrite */ /* Overwrite */
case 'f': FIO_overwriteMode(prefs); forceStdin=1; forceStdout=1; followLinks=1; argument++; break; case 'f': FIO_overwriteMode(prefs); forceStdin=1; forceStdout=1; followLinks=1; allowBlockDevices=1; argument++; break;
/* Verbose mode */ /* Verbose mode */
case 'v': g_displayLevel++; argument++; break; case 'v': g_displayLevel++; argument++; break;
@ -1331,6 +1333,7 @@ int main(int const argCount, const char* argv[])
FIO_setNbFilesTotal(fCtx, (int)filenames->tableSize); FIO_setNbFilesTotal(fCtx, (int)filenames->tableSize);
FIO_determineHasStdinInput(fCtx, filenames); FIO_determineHasStdinInput(fCtx, filenames);
FIO_setNotificationLevel(g_displayLevel); FIO_setNotificationLevel(g_displayLevel);
FIO_setAllowBlockDevices(prefs, allowBlockDevices);
FIO_setPatchFromMode(prefs, patchFromDictFileName != NULL); FIO_setPatchFromMode(prefs, patchFromDictFileName != NULL);
if (memLimit == 0) { if (memLimit == 0) {
if (compressionParams.windowLog == 0) { if (compressionParams.windowLog == 0) {

View File

@ -459,6 +459,22 @@ if [ -n "$DEVNULLRIGHTS" ] ; then
ls -las $INTOVOID | grep "rw-rw-rw-" ls -las $INTOVOID | grep "rw-rw-rw-"
fi fi
if [ -n "$READFROMBLOCKDEVICE" ] ; then
# This creates a temporary block device, which is only possible on unix-y
# systems, is somewhat invasive, and requires sudo. For these reasons, you
# have to specifically ask for this test.
println "\n===> checking that zstd can read from a block device"
datagen -g65536 > tmp.img
sudo losetup -fP tmp.img
LOOP_DEV=$(losetup -a | grep 'tmp\.img' | cut -f1 -d:)
[ -z "$LOOP_DEV" ] && die "failed to get loopback device"
sudoZstd $LOOP_DEV -c > tmp.img.zst && die "should fail without -f"
sudoZstd -f $LOOP_DEV -c > tmp.img.zst
zstd -d tmp.img.zst -o tmp.img.copy
sudo losetup -d $LOOP_DEV
$DIFF -s tmp.img tmp.img.copy || die "round trip failed"
rm -f tmp.img tmp.img.zst tmp.img.copy
fi
println "\n===> compress multiple files into an output directory, --output-dir-flat" println "\n===> compress multiple files into an output directory, --output-dir-flat"
println henlo > tmp1 println henlo > tmp1