Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Reading from Block Devices with --force #2613

Merged
merged 2 commits into from
May 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/generic-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ jobs:

test:
runs-on: ubuntu-latest
env:
DEVNULLRIGHTS: 1
READFROMBLOCKDEVICE: 1
steps:
- uses: actions/checkout@v2
- name: make test
Expand Down
16 changes: 11 additions & 5 deletions programs/fileio.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ struct FIO_prefs_s {
int excludeCompressedFiles;
int patchFromMode;
int contentSize;
int allowBlockDevices;
};

/*-*************************************
Expand Down Expand Up @@ -384,6 +385,7 @@ FIO_prefs_t* FIO_createPreferences(void)
ret->testMode = 0;
ret->literalCompressionMode = ZSTD_lcm_auto;
ret->excludeCompressedFiles = 0;
ret->allowBlockDevices = 0;
return ret;
}

Expand Down Expand Up @@ -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_setAllowBlockDevices(FIO_prefs_t* const prefs, int allowBlockDevices) { prefs->allowBlockDevices = allowBlockDevices; }

void FIO_setBlockSize(FIO_prefs_t* const prefs, int blockSize) {
if (blockSize && prefs->nbWorkers==0)
DISPLAYLEVEL(2, "Setting block size is useless in single-thread mode \n");
Expand Down Expand Up @@ -593,11 +597,12 @@ static int FIO_removeFile(const char* path)
}

/** 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 */
static FILE* FIO_openSrcFile(const char* srcFileName)
static FILE* FIO_openSrcFile(const FIO_prefs_t* const prefs, const char* srcFileName)
{
stat_t statbuf;
int allowBlockDevices = prefs != NULL ? prefs->allowBlockDevices : 0;
assert(srcFileName != NULL);
if (!strcmp (srcFileName, stdinmark)) {
DISPLAYLEVEL(4,"Using stdin for input \n");
Expand All @@ -613,6 +618,7 @@ static FILE* FIO_openSrcFile(const char* srcFileName)

if (!UTIL_isRegularFileStat(&statbuf)
&& !UTIL_isFIFOStat(&statbuf)
&& !(allowBlockDevices && UTIL_isBlockDevStat(&statbuf))
) {
DISPLAYLEVEL(1, "zstd: %s is not a regular file -- ignored \n",
srcFileName);
Expand Down Expand Up @@ -1708,7 +1714,7 @@ FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx,
return 0;
}

ress.srcFile = FIO_openSrcFile(srcFileName);
ress.srcFile = FIO_openSrcFile(prefs, srcFileName);
if (ress.srcFile == NULL) return 1; /* srcFile could not be opened */

result = FIO_compressFilename_dstFile(fCtx, prefs, ress, dstFileName, srcFileName, compressionLevel);
Expand Down Expand Up @@ -2571,7 +2577,7 @@ static int FIO_decompressSrcFile(FIO_ctx_t* const fCtx, FIO_prefs_t* const prefs
return 1;
}

srcFile = FIO_openSrcFile(srcFileName);
srcFile = FIO_openSrcFile(prefs, srcFileName);
if (srcFile==NULL) return 1;
ress.srcBufferLoaded = 0;

Expand Down Expand Up @@ -2921,7 +2927,7 @@ static InfoError
getFileInfo_fileConfirmed(fileInfo_t* info, const char* inFileName)
{
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);

info->compressedSize = UTIL_getFileSize(inFileName);
Expand Down
1 change: 1 addition & 0 deletions programs/fileio.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ void FIO_setLiteralCompressionMode(
void FIO_setNoProgress(unsigned noProgress);
void FIO_setNotificationLevel(int level);
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_setContentSize(FIO_prefs_t* const prefs, int value);

Expand Down
11 changes: 11 additions & 0 deletions programs/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,17 @@ int UTIL_isFIFOStat(const stat_t* statbuf)
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)
{
/* macro guards, as defined in : https://linux.die.net/man/2/lstat */
Expand Down
1 change: 1 addition & 0 deletions programs/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ int UTIL_setFileStat(const char* filename, const stat_t* statbuf);
int UTIL_isRegularFileStat(const stat_t* statbuf);
int UTIL_isDirectoryStat(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);

/**
Expand Down
6 changes: 4 additions & 2 deletions programs/zstd.1
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ZSTD" "1" "March 2021" "zstd 1.4.9" "User Commands"
.TH "ZSTD" "1" "May 2021" "zstd 1.4.10" "User Commands"
.
.SH "NAME"
\fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files
Expand Down Expand Up @@ -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
.
.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
\fB\-c\fR, \fB\-\-stdout\fR: force write to standard output, even if it is the console
Expand Down
2 changes: 1 addition & 1 deletion programs/zstd.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ the last one takes effect.
save result into `FILE`
* `-f`, `--force`:
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`:
force write to standard output, even if it is the console
* `--[no-]sparse`:
Expand Down
9 changes: 6 additions & 3 deletions programs/zstdcli.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, " -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, " 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, " -k : preserve source file(s) (default) \n");
DISPLAY_F(f, " -h/-H : display help/long help and exit \n");
Expand Down Expand Up @@ -724,6 +725,7 @@ int main(int const argCount, const char* argv[])
{
int argNb,
followLinks = 0,
allowBlockDevices = 0,
forceStdin = 0,
forceStdout = 0,
hasStdout = 0,
Expand Down Expand Up @@ -838,7 +840,7 @@ int main(int const argCount, const char* argv[])
if (!strcmp(argument, "--compress")) { operation=zom_compress; continue; }
if (!strcmp(argument, "--decompress")) { 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, "--help")) { usage_advanced(programName); CLEAN_RETURN(0); }
if (!strcmp(argument, "--verbose")) { g_displayLevel++; continue; }
Expand Down Expand Up @@ -1024,7 +1026,7 @@ int main(int const argCount, const char* argv[])
case 'D': argument++; NEXT_FIELD(dictFileName); break;

/* 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 */
case 'v': g_displayLevel++; argument++; break;
Expand Down Expand Up @@ -1331,6 +1333,7 @@ int main(int const argCount, const char* argv[])
FIO_setNbFilesTotal(fCtx, (int)filenames->tableSize);
FIO_determineHasStdinInput(fCtx, filenames);
FIO_setNotificationLevel(g_displayLevel);
FIO_setAllowBlockDevices(prefs, allowBlockDevices);
FIO_setPatchFromMode(prefs, patchFromDictFileName != NULL);
if (memLimit == 0) {
if (compressionParams.windowLog == 0) {
Expand Down
16 changes: 16 additions & 0 deletions tests/playTests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,22 @@ if [ -n "$DEVNULLRIGHTS" ] ; then
ls -las $INTOVOID | grep "rw-rw-rw-"
fi

if [ -n "$READFROMBLOCKDEVICE" ] ; then
felixhandte marked this conversation as resolved.
Show resolved Hide resolved
# 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 henlo > tmp1
Expand Down