Compare commits
13 Commits
upstream/1
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
db9aca72df | ||
|
153663d8b6 | ||
|
345149210e | ||
|
73b05cde71 | ||
|
1aa8d4d499 | ||
|
2285cff2a6 | ||
|
a311749e46 | ||
|
d767689d60 | ||
|
1dd99167db | ||
|
859826a091 | ||
|
36b5ac9c36 | ||
|
cfd0df25f8 | ||
|
2e8fba7836 |
52
.circleci/config.yml
Normal file
52
.circleci/config.yml
Normal file
@ -0,0 +1,52 @@
|
||||
# Build configuration for https://circleci.com/
|
||||
|
||||
version: 2.1
|
||||
|
||||
orbs:
|
||||
win: circleci/windows@2.2.0
|
||||
|
||||
workflows:
|
||||
main:
|
||||
jobs:
|
||||
- build_ubuntu
|
||||
- build_docker
|
||||
|
||||
jobs:
|
||||
build_docker:
|
||||
docker:
|
||||
- image: circleci/buildpack-deps:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run: autoreconf -i && ./configure --enable-warning-as-error && make all dist
|
||||
build_ubuntu:
|
||||
machine:
|
||||
image: ubuntu-2004:202101-01
|
||||
steps:
|
||||
- checkout
|
||||
- run: autoreconf -i && ./configure --enable-warning-as-error && make all dist
|
||||
build_win:
|
||||
executor:
|
||||
name: win/default
|
||||
steps:
|
||||
- run:
|
||||
name: Installing MSYS2
|
||||
shell: powershell.exe
|
||||
command: 'choco install msys2'
|
||||
- run:
|
||||
name: Installing tools
|
||||
shell: powershell.exe
|
||||
command: 'C:\tools\msys64\usr\bin\bash.exe -l -c "pacman --needed --noconfirm -S autoreconf automake mingw-w64-x86_64-toolchain"'
|
||||
- checkout
|
||||
- run:
|
||||
name: Autoreconf
|
||||
shell: C:\\tools\\msys64\\usr\\bin\\bash.exe -l
|
||||
command: 'cd /c/Users/circleci/project && autoreconf -i'
|
||||
- run:
|
||||
name: Configure
|
||||
shell: C:\\tools\\msys64\\usr\\bin\\bash.exe -l
|
||||
command: 'cd /c/Users/circleci/project && ./configure --enable-warning-as-error'
|
||||
- run:
|
||||
name: Make
|
||||
shell: C:\\tools\\msys64\\usr\\bin\\bash.exe -l
|
||||
command: 'cd /c/Users/circleci/project && make'
|
||||
|
17
.drone.yml
Normal file
17
.drone.yml
Normal file
@ -0,0 +1,17 @@
|
||||
# Build configuration for https://www.tea-ci.org
|
||||
|
||||
build:
|
||||
image: teaci/msys$$arch
|
||||
shell: mingw$$arch
|
||||
pull: true
|
||||
commands:
|
||||
- autoreconf -i
|
||||
- ./configure --enable-warning-as-error
|
||||
- make
|
||||
- make check
|
||||
|
||||
matrix:
|
||||
arch:
|
||||
- 64
|
||||
- 32
|
||||
|
43
.github/workflows/build.yml
vendored
Normal file
43
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build-mac:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: brew install automake
|
||||
- run: autoreconf -i
|
||||
- run: ./configure --enable-warning-as-error
|
||||
- run: make all
|
||||
- run: make distcheck
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: autoreconf -i
|
||||
- run: ./configure --enable-warning-as-error
|
||||
- run: make all
|
||||
- run: make distcheck
|
||||
build-win:
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
update: true
|
||||
install: mingw-w64-x86_64-gcc autoconf automake make
|
||||
- run: autoreconf -i
|
||||
- run: ./configure --enable-warning-as-error
|
||||
- run: make all
|
||||
- run: make distcheck
|
||||
|
71
.github/workflows/codeql-analysis.yml
vendored
Normal file
71
.github/workflows/codeql-analysis.yml
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '20 6 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
69
.gitignore
vendored
Normal file
69
.gitignore
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
# archives
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.tgz
|
||||
|
||||
# backups
|
||||
*~
|
||||
|
||||
# logs
|
||||
*.log
|
||||
stream*.bin
|
||||
|
||||
# upload
|
||||
makepush.sh
|
||||
makemount.sh
|
||||
makeumount.sh
|
||||
|
||||
# autotools
|
||||
Makefile
|
||||
Makefile.in
|
||||
compile
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
install-sh
|
||||
missing
|
||||
stamp-h1
|
||||
.dirstamp
|
||||
|
||||
# objects
|
||||
snapraid
|
||||
mktest
|
||||
mkstream
|
||||
*.exe
|
||||
*.o
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.gcov
|
||||
|
||||
# projects
|
||||
*.dst
|
||||
*.epr
|
||||
*.geany
|
||||
|
||||
# AFL
|
||||
makeafl.sh
|
||||
afl/
|
||||
afl_corpus/
|
||||
|
||||
# specific
|
||||
cov/
|
||||
contrib/
|
||||
paper/
|
||||
kernel/
|
||||
obj/
|
||||
bench/
|
||||
support/
|
||||
archive/
|
||||
www/
|
||||
wiki/
|
||||
beta/
|
||||
ftp/
|
||||
|
151
CHECKSUMS
Normal file
151
CHECKSUMS
Normal file
@ -0,0 +1,151 @@
|
||||
sha256
|
||||
761eaf08937139a89d79d1ffbad42508f270d3aa603eac50475f7449ae278dcf snapraid-1.2.tar.gz
|
||||
10e64f2629eb469a32eabc84e1f9a59593cbbf61282ead964b622af1ec0c4681 snapraid-1.2-windows-x64.zip
|
||||
27da3c54fe408ab53c6e2b4b398ae46328a2dbc701b785a55bf76ffed6046eb2 snapraid-1.2-windows-x86.zip
|
||||
2e6aaa660a5a74665044ead40959006632dcd1ee1e21091e6260f5b845304f96 snapraid-1.3.tar.gz
|
||||
0d0cefeabf8230b66414a8731ceb52a0adaaedb5be0fa11d07a6be44e9f2fb6d snapraid-1.3-windows-x64.zip
|
||||
4358802fb022ba5e2f8d1323ce963155adccea99069abd5f901eadf1411b6366 snapraid-1.3-windows-x86.zip
|
||||
157b0ca7cfa9cba43cf995b4c32b0b206e299f5ffff58062069bb6ec41c77c0d snapraid-1.4.tar.gz
|
||||
5b210dd4667369799fd02757e8efc4d733c704cfe72319d297d4ab969b80c962 snapraid-1.4-windows-x64.zip
|
||||
77047e1fa1bfcb12db7d5c3167e7dbbbb1718909f1003fd185cdf219cd952427 snapraid-1.4-windows-x86.zip
|
||||
f460bf9aee4b02b6c08f19b0caa2928b075c73ca4cfc41c7f426f015f67cffbc snapraid-1.5.tar.gz
|
||||
d19262bdf9e572fa80285887886a8fbe9a7b9bd4159496f112d383bf9b4db797 snapraid-1.5-windows-x64.zip
|
||||
28816c0cde4cf8ce8e91a585eb9aab5552344a331237b6a2afd50396685814fd snapraid-1.5-windows-x86.zip
|
||||
e0684d036cfd6b9fcdf23792c057fec4f4531d25aab7c677ff35e7a8be07b098 snapraid-1.6.tar.gz
|
||||
9c13f99d67aafe43f5c540d97d0f6b40289856f547b8f33ee8aee27b270a7fae snapraid-1.6-windows-x64.zip
|
||||
ae94db99a06068e17134ce69009492c4bfd8f6e54ea1848df105bb89f9f7ba28 snapraid-1.6-windows-x86.zip
|
||||
1cf7a8f58533d6bc717ff6d396114ec4ed61eb66ff2756370e4cc730ee4edc4d snapraid-1.7.tar.gz
|
||||
0cb49c676f3f9fd1f0fc938513b6dcaaf15390b64098e17cff5066667e4d01d5 snapraid-1.7-windows-x64.zip
|
||||
44bc6b947ba845a89ecf812b82e751dca2dd4a6143ff06391c3b8b285a7ed3a2 snapraid-1.7-windows-x86.zip
|
||||
da1c09f0139e683c03942c2b9489c2d9b989c59d147f7c28258c8e58c3938037 snapraid-1.8.tar.gz
|
||||
fca7352fece5d7243af45ba8c5a07e08cc0e24d226468a619b9d86a3767e7099 snapraid-1.8-windows-x64.zip
|
||||
35520cab33b3b3f9efc4ba4d7a968a7d7d49637b5e256921e0091424f5dd60ee snapraid-1.8-windows-x86.zip
|
||||
504c3fe288b66c84bc65173979e7cede06370ca2a5f02ef3ca200c2fc8b09ea9 snapraid-1.9.tar.gz
|
||||
ddba596451a05c61b20ce1e82c8039ba3c13be67b7469f2c75c6b0b7b4b18356 snapraid-1.9-windows-x64.zip
|
||||
5a0dd3cdc0edf69cd03d926b594e41f5ca7e07564ef1cb3d6ac417c76f16b77b snapraid-1.9-windows-x86.zip
|
||||
5e4eee49748faf966ebcc1cb3b9127ad7047542baf8952c6e0a9cbb32dac4d88 snapraid-1.10.tar.gz
|
||||
7812a37f8767beb9542def762b2e131caafffc1b1b21f1d9422030e93e367f12 snapraid-1.10-windows-x64.zip
|
||||
b899784498050c5d41752464bd31cec7de9e77ec865f55e2192fea75f52787d5 snapraid-1.10-windows-x86.zip
|
||||
c349c4c25e3cb794d908dc75422ca9b04b44162c295b41d4ea55081af1a3451f snapraid-1.11.tar.gz
|
||||
47e8f09f3d012d0a34d71e6ece7b9171c82af27766cca709fc9bbd104328cc7d snapraid-1.11-windows-x64.zip
|
||||
8a8b0562192732022ae1732f5ae48e5f8745e217f73683123b2822e316918204 snapraid-1.11-windows-x86.zip
|
||||
bd89ef0ddc3909c50fecc30da1d5d70342b92952b5d3ae0a2e31a66c8755dc8a snapraid-1.12.tar.gz
|
||||
290c5ac8667ca7ada12a0d550e06c9fbc5f4e29abb5af0ef105eba38fb274c5d snapraid-1.12-windows-x64.zip
|
||||
8cbc4e447f2152c3e76025cdbad03c54e7c85e004bb535f9dc7dde9b86605fe8 snapraid-1.12-windows-x86.zip
|
||||
7c824abf6cacd8b847467916a1b4c28f48161e4b9f9b6c2f607c4de473a663c9 snapraid-1.13.tar.gz
|
||||
22f6e9bf1dff5df4abff29b7cf364dc029959991dc158257f2a283721581abf4 snapraid-1.13-windows-x64.zip
|
||||
9801b1a0331c461ce70c7824e2624dd2866358d61d923ff854253f340985947e snapraid-1.13-windows-x86.zip
|
||||
68a48c961fcc15ffcfb86e4c5ea2371d562252e61f58fe87a529f479e81fb2bb snapraid-2.0.tar.gz
|
||||
a2e1fb0610c8bfc57d73da1dbd276c238a032bf9b4c73a41977fcc57e773fff4 snapraid-2.0-windows-x64.zip
|
||||
0fc3bee4d107bcd5e55a1c5bb81015558d9791d66a44f9ae2e3723906c3199df snapraid-2.0-windows-x86.zip
|
||||
788377f579486c2b16548563a3d25f385594ae4276f1328c8f82cd0d5e0af9b6 snapraid-2.1.tar.gz
|
||||
6e32fc0603136c4d3ad60fc1f04e6c919b7e7159267750ebf0dd8ad20ee6b442 snapraid-2.1-windows-x64.zip
|
||||
d2813aec37f96506bcf98f2b5196204f065786731a5874f495f18f58fe87064b snapraid-2.1-windows-x86.zip
|
||||
faf9545f0a66865e754ad587731483becf895a954c22e023501a2f28af44682a snapraid-2.2.tar.gz
|
||||
2ea4b610c8d99f3766f6d2c89be5eafd1e16a17454d9df02d982fa184b517744 snapraid-2.2-windows-x64.zip
|
||||
e2dac0663546f06ac3e679a93ba5de9e7de91563e09c1396fd367c5b16e011be snapraid-2.2-windows-x86.zip
|
||||
68e610d67087c02715289934472c5fa3d7aa77c8085298ba54f02f26f7d396ad snapraid-3.0.tar.gz
|
||||
ca7943f270a940554ddbd8c09698228120da2bac5b6d78486a34f5b301e24f47 snapraid-3.0-windows-x64.zip
|
||||
c6a47d8bf544e69d9b301fe525d193c8faa8ef056c78f8a0649637d2e99b93c6 snapraid-3.0-windows-x86.zip
|
||||
b5b22350c221e145c3347426f186f188f5d64616d03f196b35d75db564e78f7f snapraid-3.1.tar.gz
|
||||
6d275cf3d579a5050e936879db85acbcb34b6522b36d5bc81b2f3764ca011c87 snapraid-3.1-windows-x64.zip
|
||||
66f5967e559368193aef7b13a1c641694ca62f64e4b5749a7e2709aac6dc5759 snapraid-3.1-windows-x86.zip
|
||||
99617ef379c4e46cc4366f2b3baced653f786ef08a40d74dca23a11a9240b096 snapraid-3.2.tar.gz
|
||||
94d121d8cc0b9ab7ef1648e42edbfe1cfc602231c86a086d21984177da566f77 snapraid-3.2-windows-x64.zip
|
||||
1d1ed69d3eab8247a7444e603ba09a56ec77979d3865489b2d8a7fc5db65848f snapraid-3.2-windows-x86.zip
|
||||
c5a6e77613fab5cecb1aa55750f2045934d9374ba70471b6d35296c34509e5a9 snapraid-4.0.tar.gz
|
||||
a59c911fef0d4d3e95d5521c6a180b40c455870be3ee9dbb5991b05b2cdd2f05 snapraid-4.0-windows-x64.zip
|
||||
97ec4ae7b6ec6cd05e0c2ae835def526d12c35fa3546d27bd93978d978cd62aa snapraid-4.0-windows-x86.zip
|
||||
7f5a37be7b8b78056d6602cef8ef702fe4f0d0b6ac3fa4bcefeb70743425b6fe snapraid-4.2.tar.gz
|
||||
bf7861274639f2e9e5819ec3a89eed911cd79a212824fe3a6b64e45c0d1e2cc4 snapraid-4.2-windows-x64.zip
|
||||
c7d9330be1936d7d7b07c51668fc8d3f88ce270e9e74945288d75eda2405a377 snapraid-4.2-windows-x86.zip
|
||||
09f1ebfb5c45680c50651e94287d59e58260c46aee922d8864fb06fd591740e8 snapraid-4.3.tar.gz
|
||||
ba1008452ff679c1e144206c73a81e4cb2689006c9ce37b60ceab45ef4c99dda snapraid-4.3-windows-x64.zip
|
||||
23b21e162d5d18a4f68c8635e1f111fddb91d380514d8ddab9040b18a49d9994 snapraid-4.3-windows-x86.zip
|
||||
aa22ea2e01a8db45ba43a3139d763cb2d12548de96f957a1ea1b5f80f04a4d83 snapraid-4.4.tar.gz
|
||||
ca68dd88741290a6ee6494a9186b58766cab2b838f4a55ab23921b524b15ee82 snapraid-4.4-windows-x64.zip
|
||||
3d9cccc2080d1435e7e747c7eeeffc85e0b68ad45b390c236de321b8aca44d46 snapraid-4.4-windows-x86.zip
|
||||
ba43b0534197c6064b7a171321762be2ac2c848d4849c578007cc65aa963bed5 snapraid-5.1.tar.gz
|
||||
54a31c5c979b9c3ad481cd918a48e220f11ce04de0a8ec6f41a957af7ba259fc snapraid-5.1-windows-x64.zip
|
||||
6758966b3a120bf5b97f21748f649b2f147800b10377a0ee69d922be318ee399 snapraid-5.1-windows-x86.zip
|
||||
eab07c21201eceb4204f8039f021ff0032515719aa5e640c330da45dd8b8e7a3 snapraid-5.2.tar.gz
|
||||
554cc7be40fff0a0f249522bda957dfba229066e81102624b979213666b1aaae snapraid-5.2-windows-x64.zip
|
||||
44f909157ba89d769af59e971c71b15bd38dfd62359b2e2c7eeb8cef0f9dc081 snapraid-5.2-windows-x86.zip
|
||||
81e00fced6bb040d49aa6e3dc6fda97f22bf677d00f6c0c490e312c23222b421 snapraid-5.3.tar.gz
|
||||
2627b2491b4d432a311cca1c924f4b40cef7a64c930b7e5eca55b3b9a8a62e61 snapraid-5.3-windows-x64.zip
|
||||
d1019dc29922d4787c3fd9d4222dfc3b84a6a2e0c6b2db298340747238d8fb46 snapraid-5.3-windows-x86.zip
|
||||
d836200058b98f189e576ad5619d4ffcd867e5dc8d2a4b775bff07d4f201c938 snapraid-6.0.tar.gz
|
||||
06f2e56bc30c89e4a1561ec32cf72b240765456505f17da539af4b4338a6b12c snapraid-6.0-windows-x64.zip
|
||||
6ae0a3fa973a28c64489bc28d7a7f4b354d3fc6703bcb83ef661cf76e994b34d snapraid-6.0-windows-x86.zip
|
||||
1709c09b0e0699ce38452be7340c279c561b91433a6810600386bb9d8c0491e3 snapraid-6.1.tar.gz
|
||||
40d995a88a23d799a32eba15f64c983a012771c527208cec2ad98787a45ef4c3 snapraid-6.1-windows-x64.zip
|
||||
f8e09b3300717d1f9ee9b69bb132038642839c19a15a1f47810f3de10ad559eb snapraid-6.1-windows-x86.zip
|
||||
b182328227ed9b87b01037f7d005d38a6e3cfb0f675e919978c696dcc6246787 snapraid-6.2.tar.gz
|
||||
72ccfbf6548b83bd6f229d4862763a4e4cf6001c94d9ee84bf7b2a379a9a7743 snapraid-6.2-windows-x64.zip
|
||||
55f1bc131f9148ed2b52e0e252c7155e50f5b4383fe82cd74ec2edace2ddc9c6 snapraid-6.2-windows-x86.zip
|
||||
1f1961385b865bff5282bd16aff76f372f3ed19b685ef7a3b27d907a499385d2 snapraid-6.3.tar.gz
|
||||
bb55d74d6b3cb08b21f70fded8b706ec1e790222cb265524cb2dc5499ec73391 snapraid-6.3-windows-x64.zip
|
||||
3e4fa161ea26b8472dbbbfb4e61b34aca904ff9621f5afafbc83280d334a89b2 snapraid-6.3-windows-x86.zip
|
||||
7cad74422d45c8a05435a03d3228a2d621a962fb866caedde0497f180bd9f60d snapraid-6.4.tar.gz
|
||||
59471b49733c36acfbdeb16b28fbee063c4582abab2c9168abc7abc75610f9fc snapraid-6.4-windows-x64.zip
|
||||
abe80b7c019980da2af5e07e0ea8b1ac1e1cdb2eb663483c07dab6ad6bd15985 snapraid-6.4-windows-x86.zip
|
||||
554684520204d45f8b7cee9abb0269dd2bdba272cb0130c3b26062bea551a791 snapraid-7.0.tar.gz
|
||||
a617b435f97cd746b4076d00cde68f947cca21adaca6ce603fec4676827b7ae9 snapraid-7.0-windows-x64.zip
|
||||
301af727522912184f6d4a8290757950fed4577da625d9951809ff69f50b6e4f snapraid-7.0-windows-x86.zip
|
||||
dd9005b6d7ea701e4aa0f854a0e34dabe68d7765b75f12fc6b3e1fda4d5c2cef snapraid-7.1.tar.gz
|
||||
0d3a9625a6156ffe9b9eb4703aa2fc63141c51b83c69e98fbecce5430b1980e4 snapraid-7.1-windows-x64.zip
|
||||
e0afdb753ae6a3bb3484a1bfe1cf01b9178010a8c11604e4bbc44b2f83884842 snapraid-7.1-windows-x86.zip
|
||||
a912628dd003b3d70f2736629d48eeb738e7d27cba74014001dcc46fce3bc3be snapraid-8.0.tar.gz
|
||||
9c2158fb9e2c08570f6a03f5cea7ab68d2a424adb1f42bb6b3d970ba9dc8a15d snapraid-8.0-windows-x64.zip
|
||||
3c2c4357450564010d80bbd2cb1d5583281885b32cf659a0cf3dadce4766e167 snapraid-8.0-windows-x86.zip
|
||||
6bf89a1319ac3403958cd2c98a9c6102728c0070cfa1aedd90c4561d93c54e5d snapraid-8.1.tar.gz
|
||||
83ad064d5c3938fdacb989983c6b0fafa0932c236dc4baa93512f3c97fa019bc snapraid-8.1-windows-x64.zip
|
||||
25e5cffade3667348a242f44fb23719328d578010d79bb28a5cab662fc75916b snapraid-8.1-windows-x86.zip
|
||||
dff5f4e9a41865313ddd60b6379d5c0b308880d33f197934f98313e8241c6274 snapraid-9.0.tar.gz
|
||||
624c3aa6cb0bdb7c90566545ca831721ea5e543c843418a00ff4de753af07953 snapraid-9.0-windows-x64.zip
|
||||
6ace6dafacd902bdf058e42c7d39591e327aef1bb19a94b05496f0f14aca8e1e snapraid-9.0-windows-x86.zip
|
||||
397fdd7709e941e372b37025457794f8b0ce63a5a8455703ad17770cbccd3823 snapraid-9.1.tar.gz
|
||||
4c56b2c5d556a3685239e444cb58ce84c398e86a173be34ff7cfa3a2b31a5b34 snapraid-9.1-windows-x64.zip
|
||||
515ca2078cdcb58b59afc005770a06648d8f17adb27afa5751ca6f68de2c05c6 snapraid-9.1-windows-x86.zip
|
||||
77de90645a5debd177995d7897d58277b7c778632f0d9852740f5670f3321176 snapraid-9.2.tar.gz
|
||||
483d96dc8937f6df48b7f454f8ec8f7ee51b5e973fa8f004e59048d60525d2fb snapraid-9.2-windows-x64.zip
|
||||
99c950ff31c73cc55a1b83e4dfdbb6e1717420af54721f8bbe813fbbba484e04 snapraid-9.2-windows-x86.zip
|
||||
61c4f3ce8bd5ebb1178fe76ab5933e90c4cead6dba31669f11e262d258c2b2ba snapraid-9.3.tar.gz
|
||||
178e743b6246265f936e63ab47fe2a942bf414992cd752478854b81bdf264913 snapraid-9.3-windows-x64.zip
|
||||
2cb888833cdddc82431822f818de0cfd046ceda5a7aa17bf9c410b6147ed7e20 snapraid-9.3-windows-x86.zip
|
||||
f7dcf19480256fc2c1db9ab976aa12f786e76da6044cc397f0451524e8031ad6 snapraid-10.0.tar.gz
|
||||
a3b4b2563f44f17072bb20963d61aae53d9f0e6b9446509fee76bbfa9b51fd23 snapraid-10.0-windows-x64.zip
|
||||
95a1859163beb8c8d02208b27ecf5298068972498c7e2b99b488693ad5f8f133 snapraid-10.0-windows-x86.zip
|
||||
30a72b8853ea750128c96784b73bb55f7faa4b16367b2e03f40c1f78515c5771 snapraid-11.0.tar.gz
|
||||
af6f24adb81008e7ccdb7a8f2c46d1187542bd290294563de90acf5d817d772d snapraid-11.0-windows-x64.zip
|
||||
fedc7591c8de0ce2775482e6b18033cdaca62078a0a16d45421d5fb5dd5615d6 snapraid-11.0-windows-x86.zip
|
||||
b9acafeb6cece61fd426f08362b596ba89eea0564231955b82156fd09c0e6884 snapraid-11.1.tar.gz
|
||||
6468d1a55a9a8043eae3c7c292c908c0fbd1974af3f175df23d39dd4748d9bf9 snapraid-11.1-windows-x64.zip
|
||||
e70929b44ed88701b542abbccadc57dd89469f58cf7d6ca0bf80ce706d854553 snapraid-11.1-windows-x86.zip
|
||||
735cdeb7656ac48cbb0b4a89a203dd566505071e465d5effbcc56bcb8fd3a0d7 snapraid-11.2.tar.gz
|
||||
025faabb6390b6af600034523e5988e14160015b835541d8427475ca7fa52057 snapraid-11.2-windows-x64.zip
|
||||
de16e2083054f34e1206b552bd05c64218c0dffcf787d716c6639f8728457d20 snapraid-11.2-windows-x86.zip
|
||||
d35ad92157936db3411e2cf7325665fc59e2d159204f9424895cfa9f33122af1 snapraid-11.3.tar.gz
|
||||
b764a3341783d4694242412e0fca7c112e44e84a4a89a7c27b0f74a836a84baf snapraid-11.3-windows-x64.zip
|
||||
f8e51bee80ae0223f402afe68f5192f1036434bab816c42333bf2e5f9fbc82a2 snapraid-11.3-windows-x86.zip
|
||||
1de47b8277c7dd9c339396efdd2b12a865ff82fdf6ab47cb945f2e21717451c9 snapraid-11.4.tar.gz
|
||||
0734ca7a521ba7c05eea6898f481ca812d2a2d78da4545f7990cd27e6381dc75 snapraid-11.4-windows-x64.zip
|
||||
061075df60b584ade5c76551ca54d76726441421576a544cdfd621acb23d55e1 snapraid-11.4-windows-x86.zip
|
||||
1f5267261bdbcf4d48b9359ce67184df11905590739140f740327fb73bcecafa snapraid-11.5.tar.gz
|
||||
e18f6b825a25b71947c2c41a315440a3d394de348afca80e2ab13a525bbb8a2b snapraid-11.5-windows-x64.zip
|
||||
a66753201e55c115699df78f89dd562c1b71e876aba5be35fcaf507bfe1e9e52 snapraid-11.5-windows-x86.zip
|
||||
f030a3830449a78d10af41320da0be21c60f88dc8d328ebd056e0eb7596161cf snapraid-11.6.tar.gz
|
||||
8a3b8fd240285b5abf62c3ce222a5c674b475a83b3c48a40e457d34bfbcd1744 snapraid-11.6-windows-x64.zip
|
||||
e8e9140423552cbccbe9a162100a830cd7d2e29bae0893cca9f5bd1943393508 snapraid-11.6-windows-x86.zip
|
||||
f07652261e9821a5adfbfa8dad3350aae3e7c285f42a6bd7d96a854e5bc56dda snapraid-12.0.tar.gz
|
||||
a9cd1e30042b09ecc42b508955a1c1144b446a0399c83ecfb78b5455d528938c snapraid-12.0-windows-x64.zip
|
||||
a037d16bb9d226da2c88df00e410f9e637f1acb6153ac078c9a3805e721282a6 snapraid-12.0-windows-x86.zip
|
||||
49337d9bafa96c2beac0125463bd22622be2fc00f3b4dee7e4b0e864d2a49661 snapraid-12.1.tar.gz
|
||||
23196a373b4c7a327a207f019ea833f888977f6e48743b0060706f67fbb1c13e snapraid-12.1-windows-x64.zip
|
||||
488e3b57323fd55c1bccc14a051d4048a1a7b7b5d6440ece30b5161bda9f5498 snapraid-12.1-windows-x86.zip
|
||||
9d30993aef7fd390369dcaf422ac35f3990e8c91f0fb26151f5b84ccb73d3e01 snapraid-12.2.tar.gz
|
||||
1f08ee889b4e0d221267ad011cfbd6f3ebdf94a8809ba2b2d79dbb0751a7c06a snapraid-12.2-windows-x64.zip
|
||||
daaccc71a2b2cf3d16d021d0c1f7db20e49fbaebea5cda6c301bf41bce8df073 snapraid-12.2-windows-x86.zip
|
||||
1f27aba6e5db3929474da9c472fc4a3bc51d4a83aa5385af6b09afc9f68d6d44 snapraid-12.3.tar.gz
|
||||
ffdd430f5f1ad8fba5bd0707bd860b0d3dca55cb8aeca633804638d64b5f0550 snapraid-12.3-windows-x64.zip
|
||||
579d24cc607d0668e6f17c905eb75e409086a58f466c6fae2943c8e2fc8de039 snapraid-12.3-windows-x86.zip
|
25
HISTORY
25
HISTORY
@ -1,6 +1,31 @@
|
||||
SnapRAID HISTORY
|
||||
================
|
||||
|
||||
12.4 2025/01
|
||||
============
|
||||
* Avoid a warning about function pointer conversion. No functional changes.
|
||||
|
||||
12.3 2024/01
|
||||
============
|
||||
* Fix potential integer overflow when computing the completion percentage.
|
||||
No effect on the functionality.
|
||||
* Documentation improvements.
|
||||
|
||||
12.2 2022/08
|
||||
============
|
||||
* Fix build issue with GLIBC 2.36
|
||||
|
||||
12.1 2022/01
|
||||
============
|
||||
* Reduce stack usage to work in environments with limited stack size, like
|
||||
MUSL.
|
||||
* Increase the default disk cache from 8 MiB to 16 MiB.
|
||||
|
||||
12.0 2021/12
|
||||
============
|
||||
* Parallel disk scanning. It's always enabled but it doesn't cover the -m
|
||||
option that still process disks sequentially.
|
||||
|
||||
11.6 2021/10
|
||||
============
|
||||
* The 'fix' and 'check' command with the -e option now process the whole
|
||||
|
16
INSTALL
16
INSTALL
@ -7,25 +7,27 @@ code from http://www.snapraid.it and unpack it with:
|
||||
tar xf snapraid-*.tar.gz
|
||||
cd snapraid-*
|
||||
|
||||
To configure and build run:
|
||||
To configure and build, run:
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
To check for correctness of the application run:
|
||||
To run the correctness tests for the application:
|
||||
|
||||
make check
|
||||
|
||||
If it terminates with "Success", you can install the application and
|
||||
the documentation running as root:
|
||||
If this terminates with "Success", you can install the application and
|
||||
the documentation by running:
|
||||
|
||||
sudo make install
|
||||
|
||||
To start using SnapRAID you have to change the example configuration
|
||||
file snapraid.conf.example to fit your needs and copy it in /etc/snapraid.conf
|
||||
(The snapraid application itself does not require root privileges.)
|
||||
|
||||
To start using SnapRAID, change the example configuration
|
||||
file snapraid.conf.example to fit your needs and copy it to /etc/snapraid.conf
|
||||
|
||||
To get more help, see the "Getting Started" section in the snapraid manpage
|
||||
typing:
|
||||
by typing:
|
||||
|
||||
man snapraid
|
||||
|
||||
|
30
Makefile.am
30
Makefile.am
@ -286,7 +286,7 @@ endif
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -a check
|
||||
#### CONTROLLED ####
|
||||
$(MSG) Filesystem allocation test
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/TEST
|
||||
# Copy the file to trigger the copy optimization check
|
||||
cp -a bench/disk1/TEST bench/disk2/TEST
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
@ -301,24 +301,24 @@ endif
|
||||
# Now sync will complete with -E
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -E sync
|
||||
$(MSG) Filesystem fragmentation test
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST1
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST2
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST3
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST4
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST5
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST6
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/TEST1
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/TEST2
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/TEST3
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/TEST4
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/TEST5
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/TEST6
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
# Now delete some files, and create a bigger one to fill the holes
|
||||
rm bench/disk1/TEST1
|
||||
rm bench/disk1/TEST3
|
||||
rm bench/disk1/TEST5
|
||||
head -c 65536 /dev/zero > bench/disk1/TESTX
|
||||
dd bs=1 count=65536 if=/dev/zero of=bench/disk1/TESTX
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync -l ">&1"
|
||||
rm -r bench/disk1/TEST*
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -E sync
|
||||
# Now enforce copy detection of a file without parity
|
||||
# Create a file in a high number disk
|
||||
head -c 8192 /dev/urandom > bench/disk6/STEP1
|
||||
dd bs=1 count=8192 if=/dev/urandom of=bench/disk6/STEP1
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
# Create two new copies. The one in disk1 will copy
|
||||
# the hash from the one in disk6, and the one in disk2
|
||||
@ -328,16 +328,16 @@ endif
|
||||
cp -a bench/disk6/STEP1 bench/disk2/STEP1
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
# Now create, duplicate, move and partial sync
|
||||
head -c 8192 /dev/zero > bench/disk1/INVA1
|
||||
head -c 8192 /dev/zero > bench/disk1/INVA2
|
||||
head -c 8192 /dev/zero > bench/disk1/INVA3
|
||||
head -c 8192 /dev/zero > bench/disk1/MOVE1
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/INVA1
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/INVA2
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/INVA3
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/MOVE1
|
||||
cp -a bench/disk1/MOVE1 bench/disk1/MOVE2
|
||||
cp -a bench/disk1/MOVE1 bench/disk1/MOVE3
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
mv bench/disk1/MOVE2 bench/disk2/MOVE2
|
||||
mv bench/disk1/MOVE3 bench/disk3/MOVE3
|
||||
head -c 8192 /dev/zero > bench/disk4/MOVE4
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk4/MOVE4
|
||||
cp -a bench/disk1/INVA1 bench/disk1/EXTRA1
|
||||
cp -a bench/disk1/INVA2 bench/disk1/EXTRA2
|
||||
cp -a bench/disk1/INVA3 bench/disk1/EXTRA3
|
||||
@ -770,7 +770,7 @@ endif
|
||||
$(MSG) This triggers the recovering with q using p to check the validity, but failing for new blocks being filled with zero
|
||||
cp -pR bench/disk1/a bench/disk1/a_copy
|
||||
# Ensure that there is at least one zero filled file
|
||||
head -c 8192 /dev/zero > bench/disk1/a_copy/ZERO_FILLED
|
||||
dd bs=1 count=8192 if=/dev/zero of=bench/disk1/a_copy/ZERO_FILLED
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -B 1 --test-kill-after-sync -c $(CONF) sync
|
||||
rm -r bench/disk1/a_copy
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-unrecoverable -c $(PAR2) fix -l test-fail-earlysyncadd.log
|
||||
|
1935
Makefile.in
1935
Makefile.in
File diff suppressed because it is too large
Load Diff
44
README
44
README
@ -1,33 +1,29 @@
|
||||
SnapRAID
|
||||
========
|
||||
|
||||
SnapRAID is a backup program for disk arrays. It stores parity
|
||||
information of your data and it recovers from up to six disk
|
||||
failures.
|
||||
SnapRAID is a backup program designed for disk arrays, storing
|
||||
parity information for data recovery in the event of up to six
|
||||
disk failures.
|
||||
|
||||
SnapRAID is mainly targeted for a home media center, where you
|
||||
have a lot of big files that rarely change.
|
||||
Primarily intended for home media centers with large,
|
||||
infrequently changing files, SnapRAID offers several features:
|
||||
|
||||
Beside the ability to recover from disk failures, the other
|
||||
features of SnapRAID are:
|
||||
|
||||
* You can use disk already filled with files, without the need to
|
||||
reformat them. You will access them like now.
|
||||
* All your data is hashed to ensure data integrity and to avoid
|
||||
* You can utilize disks already filled with files without the
|
||||
need to reformat them, accessing them as usual.
|
||||
* All your data is hashed to ensure data integrity and prevent
|
||||
silent corruption.
|
||||
* If the failed disks are too many to allow a recovery,
|
||||
you lose the data only on the failed disks.
|
||||
All the data in the other disks is safe.
|
||||
* If you accidentally delete some files in a disk, you can
|
||||
recover them.
|
||||
* The disks can have different sizes.
|
||||
* When the number of failed disks exceeds the parity count,
|
||||
data loss is confined to the affected disks; data on
|
||||
other disks remains accessible.
|
||||
* If you accidentally delete files on a disk, recovery is
|
||||
possible.
|
||||
* Disks can have different sizes.
|
||||
* You can add disks at any time.
|
||||
* It doesn't lock-in your data. You can stop using SnapRAID at any
|
||||
time without the need to reformat or move data.
|
||||
* To access a file, only a single disk needs to spin, saving power and
|
||||
producing less noise.
|
||||
* SnapRAID doesn't lock in your data; you can stop using it
|
||||
anytime without reformatting or moving data.
|
||||
* To access a file, only a single disk needs to spin, saving
|
||||
power and reducing noise.
|
||||
|
||||
The official site of SnapRAID is:
|
||||
|
||||
http://www.snapraid.it/
|
||||
For more information, please visit the official SnapRAID site:
|
||||
|
||||
:http://www.snapraid.it/
|
||||
|
12
TODO
12
TODO
@ -5,6 +5,18 @@ This is the list of TODO items for SnapRAID.
|
||||
|
||||
- Next
|
||||
|
||||
* Add an option to ignore a specific Smart attribute. This solves PullRequest #17 an #21
|
||||
|
||||
* Support BTRFS subvolumes. Keep track of the subvolumeid, along with the inode, and use it when searching/comparing inodes.
|
||||
The value 0 can be used for the root volume, like a normal filesystem.
|
||||
See: https://github.com/kdave/btrfs-progs/tree/master/libbtrfsutil
|
||||
|
||||
* A "dependents" output option to [--test-fmt file|disk|path|dependents] for LIST.
|
||||
Example, snapraid LIST --test-fmt dependents >FileList_with_dependents.txt
|
||||
The goal is a filelist that, for every file, includes full paths to the dependent files
|
||||
on other data disks needed to repair that file (in addition to the parity data).
|
||||
|
||||
I created a thread about it here: https://sourceforge.net/p/snapraid/discussion/1677233/thread/6e872fdae0/
|
||||
- Minor
|
||||
|
||||
* Add a new -u, --filter-updated command that filters files
|
||||
|
838
aclocal.m4
vendored
838
aclocal.m4
vendored
@ -1,838 +0,0 @@
|
||||
# generated automatically by aclocal 1.15 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
|
||||
[m4_warning([this file was generated for autoconf 2.69.
|
||||
You have another version of autoconf. It may work, but is not guaranteed to.
|
||||
If you have problems, you may need to regenerate the build system entirely.
|
||||
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
|
||||
|
||||
# Copyright (C) 2002-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_AUTOMAKE_VERSION(VERSION)
|
||||
# ----------------------------
|
||||
# Automake X.Y traces this macro to ensure aclocal.m4 has been
|
||||
# generated from the m4 files accompanying Automake X.Y.
|
||||
# (This private macro should not be called outside this file.)
|
||||
AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||
[am__api_version='1.15'
|
||||
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||
dnl require some minimum version. Point them to the right macro.
|
||||
m4_if([$1], [1.15], [],
|
||||
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||
])
|
||||
|
||||
# _AM_AUTOCONF_VERSION(VERSION)
|
||||
# -----------------------------
|
||||
# aclocal traces this macro to find the Autoconf version.
|
||||
# This is a private macro too. Using m4_define simplifies
|
||||
# the logic in aclocal, which can simply ignore this definition.
|
||||
m4_define([_AM_AUTOCONF_VERSION], [])
|
||||
|
||||
# AM_SET_CURRENT_AUTOMAKE_VERSION
|
||||
# -------------------------------
|
||||
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.15])dnl
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||
# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
|
||||
# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
|
||||
#
|
||||
# Of course, Automake must honor this variable whenever it calls a
|
||||
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||
# depending on how configure is run. This is pretty annoying, since
|
||||
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||
# source directory, any form will work fine, but in subdirectories a
|
||||
# relative path needs to be adjusted first.
|
||||
#
|
||||
# $ac_aux_dir/missing
|
||||
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||
# $top_srcdir/$ac_aux_dir/missing
|
||||
# fails if $ac_aux_dir is absolute,
|
||||
# fails when called from a subdirectory in a VPATH build with
|
||||
# a relative $ac_aux_dir
|
||||
#
|
||||
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||
# harmless because $srcdir is '.', but things will broke when you
|
||||
# start a VPATH build or use an absolute $srcdir.
|
||||
#
|
||||
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||
# and then we would define $MISSING as
|
||||
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||
# This will work as long as MISSING is not called from configure, because
|
||||
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||
# However there are other variables, like CC, which are often used in
|
||||
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||
#
|
||||
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||
# configured tree to be moved without reconfiguration.
|
||||
|
||||
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
||||
[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
|
||||
# Expand $ac_aux_dir to an absolute path.
|
||||
am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
||||
])
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||
# -------------------------------------
|
||||
# Define a conditional.
|
||||
AC_DEFUN([AM_CONDITIONAL],
|
||||
[AC_PREREQ([2.52])dnl
|
||||
m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||
AC_SUBST([$1_TRUE])dnl
|
||||
AC_SUBST([$1_FALSE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
|
||||
m4_define([_AM_COND_VALUE_$1], [$2])dnl
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
$1_FALSE='#'
|
||||
else
|
||||
$1_TRUE='#'
|
||||
$1_FALSE=
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||
AC_MSG_ERROR([[conditional "$1" was never defined.
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Do all the work for Automake. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This macro actually does too much. Some checks are only needed if
|
||||
# your package does certain things. But this isn't really a big deal.
|
||||
|
||||
dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
|
||||
m4_define([AC_PROG_CC],
|
||||
m4_defn([AC_PROG_CC])
|
||||
[_AM_PROG_CC_C_O
|
||||
])
|
||||
|
||||
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
|
||||
# AM_INIT_AUTOMAKE([OPTIONS])
|
||||
# -----------------------------------------------
|
||||
# The call with PACKAGE and VERSION arguments is the old style
|
||||
# call (pre autoconf-2.50), which is being phased out. PACKAGE
|
||||
# and VERSION should now be passed to AC_INIT and removed from
|
||||
# the call to AM_INIT_AUTOMAKE.
|
||||
# We support both call styles for the transition. After
|
||||
# the next Automake release, Autoconf can make the AC_INIT
|
||||
# arguments mandatory, and then we can depend on a new Autoconf
|
||||
# release and drop the old call support.
|
||||
AC_DEFUN([AM_INIT_AUTOMAKE],
|
||||
[AC_PREREQ([2.65])dnl
|
||||
dnl Autoconf wants to disallow AM_ names. We explicitly allow
|
||||
dnl the ones we care about.
|
||||
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
||||
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
|
||||
AC_REQUIRE([AC_PROG_INSTALL])dnl
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`"; then
|
||||
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
|
||||
# is not polluted with repeated "-I."
|
||||
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
|
||||
# test to see if srcdir already configured
|
||||
if test -f $srcdir/config.status; then
|
||||
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||
fi
|
||||
fi
|
||||
|
||||
# test whether we have cygpath
|
||||
if test -z "$CYGPATH_W"; then
|
||||
if (cygpath --version) >/dev/null 2>/dev/null; then
|
||||
CYGPATH_W='cygpath -w'
|
||||
else
|
||||
CYGPATH_W=echo
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([CYGPATH_W])
|
||||
|
||||
# Define the identity of the package.
|
||||
dnl Distinguish between old-style and new-style calls.
|
||||
m4_ifval([$2],
|
||||
[AC_DIAGNOSE([obsolete],
|
||||
[$0: two- and three-arguments forms are deprecated.])
|
||||
m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
||||
AC_SUBST([PACKAGE], [$1])dnl
|
||||
AC_SUBST([VERSION], [$2])],
|
||||
[_AM_SET_OPTIONS([$1])dnl
|
||||
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
|
||||
m4_if(
|
||||
m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
|
||||
[ok:ok],,
|
||||
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
|
||||
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
||||
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
|
||||
|
||||
_AM_IF_OPTION([no-define],,
|
||||
[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
|
||||
AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
|
||||
|
||||
# Some tools Automake needs.
|
||||
AC_REQUIRE([AM_SANITY_CHECK])dnl
|
||||
AC_REQUIRE([AC_ARG_PROGRAM])dnl
|
||||
AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
|
||||
AM_MISSING_PROG([AUTOCONF], [autoconf])
|
||||
AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
|
||||
AM_MISSING_PROG([AUTOHEADER], [autoheader])
|
||||
AM_MISSING_PROG([MAKEINFO], [makeinfo])
|
||||
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
|
||||
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
|
||||
# For better backward compatibility. To be removed once Automake 1.9.x
|
||||
# dies out for good. For more background, see:
|
||||
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
|
||||
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
|
||||
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
|
||||
# We need awk for the "check" target (and possibly the TAP driver). The
|
||||
# system "awk" is bad on some platforms.
|
||||
AC_REQUIRE([AC_PROG_AWK])dnl
|
||||
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
|
||||
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
|
||||
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
|
||||
[_AM_PROG_TAR([v7])])])
|
||||
_AM_IF_OPTION([no-dependencies],,
|
||||
[AC_PROVIDE_IFELSE([AC_PROG_CC],
|
||||
[_AM_DEPENDENCIES([CC])],
|
||||
[m4_define([AC_PROG_CC],
|
||||
m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_CXX],
|
||||
[_AM_DEPENDENCIES([CXX])],
|
||||
[m4_define([AC_PROG_CXX],
|
||||
m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
|
||||
[_AM_DEPENDENCIES([OBJC])],
|
||||
[m4_define([AC_PROG_OBJC],
|
||||
m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
|
||||
[_AM_DEPENDENCIES([OBJCXX])],
|
||||
[m4_define([AC_PROG_OBJCXX],
|
||||
m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
|
||||
])
|
||||
AC_REQUIRE([AM_SILENT_RULES])dnl
|
||||
dnl The testsuite driver may need to know about EXEEXT, so add the
|
||||
dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
|
||||
dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
|
||||
AC_CONFIG_COMMANDS_PRE(dnl
|
||||
[m4_provide_if([_AM_COMPILER_EXEEXT],
|
||||
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
|
||||
|
||||
# POSIX will say in a future version that running "rm -f" with no argument
|
||||
# is OK; and we want to be able to make that assumption in our Makefile
|
||||
# recipes. So use an aggressive probe to check that the usage we want is
|
||||
# actually supported "in the wild" to an acceptable degree.
|
||||
# See automake bug#10828.
|
||||
# To make any issue more visible, cause the running configure to be aborted
|
||||
# by default if the 'rm' program in use doesn't match our expectations; the
|
||||
# user can still override this though.
|
||||
if rm -f && rm -fr && rm -rf; then : OK; else
|
||||
cat >&2 <<'END'
|
||||
Oops!
|
||||
|
||||
Your 'rm' program seems unable to run without file operands specified
|
||||
on the command line, even when the '-f' option is present. This is contrary
|
||||
to the behaviour of most rm programs out there, and not conforming with
|
||||
the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
|
||||
|
||||
Please tell bug-automake@gnu.org about your system, including the value
|
||||
of your $PATH and any error possibly output before this message. This
|
||||
can help us improve future automake versions.
|
||||
|
||||
END
|
||||
if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
|
||||
echo 'Configuration will proceed anyway, since you have set the' >&2
|
||||
echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
|
||||
echo >&2
|
||||
else
|
||||
cat >&2 <<'END'
|
||||
Aborting the configuration process, to ensure you take notice of the issue.
|
||||
|
||||
You can download and install GNU coreutils to get an 'rm' implementation
|
||||
that behaves properly: <http://www.gnu.org/software/coreutils/>.
|
||||
|
||||
If you want to complete the configuration process using your problematic
|
||||
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
|
||||
to "yes", and re-run configure.
|
||||
|
||||
END
|
||||
AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
|
||||
fi
|
||||
fi
|
||||
dnl The trailing newline in this macro's definition is deliberate, for
|
||||
dnl backward compatibility and to allow trailing 'dnl'-style comments
|
||||
dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
|
||||
])
|
||||
|
||||
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
|
||||
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
|
||||
dnl mangled by Autoconf and run in a shell conditional statement.
|
||||
m4_define([_AC_COMPILER_EXEEXT],
|
||||
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
|
||||
|
||||
# When config.status generates a header, we must update the stamp-h file.
|
||||
# This file resides in the same directory as the config header
|
||||
# that is generated. The stamp files are numbered to have different names.
|
||||
|
||||
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||
# loop where config.status creates the headers, so we can generate
|
||||
# our stamp files there.
|
||||
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||
[# Compute $1's index in $config_headers.
|
||||
_am_arg=$1
|
||||
_am_stamp_count=1
|
||||
for _am_header in $config_headers :; do
|
||||
case $_am_header in
|
||||
$_am_arg | $_am_arg:* )
|
||||
break ;;
|
||||
* )
|
||||
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
|
||||
esac
|
||||
done
|
||||
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_SH
|
||||
# ------------------
|
||||
# Define $install_sh.
|
||||
AC_DEFUN([AM_PROG_INSTALL_SH],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
if test x"${install_sh+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
|
||||
*)
|
||||
install_sh="\${SHELL} $am_aux_dir/install-sh"
|
||||
esac
|
||||
fi
|
||||
AC_SUBST([install_sh])])
|
||||
|
||||
# Copyright (C) 2003-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# Check whether the underlying file-system supports filenames
|
||||
# with a leading dot. For instance MS-DOS doesn't.
|
||||
AC_DEFUN([AM_SET_LEADING_DOT],
|
||||
[rm -rf .tst 2>/dev/null
|
||||
mkdir .tst 2>/dev/null
|
||||
if test -d .tst; then
|
||||
am__leading_dot=.
|
||||
else
|
||||
am__leading_dot=_
|
||||
fi
|
||||
rmdir .tst 2>/dev/null
|
||||
AC_SUBST([am__leading_dot])])
|
||||
|
||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_MISSING_PROG(NAME, PROGRAM)
|
||||
# ------------------------------
|
||||
AC_DEFUN([AM_MISSING_PROG],
|
||||
[AC_REQUIRE([AM_MISSING_HAS_RUN])
|
||||
$1=${$1-"${am_missing_run}$2"}
|
||||
AC_SUBST($1)])
|
||||
|
||||
# AM_MISSING_HAS_RUN
|
||||
# ------------------
|
||||
# Define MISSING if not defined so far and test if it is modern enough.
|
||||
# If it is, set am_missing_run to use it, otherwise, to nothing.
|
||||
AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([missing])dnl
|
||||
if test x"${MISSING+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||
*)
|
||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||
esac
|
||||
fi
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --is-lightweight"; then
|
||||
am_missing_run="$MISSING "
|
||||
else
|
||||
am_missing_run=
|
||||
AC_MSG_WARN(['missing' script is too old or missing])
|
||||
fi
|
||||
])
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_MANGLE_OPTION(NAME)
|
||||
# -----------------------
|
||||
AC_DEFUN([_AM_MANGLE_OPTION],
|
||||
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
|
||||
|
||||
# _AM_SET_OPTION(NAME)
|
||||
# --------------------
|
||||
# Set option NAME. Presently that only means defining a flag for this option.
|
||||
AC_DEFUN([_AM_SET_OPTION],
|
||||
[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
|
||||
|
||||
# _AM_SET_OPTIONS(OPTIONS)
|
||||
# ------------------------
|
||||
# OPTIONS is a space-separated list of Automake options.
|
||||
AC_DEFUN([_AM_SET_OPTIONS],
|
||||
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
|
||||
|
||||
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
|
||||
# -------------------------------------------
|
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||
AC_DEFUN([_AM_IF_OPTION],
|
||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||
|
||||
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_PROG_CC_C_O
|
||||
# ---------------
|
||||
# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
|
||||
# to automatically call this.
|
||||
AC_DEFUN([_AM_PROG_CC_C_O],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([compile])dnl
|
||||
AC_LANG_PUSH([C])dnl
|
||||
AC_CACHE_CHECK(
|
||||
[whether $CC understands -c and -o together],
|
||||
[am_cv_prog_cc_c_o],
|
||||
[AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
|
||||
# Make sure it works both with $CC and with simple cc.
|
||||
# Following AC_PROG_CC_C_O, we do the test twice because some
|
||||
# compilers refuse to overwrite an existing .o file with -o,
|
||||
# though they will create one.
|
||||
am_cv_prog_cc_c_o=yes
|
||||
for am_i in 1 2; do
|
||||
if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
|
||||
&& test -f conftest2.$ac_objext; then
|
||||
: OK
|
||||
else
|
||||
am_cv_prog_cc_c_o=no
|
||||
break
|
||||
fi
|
||||
done
|
||||
rm -f core conftest*
|
||||
unset am_i])
|
||||
if test "$am_cv_prog_cc_c_o" != yes; then
|
||||
# Losing compiler, so override with the script.
|
||||
# FIXME: It is wrong to rewrite CC.
|
||||
# But if we don't then we get into trouble of one sort or another.
|
||||
# A longer-term fix would be to have automake use am__CC in this case,
|
||||
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
|
||||
CC="$am_aux_dir/compile $CC"
|
||||
fi
|
||||
AC_LANG_POP([C])])
|
||||
|
||||
# For backward compatibility.
|
||||
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_RUN_LOG(COMMAND)
|
||||
# -------------------
|
||||
# Run COMMAND, save the exit status in ac_status, and log it.
|
||||
# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
|
||||
AC_DEFUN([AM_RUN_LOG],
|
||||
[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
|
||||
($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
|
||||
(exit $ac_status); }])
|
||||
|
||||
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_SANITY_CHECK
|
||||
# ---------------
|
||||
AC_DEFUN([AM_SANITY_CHECK],
|
||||
[AC_MSG_CHECKING([whether build environment is sane])
|
||||
# Reject unsafe characters in $srcdir or the absolute working directory
|
||||
# name. Accept space and tab only in the latter.
|
||||
am_lf='
|
||||
'
|
||||
case `pwd` in
|
||||
*[[\\\"\#\$\&\'\`$am_lf]]*)
|
||||
AC_MSG_ERROR([unsafe absolute working directory name]);;
|
||||
esac
|
||||
case $srcdir in
|
||||
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
|
||||
AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
|
||||
esac
|
||||
|
||||
# Do 'set' in a subshell so we don't clobber the current shell's
|
||||
# arguments. Must try -L first in case configure is actually a
|
||||
# symlink; some systems play weird games with the mod time of symlinks
|
||||
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||
# directory).
|
||||
if (
|
||||
am_has_slept=no
|
||||
for am_try in 1 2; do
|
||||
echo "timestamp, slept: $am_has_slept" > conftest.file
|
||||
set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
|
||||
if test "$[*]" = "X"; then
|
||||
# -L didn't work.
|
||||
set X `ls -t "$srcdir/configure" conftest.file`
|
||||
fi
|
||||
if test "$[*]" != "X $srcdir/configure conftest.file" \
|
||||
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
|
||||
|
||||
# If neither matched, then we have a broken ls. This can happen
|
||||
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
||||
# broken ls alias from the environment. This has actually
|
||||
# happened. Such a system could not be considered "sane".
|
||||
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
||||
alias in your environment])
|
||||
fi
|
||||
if test "$[2]" = conftest.file || test $am_try -eq 2; then
|
||||
break
|
||||
fi
|
||||
# Just in case.
|
||||
sleep 1
|
||||
am_has_slept=yes
|
||||
done
|
||||
test "$[2]" = conftest.file
|
||||
)
|
||||
then
|
||||
# Ok.
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||
Check your system clock])
|
||||
fi
|
||||
AC_MSG_RESULT([yes])
|
||||
# If we didn't sleep, we still need to ensure time stamps of config.status and
|
||||
# generated files are strictly newer.
|
||||
am_sleep_pid=
|
||||
if grep 'slept: no' conftest.file >/dev/null 2>&1; then
|
||||
( sleep 1 ) &
|
||||
am_sleep_pid=$!
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[AC_MSG_CHECKING([that generated files are newer than configure])
|
||||
if test -n "$am_sleep_pid"; then
|
||||
# Hide warnings about reused PIDs.
|
||||
wait $am_sleep_pid 2>/dev/null
|
||||
fi
|
||||
AC_MSG_RESULT([done])])
|
||||
rm -f conftest.file
|
||||
])
|
||||
|
||||
# Copyright (C) 2009-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_SILENT_RULES([DEFAULT])
|
||||
# --------------------------
|
||||
# Enable less verbose build rules; with the default set to DEFAULT
|
||||
# ("yes" being less verbose, "no" or empty being verbose).
|
||||
AC_DEFUN([AM_SILENT_RULES],
|
||||
[AC_ARG_ENABLE([silent-rules], [dnl
|
||||
AS_HELP_STRING(
|
||||
[--enable-silent-rules],
|
||||
[less verbose build output (undo: "make V=1")])
|
||||
AS_HELP_STRING(
|
||||
[--disable-silent-rules],
|
||||
[verbose build output (undo: "make V=0")])dnl
|
||||
])
|
||||
case $enable_silent_rules in @%:@ (((
|
||||
yes) AM_DEFAULT_VERBOSITY=0;;
|
||||
no) AM_DEFAULT_VERBOSITY=1;;
|
||||
*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
|
||||
esac
|
||||
dnl
|
||||
dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
|
||||
dnl do not support nested variable expansions.
|
||||
dnl See automake bug#9928 and bug#10237.
|
||||
am_make=${MAKE-make}
|
||||
AC_CACHE_CHECK([whether $am_make supports nested variables],
|
||||
[am_cv_make_support_nested_variables],
|
||||
[if AS_ECHO([['TRUE=$(BAR$(V))
|
||||
BAR0=false
|
||||
BAR1=true
|
||||
V=1
|
||||
am__doit:
|
||||
@$(TRUE)
|
||||
.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
|
||||
am_cv_make_support_nested_variables=yes
|
||||
else
|
||||
am_cv_make_support_nested_variables=no
|
||||
fi])
|
||||
if test $am_cv_make_support_nested_variables = yes; then
|
||||
dnl Using '$V' instead of '$(V)' breaks IRIX make.
|
||||
AM_V='$(V)'
|
||||
AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
|
||||
else
|
||||
AM_V=$AM_DEFAULT_VERBOSITY
|
||||
AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
|
||||
fi
|
||||
AC_SUBST([AM_V])dnl
|
||||
AM_SUBST_NOTMAKE([AM_V])dnl
|
||||
AC_SUBST([AM_DEFAULT_V])dnl
|
||||
AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
|
||||
AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
|
||||
AM_BACKSLASH='\'
|
||||
AC_SUBST([AM_BACKSLASH])dnl
|
||||
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
|
||||
])
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_STRIP
|
||||
# ---------------------
|
||||
# One issue with vendor 'install' (even GNU) is that you can't
|
||||
# specify the program used to strip binaries. This is especially
|
||||
# annoying in cross-compiling environments, where the build's strip
|
||||
# is unlikely to handle the host's binaries.
|
||||
# Fortunately install-sh will honor a STRIPPROG variable, so we
|
||||
# always use install-sh in "make install-strip", and initialize
|
||||
# STRIPPROG with the value of the STRIP variable (set by the user).
|
||||
AC_DEFUN([AM_PROG_INSTALL_STRIP],
|
||||
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
# Installed binaries are usually stripped using 'strip' when the user
|
||||
# run "make install-strip". However 'strip' might not be the right
|
||||
# tool to use in cross-compilation environments, therefore Automake
|
||||
# will honor the 'STRIP' environment variable to overrule this program.
|
||||
dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
|
||||
if test "$cross_compiling" != no; then
|
||||
AC_CHECK_TOOL([STRIP], [strip], :)
|
||||
fi
|
||||
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||
|
||||
# Copyright (C) 2006-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# ---------------------------
|
||||
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
|
||||
# This macro is traced by Automake.
|
||||
AC_DEFUN([_AM_SUBST_NOTMAKE])
|
||||
|
||||
# AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# --------------------------
|
||||
# Public sister of _AM_SUBST_NOTMAKE.
|
||||
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||
|
||||
# Check how to create a tarball. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2004-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_PROG_TAR(FORMAT)
|
||||
# --------------------
|
||||
# Check how to create a tarball in format FORMAT.
|
||||
# FORMAT should be one of 'v7', 'ustar', or 'pax'.
|
||||
#
|
||||
# Substitute a variable $(am__tar) that is a command
|
||||
# writing to stdout a FORMAT-tarball containing the directory
|
||||
# $tardir.
|
||||
# tardir=directory && $(am__tar) > result.tar
|
||||
#
|
||||
# Substitute a variable $(am__untar) that extract such
|
||||
# a tarball read from stdin.
|
||||
# $(am__untar) < result.tar
|
||||
#
|
||||
AC_DEFUN([_AM_PROG_TAR],
|
||||
[# Always define AMTAR for backward compatibility. Yes, it's still used
|
||||
# in the wild :-( We should find a proper way to deprecate it ...
|
||||
AC_SUBST([AMTAR], ['$${TAR-tar}'])
|
||||
|
||||
# We'll loop over all known methods to create a tar archive until one works.
|
||||
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
|
||||
|
||||
m4_if([$1], [v7],
|
||||
[am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
|
||||
|
||||
[m4_case([$1],
|
||||
[ustar],
|
||||
[# The POSIX 1988 'ustar' format is defined with fixed-size fields.
|
||||
# There is notably a 21 bits limit for the UID and the GID. In fact,
|
||||
# the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
|
||||
# and bug#13588).
|
||||
am_max_uid=2097151 # 2^21 - 1
|
||||
am_max_gid=$am_max_uid
|
||||
# The $UID and $GID variables are not portable, so we need to resort
|
||||
# to the POSIX-mandated id(1) utility. Errors in the 'id' calls
|
||||
# below are definitely unexpected, so allow the users to see them
|
||||
# (that is, avoid stderr redirection).
|
||||
am_uid=`id -u || echo unknown`
|
||||
am_gid=`id -g || echo unknown`
|
||||
AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
|
||||
if test $am_uid -le $am_max_uid; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
_am_tools=none
|
||||
fi
|
||||
AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
|
||||
if test $am_gid -le $am_max_gid; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
_am_tools=none
|
||||
fi],
|
||||
|
||||
[pax],
|
||||
[],
|
||||
|
||||
[m4_fatal([Unknown tar format])])
|
||||
|
||||
AC_MSG_CHECKING([how to create a $1 tar archive])
|
||||
|
||||
# Go ahead even if we have the value already cached. We do so because we
|
||||
# need to set the values for the 'am__tar' and 'am__untar' variables.
|
||||
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
|
||||
|
||||
for _am_tool in $_am_tools; do
|
||||
case $_am_tool in
|
||||
gnutar)
|
||||
for _am_tar in tar gnutar gtar; do
|
||||
AM_RUN_LOG([$_am_tar --version]) && break
|
||||
done
|
||||
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
|
||||
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
|
||||
am__untar="$_am_tar -xf -"
|
||||
;;
|
||||
plaintar)
|
||||
# Must skip GNU tar: if it does not support --format= it doesn't create
|
||||
# ustar tarball either.
|
||||
(tar --version) >/dev/null 2>&1 && continue
|
||||
am__tar='tar chf - "$$tardir"'
|
||||
am__tar_='tar chf - "$tardir"'
|
||||
am__untar='tar xf -'
|
||||
;;
|
||||
pax)
|
||||
am__tar='pax -L -x $1 -w "$$tardir"'
|
||||
am__tar_='pax -L -x $1 -w "$tardir"'
|
||||
am__untar='pax -r'
|
||||
;;
|
||||
cpio)
|
||||
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
|
||||
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
|
||||
am__untar='cpio -i -H $1 -d'
|
||||
;;
|
||||
none)
|
||||
am__tar=false
|
||||
am__tar_=false
|
||||
am__untar=false
|
||||
;;
|
||||
esac
|
||||
|
||||
# If the value was cached, stop now. We just wanted to have am__tar
|
||||
# and am__untar set.
|
||||
test -n "${am_cv_prog_tar_$1}" && break
|
||||
|
||||
# tar/untar a dummy directory, and stop if the command works.
|
||||
rm -rf conftest.dir
|
||||
mkdir conftest.dir
|
||||
echo GrepMe > conftest.dir/file
|
||||
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
|
||||
rm -rf conftest.dir
|
||||
if test -s conftest.tar; then
|
||||
AM_RUN_LOG([$am__untar <conftest.tar])
|
||||
AM_RUN_LOG([cat conftest.dir/file])
|
||||
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
|
||||
fi
|
||||
done
|
||||
rm -rf conftest.dir
|
||||
|
||||
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
|
||||
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
|
||||
|
||||
AC_SUBST([am__tar])
|
||||
AC_SUBST([am__untar])
|
||||
]) # _AM_PROG_TAR
|
||||
|
||||
m4_include([acinclude.m4])
|
@ -1896,7 +1896,7 @@ bail:
|
||||
if (error && !fix)
|
||||
log_fatal("WARNING! There are errors!\n");
|
||||
if (unrecoverable_error)
|
||||
log_fatal("DANGER! There are unrecoverable errors!\n");
|
||||
log_fatal("DANGER! Unrecoverable errors detected!\n");
|
||||
|
||||
log_tag("summary:error:%u\n", error);
|
||||
if (fix)
|
||||
@ -1974,7 +1974,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
|
||||
|
||||
if (blockstart > blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
|
||||
log_fatal("Error in the specified starting block %u. It's larger than the parity size %u.\n", blockstart, blockmax);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
@ -403,7 +403,7 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
||||
|
||||
if (blockstart > blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
|
||||
log_fatal("Error in the specified starting block %u. It's larger than the parity size %u.\n", blockstart, blockmax);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
@ -435,21 +435,21 @@ void file_copy(struct snapraid_file* src_file, struct snapraid_file* dst_file)
|
||||
|
||||
if (src_file->size != dst_file->size) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in copy file with different size\n");
|
||||
log_fatal("Internal inconsistency: Copy file with different size\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (src_file->mtime_sec != dst_file->mtime_sec) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in copy file with different mtime_sec\n");
|
||||
log_fatal("Internal inconsistency: Copy file with different mtime_sec\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (src_file->mtime_nsec != dst_file->mtime_nsec) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in copy file with different mtime_nsec\n");
|
||||
log_fatal("Internal inconsistency: Copy file with different mtime_nsec\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -499,7 +499,7 @@ int file_block_is_last(struct snapraid_file* file, block_off_t file_pos)
|
||||
|
||||
if (file_pos >= file->blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in file block position\n");
|
||||
log_fatal("Internal inconsistency: File block position over the max\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -620,13 +620,13 @@ struct snapraid_extent* extent_alloc(block_off_t parity_pos, struct snapraid_fil
|
||||
|
||||
if (count == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when allocating empty extent for file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax);
|
||||
log_fatal("Internal inconsistency: Allocating empty extent for file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (file_pos + count > file->blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when allocating overflowing extent for file '%s' at position '%u:%u/%u'\n", file->sub, file_pos, count, file->blockmax);
|
||||
log_fatal("Internal inconsistency: Allocating overflowing extent for file '%s' at position '%u:%u/%u'\n", file->sub, file_pos, count, file->blockmax);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -938,7 +938,7 @@ static void extent_parity_check_foreach_unlock(void* void_arg, void* void_obj)
|
||||
|
||||
if (obj->count == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in parity count zero for file '%s' at '%u'\n",
|
||||
log_fatal("Internal inconsistency: Parity count zero for file '%s' at '%u'\n",
|
||||
obj->file->sub, obj->parity_pos);
|
||||
++arg->result;
|
||||
return;
|
||||
@ -952,7 +952,7 @@ static void extent_parity_check_foreach_unlock(void* void_arg, void* void_obj)
|
||||
/* check the order */
|
||||
if (prev->parity_pos >= obj->parity_pos) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in parity order for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
|
||||
log_fatal("Internal inconsistency: Parity order for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
|
||||
prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count);
|
||||
++arg->result;
|
||||
return;
|
||||
@ -962,7 +962,7 @@ static void extent_parity_check_foreach_unlock(void* void_arg, void* void_obj)
|
||||
/* check that the extents don't overlap */
|
||||
if (prev->parity_pos + prev->count > obj->parity_pos) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency for parity overlap for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
|
||||
log_fatal("Internal inconsistency: Parity overlap for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
|
||||
prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count);
|
||||
++arg->result;
|
||||
return;
|
||||
@ -988,7 +988,7 @@ static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
|
||||
|
||||
if (obj->count == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in file count zero for file '%s' at '%u'\n",
|
||||
log_fatal("Internal inconsistency: File count zero for file '%s' at '%u'\n",
|
||||
obj->file->sub, obj->file_pos);
|
||||
++arg->result;
|
||||
return;
|
||||
@ -1004,7 +1004,7 @@ static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
|
||||
/* check that the extent doesn't overflow the file */
|
||||
if (prev->file_pos + prev->count > prev->file->blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in delete end for file '%s' at '%u:%u' overflowing size '%u'\n",
|
||||
log_fatal("Internal inconsistency: Delete end for file '%s' at '%u:%u' overflowing size '%u'\n",
|
||||
prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax);
|
||||
++arg->result;
|
||||
return;
|
||||
@ -1014,7 +1014,7 @@ static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
|
||||
/* check that the extent ends the file */
|
||||
if (prev->file_pos + prev->count != prev->file->blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in file end for file '%s' at '%u:%u' instead of size '%u'\n",
|
||||
log_fatal("Internal inconsistency: File end for file '%s' at '%u:%u' instead of size '%u'\n",
|
||||
prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax);
|
||||
++arg->result;
|
||||
return;
|
||||
@ -1027,7 +1027,7 @@ static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
|
||||
/* check that the extent doesn't overflow the file */
|
||||
if (obj->file_pos + obj->count > obj->file->blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in delete start for file '%s' at '%u:%u' overflowing size '%u'\n",
|
||||
log_fatal("Internal inconsistency: Delete start for file '%s' at '%u:%u' overflowing size '%u'\n",
|
||||
obj->file->sub, obj->file_pos, obj->count, obj->file->blockmax);
|
||||
++arg->result;
|
||||
return;
|
||||
@ -1037,7 +1037,7 @@ static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
|
||||
/* check that the extent starts the file */
|
||||
if (obj->file_pos != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in file start for file '%s' at '%u:%u'\n",
|
||||
log_fatal("Internal inconsistency: File start for file '%s' at '%u:%u'\n",
|
||||
obj->file->sub, obj->file_pos, obj->count);
|
||||
++arg->result;
|
||||
return;
|
||||
@ -1048,7 +1048,7 @@ static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
|
||||
/* check the order */
|
||||
if (prev->file_pos >= obj->file_pos) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in file order for file '%s' at '%u:%u' and at '%u:%u'\n",
|
||||
log_fatal("Internal inconsistency: File order for file '%s' at '%u:%u' and at '%u:%u'\n",
|
||||
prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
|
||||
++arg->result;
|
||||
return;
|
||||
@ -1059,7 +1059,7 @@ static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
|
||||
/* check that the extents don't overlap */
|
||||
if (prev->file_pos + prev->count > obj->file_pos) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in delete sequence for file '%s' at '%u:%u' and at '%u:%u'\n",
|
||||
log_fatal("Internal inconsistency: Delete sequence for file '%s' at '%u:%u' and at '%u:%u'\n",
|
||||
prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
|
||||
++arg->result;
|
||||
return;
|
||||
@ -1069,7 +1069,7 @@ static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
|
||||
/* check that the extents are sequential */
|
||||
if (prev->file_pos + prev->count != obj->file_pos) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in file sequence for file '%s' at '%u:%u' and at '%u:%u'\n",
|
||||
log_fatal("Internal inconsistency: File sequence for file '%s' at '%u:%u' and at '%u:%u'\n",
|
||||
prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
|
||||
++arg->result;
|
||||
return;
|
||||
@ -1267,7 +1267,7 @@ void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snap
|
||||
/* ensure that we are extending the extent at the end */
|
||||
if (file_pos != extent->file_pos + extent->count) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when allocating file '%s' at position '%u/%u' in the middle of extent '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, extent->file_pos, extent->count, disk->name);
|
||||
log_fatal("Internal inconsistency: Allocating file '%s' at position '%u/%u' in the middle of extent '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, extent->file_pos, extent->count, disk->name);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1289,7 +1289,7 @@ void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snap
|
||||
|
||||
if (parity_extent != extent || file_extent != extent) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when allocating file '%s' at position '%u/%u' for existing extent '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, extent->file_pos, extent->count, disk->name);
|
||||
log_fatal("Internal inconsistency: Allocating file '%s' at position '%u/%u' for existing extent '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, extent->file_pos, extent->count, disk->name);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1313,7 +1313,7 @@ void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos)
|
||||
extent = fs_par2extent_get_unlock(disk, &disk->fs_last, parity_pos);
|
||||
if (!extent) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when deallocating parity position '%u' for not existing extent in disk '%s'\n", parity_pos, disk->name);
|
||||
log_fatal("Internal inconsistency: Deallocating parity position '%u' for not existing extent in disk '%s'\n", parity_pos, disk->name);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1368,7 +1368,7 @@ void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos)
|
||||
|
||||
if (parity_extent != second_extent || file_extent != second_extent) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when deallocating parity position '%u' for splitting extent '%u:%u' in disk '%s'\n", parity_pos, second_extent->file_pos, second_extent->count, disk->name);
|
||||
log_fatal("Internal inconsistency: Deallocating parity position '%u' for splitting extent '%u:%u' in disk '%s'\n", parity_pos, second_extent->file_pos, second_extent->count, disk->name);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1383,7 +1383,7 @@ struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t
|
||||
{
|
||||
if (file_pos >= file->blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when dereferencing file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax);
|
||||
log_fatal("Internal inconsistency: Dereferencing file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
@ -369,6 +369,13 @@ struct snapraid_disk {
|
||||
*/
|
||||
thread_mutex_t fs_mutex;
|
||||
int fs_mutex_enabled; /*< If the lock has to be used. */
|
||||
|
||||
/**
|
||||
* Mutex for protecting the scan process.
|
||||
*
|
||||
* It's used during the scan process to protect the stampset to identity copy of files
|
||||
*/
|
||||
thread_mutex_t stamp_mutex;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -1041,7 +1048,7 @@ static inline struct snapraid_file* fs_par2file_get(struct snapraid_disk* disk,
|
||||
ret = fs_par2file_find(disk, parity_pos, file_pos);
|
||||
if (ret == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when deresolving parity to file at position '%u' in disk '%s'\n", parity_pos, disk->name);
|
||||
log_fatal("Internal inconsistency: Deresolving parity to file at position '%u' in disk '%s'\n", parity_pos, disk->name);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1065,7 +1072,7 @@ static inline block_off_t fs_file2par_get(struct snapraid_disk* disk, struct sna
|
||||
ret = fs_file2par_find(disk, file, file_pos);
|
||||
if (ret == POS_NULL) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when resolving file '%s' at position '%u/%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, disk->name);
|
||||
log_fatal("Internal inconsistency: Resolving file '%s' at position '%u/%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, disk->name);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1089,7 +1096,7 @@ static inline struct snapraid_block* fs_par2block_get(struct snapraid_disk* disk
|
||||
ret = fs_par2block_find(disk, parity_pos);
|
||||
if (ret == BLOCK_NULL) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when deresolving parity to block at position '%u' in disk '%s'\n", parity_pos, disk->name);
|
||||
log_fatal("Internal inconsistency: Deresolving parity to block at position '%u' in disk '%s'\n", parity_pos, disk->name);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
@ -879,9 +879,9 @@ void io_init(struct snapraid_io* io, struct snapraid_state* state,
|
||||
|
||||
#if HAVE_THREAD
|
||||
if (io_cache == 0) {
|
||||
/* default is 8 MiB of cache */
|
||||
/* default is 16 MiB of cache */
|
||||
/* this seems to be a good tradeoff between speed and memory usage */
|
||||
io->io_max = 8 * 1024 * 1024 / state->block_size;
|
||||
io->io_max = 16 * 1024 * 1024 / state->block_size;
|
||||
if (io->io_max < IO_MIN)
|
||||
io->io_max = IO_MIN;
|
||||
if (io->io_max > IO_MAX)
|
||||
|
@ -35,8 +35,8 @@
|
||||
* 4 - 452 MB/s, CPU 54%, speed 118%
|
||||
* 8 - 487 MB/s, CPU 60%, speed 128%
|
||||
* 16 - 505 MB/s, CPU 63%, speed 132%
|
||||
* 32 - 520 MB/s, CPU 64%, speed 136%
|
||||
* 64 - 524 MB/s, CPU 65%, speed 137%
|
||||
* 32 - 520 MB/s, CPU 64%, speed 136% [SnapRAID <= 12.0]
|
||||
* 64 - 524 MB/s, CPU 65%, speed 137% [SnapRAID > 12.0]
|
||||
* 128 - 525 MB/s, CPU 66%, speed 138%
|
||||
*/
|
||||
#define IO_MIN 3 /* required by writers, readers can work also with 2 */
|
||||
|
@ -31,14 +31,26 @@ int exit_sync_needed = 2;
|
||||
/* Add missing Windows declaration */
|
||||
|
||||
/* For SetThreadExecutionState */
|
||||
#ifndef WIN32_ES_SYSTEM_REQUIRED
|
||||
#define WIN32_ES_SYSTEM_REQUIRED 0x00000001L
|
||||
#endif
|
||||
#ifndef WIN32_ES_DISPLAY_REQUIRED
|
||||
#define WIN32_ES_DISPLAY_REQUIRED 0x00000002L
|
||||
#endif
|
||||
#ifndef WIN32_ES_USER_PRESENT
|
||||
#define WIN32_ES_USER_PRESENT 0x00000004L
|
||||
#endif
|
||||
#ifndef WIN32_ES_AWAYMODE_REQUIRED
|
||||
#define WIN32_ES_AWAYMODE_REQUIRED 0x00000040L
|
||||
#endif
|
||||
#ifndef WIN32_ES_CONTINUOUS
|
||||
#define WIN32_ES_CONTINUOUS 0x80000000L
|
||||
#endif
|
||||
|
||||
/* File Index */
|
||||
#ifndef FILE_INVALID_FILE_ID
|
||||
#define FILE_INVALID_FILE_ID ((ULONGLONG)-1LL)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Direct access to RtlGenRandom().
|
||||
@ -475,7 +487,7 @@ static void windows_attr2stat(DWORD FileAttributes, DWORD ReparseTag, struct win
|
||||
*/
|
||||
static int windows_info2stat(const BY_HANDLE_FILE_INFORMATION* info, const FILE_ATTRIBUTE_TAG_INFO* tag, struct windows_stat* st)
|
||||
{
|
||||
uint64_t mtime;
|
||||
int64_t mtime;
|
||||
|
||||
windows_attr2stat(info->dwFileAttributes, tag->ReparseTag, st);
|
||||
|
||||
@ -518,7 +530,7 @@ static int windows_info2stat(const BY_HANDLE_FILE_INFORMATION* info, const FILE_
|
||||
* "that includes 128-bit file identifiers. If GetFileInformationByHandle returns"
|
||||
* "FILE_INVALID_FILE_ID, the identifier may only be described in 128 bit form."
|
||||
*/
|
||||
if (st->st_ino == FILE_INVALID_FILE_ID) {
|
||||
if (st->st_ino == (uint64_t)FILE_INVALID_FILE_ID) {
|
||||
log_fatal("Invalid inode number! Is this ReFS?\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
@ -532,7 +544,7 @@ static int windows_info2stat(const BY_HANDLE_FILE_INFORMATION* info, const FILE_
|
||||
*/
|
||||
static int windows_stream2stat(const BY_HANDLE_FILE_INFORMATION* info, const FILE_ID_BOTH_DIR_INFO* stream, struct windows_stat* st)
|
||||
{
|
||||
uint64_t mtime;
|
||||
int64_t mtime;
|
||||
|
||||
/* The FILE_ID_BOTH_DIR_INFO doesn't have the ReparseTag information */
|
||||
/* we could use instead FILE_ID_EXTD_DIR_INFO, but it's available only */
|
||||
@ -563,7 +575,7 @@ static int windows_stream2stat(const BY_HANDLE_FILE_INFORMATION* info, const FIL
|
||||
st->st_sync = 0;
|
||||
|
||||
/* in ReFS the IDs are 128 bit, and the 64 bit interface may fail */
|
||||
if (st->st_ino == FILE_INVALID_FILE_ID) {
|
||||
if (st->st_ino == (uint64_t)FILE_INVALID_FILE_ID) {
|
||||
log_fatal("Invalid inode number! Is this ReFS?\n");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
@ -577,7 +589,7 @@ static int windows_stream2stat(const BY_HANDLE_FILE_INFORMATION* info, const FIL
|
||||
*/
|
||||
static void windows_finddata2stat(const WIN32_FIND_DATAW* info, struct windows_stat* st)
|
||||
{
|
||||
uint64_t mtime;
|
||||
int64_t mtime;
|
||||
|
||||
windows_attr2stat(info->dwFileAttributes, info->dwReserved0, st);
|
||||
|
||||
@ -789,7 +801,7 @@ static BOOL GetFilePhysicalOffset(HANDLE h, uint64_t* physical)
|
||||
BOOL ret;
|
||||
DWORD n;
|
||||
|
||||
/* in Wine FSCTL_GET_RETRIVIAL_POINTERS is not supported */
|
||||
/* in Wine FSCTL_GET_RETRIEVAL_POINTERS is not supported */
|
||||
if (is_wine) {
|
||||
*physical = FILEPHY_UNREPORTED_OFFSET;
|
||||
return TRUE;
|
||||
@ -1039,7 +1051,7 @@ int windows_futimens(int fd, struct windows_timespec tv[2])
|
||||
{
|
||||
HANDLE h;
|
||||
FILETIME ft;
|
||||
uint64_t mtime;
|
||||
int64_t mtime;
|
||||
|
||||
if (fd == -1) {
|
||||
errno = EBADF;
|
||||
@ -1061,7 +1073,7 @@ int windows_futimens(int fd, struct windows_timespec tv[2])
|
||||
mtime = tv[0].tv_sec;
|
||||
mtime *= 10000000;
|
||||
mtime += tv[0].tv_nsec / 100;
|
||||
mtime += 116444736000000000;
|
||||
mtime += 116444736000000000LL;
|
||||
|
||||
ft.dwHighDateTime = mtime >> 32;
|
||||
ft.dwLowDateTime = mtime;
|
||||
@ -1079,7 +1091,7 @@ int windows_utimensat(int fd, const char* file, struct windows_timespec tv[2], i
|
||||
wchar_t conv_buf[CONV_MAX];
|
||||
HANDLE h;
|
||||
FILETIME ft;
|
||||
uint64_t mtime;
|
||||
int64_t mtime;
|
||||
DWORD wflags;
|
||||
|
||||
/*
|
||||
@ -1119,7 +1131,7 @@ int windows_utimensat(int fd, const char* file, struct windows_timespec tv[2], i
|
||||
mtime = tv[0].tv_sec;
|
||||
mtime *= 10000000;
|
||||
mtime += tv[0].tv_nsec / 100;
|
||||
mtime += 116444736000000000;
|
||||
mtime += 116444736000000000LL;
|
||||
|
||||
ft.dwHighDateTime = mtime >> 32;
|
||||
ft.dwLowDateTime = mtime;
|
||||
@ -1556,7 +1568,7 @@ int windows_link(const char* existing, const char* file)
|
||||
}
|
||||
|
||||
/**
|
||||
* In Windows 10 allow creation of symblink by not privileged user.
|
||||
* In Windows 10 allow creation of symlink by not privileged user.
|
||||
*
|
||||
* See: Symlinks in Windows 10!
|
||||
* https://blogs.windows.com/buildingapps/2016/12/02/symlinks-windows-10/#cQG7cx48oGH86lkI.97
|
||||
|
@ -152,8 +152,8 @@ void parity_overflow(struct snapraid_state* state, data_off_t size)
|
||||
}
|
||||
|
||||
if (found) {
|
||||
log_fatal("\nYour data requires more parity than the available space.\n");
|
||||
log_fatal("Please move the files 'outofparity' to another data disk.\n");
|
||||
log_fatal("\nInsufficient parity space. Data requires more parity than available.\n");
|
||||
log_fatal("Move the 'outofparity' files to a larger disk.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,7 +362,7 @@ int devuuid(uint64_t device, char* uuid, size_t size);
|
||||
#define FILEPHY_REAL_OFFSET 3
|
||||
|
||||
/**
|
||||
* Get the physcal address of the specified file.
|
||||
* Get the physical address of the specified file.
|
||||
* This is expected to be just a hint and not necessarily correct or unique.
|
||||
* Return 0 on success.
|
||||
*/
|
||||
|
370
cmdline/scan.c
370
cmdline/scan.c
@ -25,6 +25,17 @@
|
||||
struct snapraid_scan {
|
||||
struct snapraid_state* state; /**< State used. */
|
||||
struct snapraid_disk* disk; /**< Disk used. */
|
||||
thread_id_t thread; /**< Thread used for scanning the disk */
|
||||
|
||||
int is_diff; /**< If it's a diff command or a scanning */
|
||||
int need_write; /**< If a state write is required */
|
||||
|
||||
#if HAVE_THREAD
|
||||
/**
|
||||
* Mutex for protecting the disk stampset table
|
||||
*/
|
||||
thread_mutex_t mutex;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Counters of changes.
|
||||
@ -45,16 +56,69 @@ struct snapraid_scan {
|
||||
tommy_node node;
|
||||
};
|
||||
|
||||
static struct snapraid_scan* scan_alloc(struct snapraid_state* state, struct snapraid_disk* disk, int is_diff)
|
||||
{
|
||||
struct snapraid_scan* scan;
|
||||
|
||||
scan = malloc_nofail(sizeof(struct snapraid_scan));
|
||||
scan->state = state;
|
||||
scan->disk = disk;
|
||||
scan->count_equal = 0;
|
||||
scan->count_move = 0;
|
||||
scan->count_copy = 0;
|
||||
scan->count_restore = 0;
|
||||
scan->count_change = 0;
|
||||
scan->count_remove = 0;
|
||||
scan->count_insert = 0;
|
||||
tommy_list_init(&scan->file_insert_list);
|
||||
tommy_list_init(&scan->link_insert_list);
|
||||
tommy_list_init(&scan->dir_insert_list);
|
||||
scan->is_diff = is_diff;
|
||||
scan->need_write = 0;
|
||||
|
||||
#if HAVE_THREAD
|
||||
thread_mutex_init(&disk->stamp_mutex);
|
||||
#endif
|
||||
|
||||
return scan;
|
||||
}
|
||||
|
||||
static void scan_free(struct snapraid_scan* scan)
|
||||
{
|
||||
#if HAVE_THREAD
|
||||
thread_mutex_destroy(&scan->disk->stamp_mutex);
|
||||
#endif
|
||||
|
||||
free(scan);
|
||||
}
|
||||
|
||||
static void stamp_lock(struct snapraid_disk* disk)
|
||||
{
|
||||
#if HAVE_THREAD
|
||||
thread_mutex_lock(&disk->stamp_mutex);
|
||||
#else
|
||||
(void)disk;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void stamp_unlock(struct snapraid_disk* disk)
|
||||
{
|
||||
#if HAVE_THREAD
|
||||
thread_mutex_unlock(&disk->stamp_mutex);
|
||||
#else
|
||||
(void)disk;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified link from the data set.
|
||||
*/
|
||||
static void scan_link_remove(struct snapraid_scan* scan, struct snapraid_link* slink)
|
||||
{
|
||||
struct snapraid_state* state = scan->state;
|
||||
struct snapraid_disk* disk = scan->disk;
|
||||
|
||||
/* state changed */
|
||||
state->need_write = 1;
|
||||
scan->need_write = 1;
|
||||
|
||||
/* remove the file from the link containers */
|
||||
tommy_hashdyn_remove_existing(&disk->linkset, &slink->nodeset);
|
||||
@ -69,11 +133,10 @@ static void scan_link_remove(struct snapraid_scan* scan, struct snapraid_link* s
|
||||
*/
|
||||
static void scan_link_insert(struct snapraid_scan* scan, struct snapraid_link* slink)
|
||||
{
|
||||
struct snapraid_state* state = scan->state;
|
||||
struct snapraid_disk* disk = scan->disk;
|
||||
|
||||
/* state changed */
|
||||
state->need_write = 1;
|
||||
scan->need_write = 1;
|
||||
|
||||
/* insert the link in the link containers */
|
||||
tommy_hashdyn_insert(&disk->linkset, &slink->nodeset, slink, link_name_hash(slink->sub));
|
||||
@ -116,13 +179,13 @@ static void scan_link(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
/* it's an update */
|
||||
|
||||
/* we have to save the linkto/type */
|
||||
state->need_write = 1;
|
||||
scan->need_write = 1;
|
||||
|
||||
++scan->count_change;
|
||||
|
||||
log_tag("scan:update:%s:%s\n", disk->name, esc_tag(slink->sub, esc_buffer));
|
||||
if (is_diff) {
|
||||
printf("update %s\n", fmt_term(disk, slink->sub, esc_buffer));
|
||||
msg_info("update %s\n", fmt_term(disk, slink->sub, esc_buffer));
|
||||
}
|
||||
|
||||
/* update it */
|
||||
@ -139,7 +202,7 @@ static void scan_link(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
|
||||
log_tag("scan:add:%s:%s\n", disk->name, esc_tag(sub, esc_buffer));
|
||||
if (is_diff) {
|
||||
printf("add %s\n", fmt_term(disk, sub, esc_buffer));
|
||||
msg_info("add %s\n", fmt_term(disk, sub, esc_buffer));
|
||||
}
|
||||
|
||||
/* and continue to insert it */
|
||||
@ -166,7 +229,7 @@ static void scan_file_allocate(struct snapraid_scan* scan, struct snapraid_file*
|
||||
block_off_t parity_pos;
|
||||
|
||||
/* state changed */
|
||||
state->need_write = 1;
|
||||
scan->need_write = 1;
|
||||
|
||||
/* allocate the blocks of the file */
|
||||
parity_pos = disk->first_free_block;
|
||||
@ -267,7 +330,7 @@ static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_fil
|
||||
tommy_list_remove_existing(&disk->filelist, &file->nodelist);
|
||||
|
||||
/* state changed */
|
||||
state->need_write = 1;
|
||||
scan->need_write = 1;
|
||||
|
||||
/* here we are supposed to adjust the ::first_free_block position */
|
||||
/* with the parity position we are deleting */
|
||||
@ -563,8 +626,11 @@ static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* f
|
||||
/* insert the file in the containers */
|
||||
if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
|
||||
tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
|
||||
|
||||
stamp_lock(disk);
|
||||
tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
|
||||
tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec));
|
||||
stamp_unlock(disk);
|
||||
|
||||
/* delayed allocation of the parity */
|
||||
scan_file_delayed_allocate(scan, file);
|
||||
@ -583,7 +649,10 @@ static void scan_file_remove(struct snapraid_scan* scan, struct snapraid_file* f
|
||||
if (!file_flag_has(file, FILE_IS_WITHOUT_INODE))
|
||||
tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
|
||||
tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset);
|
||||
|
||||
stamp_lock(disk);
|
||||
tommy_hashdyn_remove_existing(&disk->stampset, &file->stampset);
|
||||
stamp_unlock(disk);
|
||||
|
||||
/* deallocate the file from the parity */
|
||||
scan_file_deallocate(scan, file);
|
||||
@ -706,7 +775,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
file->mtime_nsec = STAT_NSEC(st);
|
||||
|
||||
/* we have to save the new mtime */
|
||||
state->need_write = 1;
|
||||
scan->need_write = 1;
|
||||
}
|
||||
|
||||
if (strcmp(file->sub, sub) != 0) {
|
||||
@ -715,7 +784,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
|
||||
log_tag("scan:move:%s:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer), esc_tag(sub, esc_buffer_alt));
|
||||
if (is_diff) {
|
||||
printf("move %s -> %s\n", fmt_term(disk, file->sub, esc_buffer), fmt_term(disk, sub, esc_buffer_alt));
|
||||
msg_info("move %s -> %s\n", fmt_term(disk, file->sub, esc_buffer), fmt_term(disk, sub, esc_buffer_alt));
|
||||
}
|
||||
|
||||
/* remove from the name set */
|
||||
@ -728,7 +797,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub));
|
||||
|
||||
/* we have to save the new name */
|
||||
state->need_write = 1;
|
||||
scan->need_write = 1;
|
||||
} else {
|
||||
/* otherwise it's equal */
|
||||
++scan->count_equal;
|
||||
@ -864,7 +933,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
file->mtime_nsec = STAT_NSEC(st);
|
||||
|
||||
/* we have to save the new mtime */
|
||||
state->need_write = 1;
|
||||
scan->need_write = 1;
|
||||
}
|
||||
|
||||
/* if when processing the disk we used the past inodes values */
|
||||
@ -878,7 +947,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
|
||||
log_tag("scan:restore:%s:%s\n", disk->name, esc_tag(sub, esc_buffer));
|
||||
if (is_diff) {
|
||||
printf("restore %s\n", fmt_term(disk, sub, esc_buffer));
|
||||
msg_info("restore %s\n", fmt_term(disk, sub, esc_buffer));
|
||||
}
|
||||
|
||||
/* remove from the inode set */
|
||||
@ -891,7 +960,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode));
|
||||
|
||||
/* we have to save the new inode */
|
||||
state->need_write = 1;
|
||||
scan->need_write = 1;
|
||||
} else {
|
||||
/* otherwise it's the case of not persistent inode, where doesn't */
|
||||
/* matter if the inode is different or equal, because they have no */
|
||||
@ -976,12 +1045,14 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
struct snapraid_disk* other_disk = i->data;
|
||||
struct snapraid_file* other_file;
|
||||
|
||||
stamp_lock(other_disk);
|
||||
/* if the nanosecond part of the time stamp is valid, search */
|
||||
/* for name and stamp, otherwise for path and stamp */
|
||||
if (file->mtime_nsec != 0 && file->mtime_nsec != STAT_NSEC_INVALID)
|
||||
other_file = tommy_hashdyn_search(&other_disk->stampset, file_namestamp_compare, file, hash);
|
||||
else
|
||||
other_file = tommy_hashdyn_search(&other_disk->stampset, file_pathstamp_compare, file, hash);
|
||||
stamp_unlock(other_disk);
|
||||
|
||||
/* if found, and it's a fully hashed file */
|
||||
if (other_file && file_is_full_hashed_and_stable(scan->state, other_disk, other_file)) {
|
||||
@ -993,7 +1064,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
|
||||
log_tag("scan:copy:%s:%s:%s:%s\n", other_disk->name, esc_tag(other_file->sub, esc_buffer), disk->name, esc_tag(file->sub, esc_buffer_alt));
|
||||
if (is_diff) {
|
||||
printf("copy %s -> %s\n", fmt_term(other_disk, other_file->sub, esc_buffer), fmt_term(disk, file->sub, esc_buffer_alt));
|
||||
msg_info("copy %s -> %s\n", fmt_term(other_disk, other_file->sub, esc_buffer), fmt_term(disk, file->sub, esc_buffer_alt));
|
||||
}
|
||||
|
||||
/* mark it as reported */
|
||||
@ -1017,14 +1088,14 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
);
|
||||
|
||||
if (is_diff) {
|
||||
printf("update %s\n", fmt_term(disk, sub, esc_buffer));
|
||||
msg_info("update %s\n", fmt_term(disk, sub, esc_buffer));
|
||||
}
|
||||
} else {
|
||||
++scan->count_insert;
|
||||
|
||||
log_tag("scan:add:%s:%s\n", disk->name, esc_tag(sub, esc_buffer));
|
||||
if (is_diff) {
|
||||
printf("add %s\n", fmt_term(disk, sub, esc_buffer));
|
||||
msg_info("add %s\n", fmt_term(disk, sub, esc_buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1038,11 +1109,10 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub,
|
||||
*/
|
||||
static void scan_emptydir_remove(struct snapraid_scan* scan, struct snapraid_dir* dir)
|
||||
{
|
||||
struct snapraid_state* state = scan->state;
|
||||
struct snapraid_disk* disk = scan->disk;
|
||||
|
||||
/* state changed */
|
||||
state->need_write = 1;
|
||||
scan->need_write = 1;
|
||||
|
||||
/* remove the file from the dir containers */
|
||||
tommy_hashdyn_remove_existing(&disk->dirset, &dir->nodeset);
|
||||
@ -1057,11 +1127,10 @@ static void scan_emptydir_remove(struct snapraid_scan* scan, struct snapraid_dir
|
||||
*/
|
||||
static void scan_emptydir_insert(struct snapraid_scan* scan, struct snapraid_dir* dir)
|
||||
{
|
||||
struct snapraid_state* state = scan->state;
|
||||
struct snapraid_disk* disk = scan->disk;
|
||||
|
||||
/* state changed */
|
||||
state->need_write = 1;
|
||||
scan->need_write = 1;
|
||||
|
||||
/* insert the dir in the dir containers */
|
||||
tommy_hashdyn_insert(&disk->dirset, &dir->nodeset, dir, dir_name_hash(dir->sub));
|
||||
@ -1172,7 +1241,7 @@ struct stat* dstat(const char* file, struct stat* st)
|
||||
* Process a directory.
|
||||
* Return != 0 if at least one file or link is processed.
|
||||
*/
|
||||
static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const char* dir, const char* sub)
|
||||
static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* path_next, char* sub_next, char* tmp)
|
||||
{
|
||||
struct snapraid_state* state = scan->state;
|
||||
struct snapraid_disk* disk = scan->disk;
|
||||
@ -1180,25 +1249,28 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
DIR* d;
|
||||
tommy_list list;
|
||||
tommy_node* node;
|
||||
size_t path_len;
|
||||
size_t sub_len;
|
||||
|
||||
path_len = strlen(path_next);
|
||||
sub_len = strlen(sub_next);
|
||||
|
||||
tommy_list_init(&list);
|
||||
|
||||
d = opendir(dir);
|
||||
d = opendir(path_next);
|
||||
if (!d) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening directory '%s'. %s.\n", dir, strerror(errno));
|
||||
log_fatal("Error opening directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
if (level == 0)
|
||||
log_fatal("If this is the disk mount point, remember to create it manually\n");
|
||||
else
|
||||
log_fatal("If it's a permission problem, you can exclude it in the config file with:\n\texclude /%s\n", sub);
|
||||
log_fatal("If it's a permission problem, you can exclude it in the config file with:\n\texclude /%s\n", sub_next);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* read the full directory */
|
||||
while (1) {
|
||||
char path_next[PATH_MAX];
|
||||
char sub_next[PATH_MAX];
|
||||
struct dirent_sorted* entry;
|
||||
const char* name;
|
||||
struct dirent* dd;
|
||||
@ -1215,8 +1287,11 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
dd = readdir(d);
|
||||
if (dd == 0 && errno != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno));
|
||||
log_fatal("You can exclude it in the config file with:\n\texclude /%s\n", sub);
|
||||
/* restore removing additions */
|
||||
path_next[path_len] = 0;
|
||||
sub_next[sub_len] = 0;
|
||||
log_fatal("Error reading directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
log_fatal("You can exclude it in the config file with:\n\texclude /%s\n", sub_next);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1229,8 +1304,7 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
|
||||
continue;
|
||||
|
||||
pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
|
||||
pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
|
||||
pathcatl(path_next, path_len, PATH_MAX, name);
|
||||
|
||||
/* check for not supported file names */
|
||||
if (name[0] == 0) {
|
||||
@ -1276,7 +1350,9 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
|
||||
if (closedir(d) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing directory '%s'. %s.\n", dir, strerror(errno));
|
||||
/* restore removing additions */
|
||||
path_next[path_len] = 0;
|
||||
log_fatal("Error closing directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1299,9 +1375,6 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
/* process the sorted dir entries */
|
||||
node = list;
|
||||
while (node != 0) {
|
||||
char path_next[PATH_MAX];
|
||||
char sub_next[PATH_MAX];
|
||||
char out[PATH_MAX];
|
||||
struct snapraid_filter* reason = 0;
|
||||
struct dirent_sorted* dd = node->data;
|
||||
const char* name = dd->d_name;
|
||||
@ -1311,8 +1384,8 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
struct stat st_buf;
|
||||
#endif
|
||||
|
||||
pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
|
||||
pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
|
||||
pathcatl(path_next, path_len, PATH_MAX, name);
|
||||
pathcatl(sub_next, sub_len, PATH_MAX, name);
|
||||
|
||||
/* start with an unknown type */
|
||||
type = -1;
|
||||
@ -1383,14 +1456,13 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
scan_file(scan, is_diff, sub_next, st, FILEPHY_UNREAD_OFFSET);
|
||||
processed = 1;
|
||||
} else {
|
||||
msg_verbose("Excluding file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
|
||||
msg_verbose("Excluding file '%s' for rule '%s'\n", path_next, filter_type(reason, tmp, PATH_MAX));
|
||||
}
|
||||
} else if (type == 1) { /* LNK */
|
||||
if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
|
||||
char subnew[PATH_MAX];
|
||||
int ret;
|
||||
|
||||
ret = readlink(path_next, subnew, sizeof(subnew));
|
||||
ret = readlink(path_next, tmp, PATH_MAX);
|
||||
if (ret >= PATH_MAX) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in readlink file '%s'. Symlink too long.\n", path_next);
|
||||
@ -1407,13 +1479,13 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
log_fatal("WARNING! Empty symbolic link '%s'.\n", path_next);
|
||||
|
||||
/* readlink doesn't put the final 0 */
|
||||
subnew[ret] = 0;
|
||||
tmp[ret] = 0;
|
||||
|
||||
/* process as a symbolic link */
|
||||
scan_link(scan, is_diff, sub_next, subnew, FILE_IS_SYMLINK);
|
||||
scan_link(scan, is_diff, sub_next, tmp, FILE_IS_SYMLINK);
|
||||
processed = 1;
|
||||
} else {
|
||||
msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
|
||||
msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, tmp, PATH_MAX));
|
||||
}
|
||||
} else if (type == 2) { /* DIR */
|
||||
if (filter_subdir(&state->filterlist, &reason, disk->name, sub_next) == 0) {
|
||||
@ -1429,13 +1501,12 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
char sub_dir[PATH_MAX];
|
||||
|
||||
/* recurse */
|
||||
pathslash(path_next, sizeof(path_next));
|
||||
pathcpy(sub_dir, sizeof(sub_dir), sub_next);
|
||||
pathslash(sub_dir, sizeof(sub_dir));
|
||||
if (scan_dir(scan, level + 1, is_diff, path_next, sub_dir) == 0) {
|
||||
pathslash(path_next, PATH_MAX);
|
||||
pathslash(sub_next, PATH_MAX);
|
||||
if (scan_sub(scan, level + 1, is_diff, path_next, sub_next, tmp) == 0) {
|
||||
/* restore removing additions */
|
||||
pathcatl(sub_next, sub_len, PATH_MAX, name);
|
||||
/* scan the directory as empty dir */
|
||||
scan_emptydir(scan, sub_next);
|
||||
}
|
||||
@ -1443,7 +1514,7 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
processed = 1;
|
||||
}
|
||||
} else {
|
||||
msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
|
||||
msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, tmp, PATH_MAX));
|
||||
}
|
||||
} else {
|
||||
if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
|
||||
@ -1453,7 +1524,7 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
|
||||
log_fatal("WARNING! Ignoring special '%s' file '%s'\n", stat_desc(st), path_next);
|
||||
} else {
|
||||
msg_verbose("Excluding special file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
|
||||
msg_verbose("Excluding special file '%s' for rule '%s'\n", path_next, filter_type(reason, tmp, PATH_MAX));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1467,6 +1538,80 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch
|
||||
return processed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a directory.
|
||||
* Return != 0 if at least one file or link is processed.
|
||||
*/
|
||||
static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const char* dir, const char* sub)
|
||||
{
|
||||
/* working buffers used by scan_sub() */
|
||||
char path_next[PATH_MAX];
|
||||
char sub_next[PATH_MAX];
|
||||
char tmp[PATH_MAX];
|
||||
|
||||
pathcpy(path_next, sizeof(path_next), dir);
|
||||
pathcpy(sub_next, sizeof(sub_next), sub);
|
||||
|
||||
return scan_sub(scan, level, is_diff, path_next, sub_next, tmp);
|
||||
}
|
||||
|
||||
static void* scan_disk(void* arg)
|
||||
{
|
||||
struct snapraid_scan* scan = arg;
|
||||
struct snapraid_disk* disk = scan->disk;
|
||||
int ret;
|
||||
int has_persistent_inodes;
|
||||
int has_syncronized_hardlinks;
|
||||
uint64_t start;
|
||||
|
||||
/* check if the disk supports persistent inodes */
|
||||
ret = fsinfo(disk->dir, &has_persistent_inodes, &has_syncronized_hardlinks, 0, 0);
|
||||
if (ret < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing disk '%s' to get file-system info. %s.\n", disk->dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (!has_persistent_inodes) {
|
||||
disk->has_volatile_inodes = 1;
|
||||
}
|
||||
if (!has_syncronized_hardlinks) {
|
||||
disk->has_volatile_hardlinks = 1;
|
||||
}
|
||||
|
||||
/* if inodes or UUID are not persistent/changed/unsupported */
|
||||
if (disk->has_volatile_inodes || disk->has_different_uuid || disk->has_unsupported_uuid) {
|
||||
/* remove all the inodes from the inode collection */
|
||||
/* if they are not persistent, all of them could be changed now */
|
||||
/* and we don't want to find false matching ones */
|
||||
/* see scan_file() for more details */
|
||||
tommy_node* node = disk->filelist;
|
||||
while (node) {
|
||||
struct snapraid_file* file = node->data;
|
||||
|
||||
node = node->next;
|
||||
|
||||
/* remove from the inode set */
|
||||
tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
|
||||
|
||||
/* clear the inode */
|
||||
file->inode = 0;
|
||||
|
||||
/* mark as missing inode */
|
||||
file_flag_set(file, FILE_IS_WITHOUT_INODE);
|
||||
}
|
||||
}
|
||||
|
||||
start = tick_ms();
|
||||
|
||||
scan_dir(scan, 0, scan->is_diff, disk->dir, "");
|
||||
|
||||
if (!scan->is_diff)
|
||||
msg_progress("Scanned %s in %" PRIu64 " seconds\n", disk->name, (tick_ms() - start) / 1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
{
|
||||
tommy_node* i;
|
||||
@ -1482,76 +1627,44 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
|
||||
if (is_diff)
|
||||
msg_progress("Comparing...\n");
|
||||
else
|
||||
msg_progress("Scanning...\n");
|
||||
|
||||
/* first scan all the directory and find new and deleted files */
|
||||
/* allocate all the scan data */
|
||||
for (i = state->disklist; i != 0; i = i->next) {
|
||||
struct snapraid_disk* disk = i->data;
|
||||
struct snapraid_scan* scan;
|
||||
tommy_node* node;
|
||||
int ret;
|
||||
int has_persistent_inodes;
|
||||
int has_syncronized_hardlinks;
|
||||
|
||||
scan = malloc_nofail(sizeof(struct snapraid_scan));
|
||||
scan->state = state;
|
||||
scan->disk = disk;
|
||||
scan->count_equal = 0;
|
||||
scan->count_move = 0;
|
||||
scan->count_copy = 0;
|
||||
scan->count_restore = 0;
|
||||
scan->count_change = 0;
|
||||
scan->count_remove = 0;
|
||||
scan->count_insert = 0;
|
||||
tommy_list_init(&scan->file_insert_list);
|
||||
tommy_list_init(&scan->link_insert_list);
|
||||
tommy_list_init(&scan->dir_insert_list);
|
||||
scan = scan_alloc(state, disk, is_diff);
|
||||
|
||||
tommy_list_insert_tail(&scanlist, &scan->node, scan);
|
||||
|
||||
if (!is_diff)
|
||||
msg_progress("Scanning disk %s...\n", disk->name);
|
||||
|
||||
/* check if the disk supports persistent inodes */
|
||||
ret = fsinfo(disk->dir, &has_persistent_inodes, &has_syncronized_hardlinks, 0, 0);
|
||||
if (ret < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing disk '%s' to get file-system info. %s.\n", disk->dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (!has_persistent_inodes) {
|
||||
disk->has_volatile_inodes = 1;
|
||||
}
|
||||
if (!has_syncronized_hardlinks) {
|
||||
disk->has_volatile_hardlinks = 1;
|
||||
}
|
||||
|
||||
/* if inodes or UUID are not persistent/changed/unsupported */
|
||||
if (disk->has_volatile_inodes || disk->has_different_uuid || disk->has_unsupported_uuid) {
|
||||
/* remove all the inodes from the inode collection */
|
||||
/* if they are not persistent, all of them could be changed now */
|
||||
/* and we don't want to find false matching ones */
|
||||
/* see scan_file() for more details */
|
||||
node = disk->filelist;
|
||||
while (node) {
|
||||
struct snapraid_file* file = node->data;
|
||||
|
||||
node = node->next;
|
||||
|
||||
/* remove from the inode set */
|
||||
tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset);
|
||||
|
||||
/* clear the inode */
|
||||
file->inode = 0;
|
||||
|
||||
/* mark as missing inode */
|
||||
file_flag_set(file, FILE_IS_WITHOUT_INODE);
|
||||
}
|
||||
}
|
||||
|
||||
scan_dir(scan, 0, is_diff, disk->dir, "");
|
||||
}
|
||||
|
||||
/* first scan all the directory and find new and deleted files */
|
||||
for (i = scanlist; i != 0; i = i->next) {
|
||||
struct snapraid_scan* scan = i->data;
|
||||
#if HAVE_THREAD
|
||||
if (state->opt.skip_multi_scan)
|
||||
scan_disk(scan);
|
||||
else
|
||||
thread_create(&scan->thread, scan_disk, scan);
|
||||
#else
|
||||
scan_disk(scan);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAVE_THREAD
|
||||
/* wait for all threads to terminate */
|
||||
for (i = scanlist; i != 0; i = i->next) {
|
||||
struct snapraid_scan* scan = i->data;
|
||||
void* retval;
|
||||
|
||||
/* wait for thread termination */
|
||||
if (!state->opt.skip_multi_scan)
|
||||
thread_join(scan->thread, &retval);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* we split the search in two phases because to detect files */
|
||||
/* moved from one disk to another we have to start deletion */
|
||||
/* only when all disks have all the new files found */
|
||||
@ -1561,7 +1674,6 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
struct snapraid_scan* scan = i->data;
|
||||
struct snapraid_disk* disk = scan->disk;
|
||||
tommy_node* node;
|
||||
unsigned phy_count;
|
||||
unsigned phy_dup;
|
||||
uint64_t phy_last;
|
||||
struct snapraid_file* phy_file_last;
|
||||
@ -1580,7 +1692,7 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
|
||||
log_tag("scan:remove:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
|
||||
if (is_diff) {
|
||||
printf("remove %s\n", fmt_term(disk, file->sub, esc_buffer));
|
||||
msg_info("remove %s\n", fmt_term(disk, file->sub, esc_buffer));
|
||||
}
|
||||
|
||||
scan_file_remove(scan, file);
|
||||
@ -1601,7 +1713,7 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
|
||||
log_tag("scan:remove:%s:%s\n", disk->name, esc_tag(slink->sub, esc_buffer));
|
||||
if (is_diff) {
|
||||
printf("remove %s\n", fmt_term(disk, slink->sub, esc_buffer));
|
||||
msg_info("remove %s\n", fmt_term(disk, slink->sub, esc_buffer));
|
||||
}
|
||||
|
||||
scan_link_remove(scan, slink);
|
||||
@ -1644,7 +1756,6 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
/* to reuse the just freed space */
|
||||
/* also check if the physical offset reported are fakes or not */
|
||||
node = scan->file_insert_list;
|
||||
phy_count = 0;
|
||||
phy_dup = 0;
|
||||
phy_last = FILEPHY_UNREAD_OFFSET;
|
||||
phy_file_last = 0;
|
||||
@ -1660,13 +1771,12 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
/* if verbose, print the list of duplicates real offsets */
|
||||
/* other cases are for offsets not supported, so we don't need to report them file by file */
|
||||
if (phy_last >= FILEPHY_REAL_OFFSET) {
|
||||
log_fatal("WARNING! Files '%s%s' and '%s%s' have the same physical offset %" PRId64 ".\n", disk->dir, phy_file_last->sub, disk->dir, file->sub, phy_last);
|
||||
log_fatal("WARNING! Files '%s%s' and '%s%s' share the same physical offset %" PRId64 ".\n", disk->dir, phy_file_last->sub, disk->dir, file->sub, phy_last);
|
||||
}
|
||||
++phy_dup;
|
||||
}
|
||||
phy_file_last = file;
|
||||
phy_last = file->physical;
|
||||
++phy_count;
|
||||
}
|
||||
|
||||
/* next node */
|
||||
@ -1707,6 +1817,14 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
}
|
||||
}
|
||||
|
||||
/* propagate the state change (after all the scan operations are called) */
|
||||
for (i = scanlist; i != 0; i = i->next) {
|
||||
struct snapraid_scan* scan = i->data;
|
||||
if (scan->need_write) {
|
||||
state->need_write = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for disks where all the previously existing files where removed */
|
||||
if (!state->opt.force_empty) {
|
||||
int all_missing = 0;
|
||||
@ -1738,13 +1856,13 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
}
|
||||
}
|
||||
if (done) {
|
||||
log_fatal("\nare now missing or rewritten!\n");
|
||||
log_fatal("\nare now missing or have been rewritten!\n");
|
||||
if (all_rewritten) {
|
||||
log_fatal("This could happen when restoring a disk with a backup\n");
|
||||
log_fatal("This could occur when restoring a disk from a backup\n");
|
||||
log_fatal("program that is not setting correctly the timestamps.\n");
|
||||
}
|
||||
if (all_missing) {
|
||||
log_fatal("This could happen when some disks are not mounted\n");
|
||||
log_fatal("This could occur when some disks are not mounted\n");
|
||||
log_fatal("in the expected directory.\n");
|
||||
}
|
||||
if (!is_diff) {
|
||||
@ -1770,7 +1888,7 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
}
|
||||
}
|
||||
if (done) {
|
||||
log_fatal(". Files order won't be optimal.\n");
|
||||
log_fatal(". The order of files won't be optimal.\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1789,7 +1907,7 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
}
|
||||
}
|
||||
if (done) {
|
||||
log_fatal(". Not using inodes to detect move operations.\n");
|
||||
log_fatal(". Inodes are not used to detect move operations.\n");
|
||||
}
|
||||
|
||||
/* check for disks with changed UUID */
|
||||
@ -1811,7 +1929,7 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
}
|
||||
}
|
||||
if (done) {
|
||||
log_fatal(". Not using inodes to detect move operations.\n");
|
||||
log_fatal(". Inodes are not used to detect move operations.\n");
|
||||
}
|
||||
|
||||
/* check for disks with unsupported UUID */
|
||||
@ -1896,7 +2014,7 @@ static int state_diffscan(struct snapraid_state* state, int is_diff)
|
||||
}
|
||||
log_flush();
|
||||
|
||||
tommy_list_foreach(&scanlist, (tommy_foreach_func*)free);
|
||||
tommy_list_foreach(&scanlist, (tommy_foreach_func*)scan_free);
|
||||
|
||||
/* check the file-system on all disks */
|
||||
state_fscheck(state, "after scan");
|
||||
|
@ -671,7 +671,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
||||
if (io_error || silent_error) {
|
||||
log_fatal("Use 'snapraid status' to list the bad blocks.\n");
|
||||
log_fatal("Use 'snapraid -e fix' to recover them.\n");
|
||||
log_fatal("Use 'snapraid -p bad scrub' to recheck after fixing.\n");
|
||||
log_fatal("Use 'snapraid -p bad scrub' to recheck after fixing to clear the bad state.\n");
|
||||
}
|
||||
|
||||
log_tag("summary:error_file:%u\n", error);
|
||||
|
@ -38,7 +38,7 @@ void usage(void)
|
||||
{
|
||||
version();
|
||||
|
||||
printf("Usage: " PACKAGE " status|diff|sync|scrub|list|dup|up|down|smart|pool|check|fix [options]\n");
|
||||
printf("Usage: " PACKAGE " status|diff|sync|scrub|list|dup|up|down|touch|smart|pool|check|fix [options]\n");
|
||||
printf("\n");
|
||||
printf("Commands:\n");
|
||||
printf(" status Print the status of the array\n");
|
||||
@ -49,6 +49,7 @@ void usage(void)
|
||||
printf(" dup Find duplicate files\n");
|
||||
printf(" up Spin-up the array\n");
|
||||
printf(" down Spin-down the array\n");
|
||||
printf(" touch Add non-zero ns timestamps to files\n");
|
||||
printf(" smart SMART attributes of the array\n");
|
||||
printf(" pool Create or update the virtual view of the array\n");
|
||||
printf(" check Check the array\n");
|
||||
@ -307,6 +308,7 @@ void config(char* conf, size_t conf_size, const char* argv0)
|
||||
#define OPT_TEST_SKIP_CONTENT_WRITE 302
|
||||
#define OPT_TEST_SKIP_SPACE_HOLDER 303
|
||||
#define OPT_TEST_FORMAT 304
|
||||
#define OPT_TEST_SKIP_MULTI_SCAN 305
|
||||
|
||||
#if HAVE_GETOPT_LONG
|
||||
struct option long_options[] = {
|
||||
@ -475,6 +477,9 @@ struct option long_options[] = {
|
||||
/* Set the output format */
|
||||
{ "test-fmt", 1, 0, OPT_TEST_FORMAT },
|
||||
|
||||
/* Skip thread in disk scan */
|
||||
{ "test-skip-multi-scan", 0, 0, OPT_TEST_SKIP_MULTI_SCAN },
|
||||
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
#endif
|
||||
@ -929,6 +934,9 @@ int main(int argc, char* argv[])
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
break;
|
||||
case OPT_TEST_SKIP_MULTI_SCAN :
|
||||
opt.skip_multi_scan = 1;
|
||||
break;
|
||||
default :
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Unknown option '%c'\n", (char)c);
|
||||
@ -1076,28 +1084,28 @@ int main(int argc, char* argv[])
|
||||
|
||||
if (opt.force_full && opt.force_nocopy) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You cannot use the -F, --force-full and -N, --force-nocopy options at the same time\n");
|
||||
log_fatal("You cannot use the -F, --force-full and -N, --force-nocopy options simultaneously\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (opt.force_realloc && opt.force_nocopy) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You cannot use the -R, --force-realloc and -N, --force-nocopy options at the same time\n");
|
||||
log_fatal("You cannot use the -R, --force-realloc and -N, --force-nocopy options simultaneously\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (opt.force_realloc && opt.force_full) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You cannot use the -R, --force-realloc and -F, --force-full options at the same time\n");
|
||||
log_fatal("You cannot use the -R, --force-realloc and -F, --force-full options simultaneously\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (opt.prehash && opt.force_nocopy) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You cannot use the -h, --pre-hash and -N, --force-nocopy options at the same time\n");
|
||||
log_fatal("You cannot use the -h, --pre-hash and -N, --force-nocopy options simultaneously\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1141,7 +1149,7 @@ int main(int argc, char* argv[])
|
||||
/* because we don't keep the information on what disk is the error */
|
||||
if (filter_error != 0 && !tommy_list_empty(&filterlist_disk)) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You cannot use -e, --filter-error and -d, --filter-disk at the same time\n");
|
||||
log_fatal("You cannot use -e, --filter-error and -d, --filter-disk simultaneously\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1153,7 +1161,7 @@ int main(int argc, char* argv[])
|
||||
default :
|
||||
if (import_timestamp != 0 || import_content != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You cannot import with the '%s' command\n", command);
|
||||
log_fatal("Import not allowed with the '%s' command\n", command);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1279,9 +1287,9 @@ int main(int argc, char* argv[])
|
||||
if (lock == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
if (errno != EWOULDBLOCK) {
|
||||
log_fatal("Error creating the lock file '%s'. %s.\n", state.lockfile, strerror(errno));
|
||||
log_fatal("Failed to create the lock file '%s'. %s.\n", state.lockfile, strerror(errno));
|
||||
} else {
|
||||
log_fatal("The lock file '%s' is already locked!\n", state.lockfile);
|
||||
log_fatal("The lock file '%s' is already in use!\n", state.lockfile);
|
||||
log_fatal("SnapRAID is already in use!\n");
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
@ -1347,7 +1355,7 @@ int main(int argc, char* argv[])
|
||||
ret = system(run); /* ignore error */
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in running command '%s'.\n", run);
|
||||
log_fatal("Error executing command '%s'.\n", run);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1370,7 +1378,7 @@ int main(int argc, char* argv[])
|
||||
if ((state.need_write || state.opt.force_content_write))
|
||||
state_write(&state);
|
||||
} else {
|
||||
log_fatal("WARNING! Skipped state write for --test-kill-after-sync option.\n");
|
||||
log_fatal("WARNING! Skipped writing state due to --test-kill-after-sync option.\n");
|
||||
}
|
||||
|
||||
/* abort if required */
|
||||
@ -1519,7 +1527,7 @@ int main(int argc, char* argv[])
|
||||
if (!opt.skip_lock && state.lockfile[0]) {
|
||||
if (lock_unlock(lock) == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing the lock file '%s'. %s.\n", state.lockfile, strerror(errno));
|
||||
log_fatal("Failed to close the lock file '%s'. %s.\n", state.lockfile, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
162
cmdline/state.c
162
cmdline/state.c
@ -37,10 +37,6 @@
|
||||
* writing to disk, but you'll need to access multiple times the same data,
|
||||
* being potentially slower.
|
||||
*
|
||||
* For upcoming SnapRAID version it's planned to add a mutex protection
|
||||
* at the file-system structure, slowing down multiple data access,
|
||||
* so we disable it.
|
||||
*
|
||||
* Multi thread for verify is instead always generally faster,
|
||||
* so we enable it if possible.
|
||||
*/
|
||||
@ -215,7 +211,7 @@ static void state_config_check(struct snapraid_state* state, const char* path, t
|
||||
if (state->raid_mode == RAID_MODE_VANDERMONDE) {
|
||||
if (state->level > 3) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("If you use the z-parity you cannot have more than 3 parities.\n");
|
||||
log_fatal("Using z-parity limits you to a maximum of 3 parities.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STIO */
|
||||
}
|
||||
@ -224,7 +220,7 @@ static void state_config_check(struct snapraid_state* state, const char* path, t
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
if (state->parity[l].split_mac == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("No '%s' specification in '%s'\n", lev_config_name(l), path);
|
||||
log_fatal("Missing '%s' specification in '%s'\n", lev_config_name(l), path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -232,7 +228,7 @@ static void state_config_check(struct snapraid_state* state, const char* path, t
|
||||
|
||||
if (tommy_list_empty(&state->contentlist)) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("No 'content' specification in '%s'\n", path);
|
||||
log_fatal("Missing 'content' specification in '%s'\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -859,7 +855,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
||||
pathimport(device, sizeof(device), buffer);
|
||||
slash = strrchr(device, '/');
|
||||
if (slash)
|
||||
*slash = 0;
|
||||
*(slash + 1) = 0;
|
||||
else
|
||||
pathcpy(device, sizeof(device), ".");
|
||||
if (stat(device, &st) == 0) {
|
||||
@ -996,14 +992,14 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
||||
ret = sgettok(f, buffer, sizeof(buffer));
|
||||
if (ret < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Invalid 'smartctl' name specification in '%s' at line %u\n", path, line);
|
||||
log_fatal("Invalid 'smartctl' name in '%s' at line %u\n", path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (!*buffer) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Empty 'smartctl' name specification in '%s' at line %u\n", path, line);
|
||||
log_fatal("Empty 'smartctl' name in '%s' at line %u\n", path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1013,21 +1009,21 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
||||
ret = sgetlasttok(f, custom, sizeof(custom));
|
||||
if (ret < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Invalid 'smartctl' option specification in '%s' at line %u\n", path, line);
|
||||
log_fatal("Invalid 'smartctl' option in '%s' at line %u\n", path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (!*custom) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Empty 'smartctl' option specification in '%s' at line %u\n", path, line);
|
||||
log_fatal("Empty 'smartctl' option in '%s' at line %u\n", path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (validate_smartctl(custom) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Invalid 'smartctl' option specification in '%s' at line %u\n", path, line);
|
||||
log_fatal("Invalid 'smartctl' option in '%s' at line %u\n", path, line);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1036,7 +1032,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
||||
if (lev_config_scan(buffer, &level, 0) == 0) {
|
||||
if (state->parity[level].smartctl[0] != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Duplicate parity smartctl '%s' at line %u\n", buffer, line);
|
||||
log_fatal("Duplicate parity 'smartctl' '%s' at line %u\n", buffer, line);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1054,7 +1050,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
||||
}
|
||||
if (!disk) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Missing disk smartctl '%s' at line %u\n", buffer, line);
|
||||
log_fatal("Missing disk 'smartctl' '%s' at line %u\n", buffer, line);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1091,7 +1087,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
||||
if (!filter) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Invalid 'exclude' specification '%s' in '%s' at line %u\n", buffer, path, line);
|
||||
log_fatal("Filters using relative paths are not supported. Ensure to add an initial slash\n");
|
||||
log_fatal("Filters with relative paths are not supported. Ensure to add an initial slash\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1118,7 +1114,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
||||
if (!filter) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Invalid 'include' specification '%s' in '%s' at line %u\n", buffer, path, line);
|
||||
log_fatal("Filters using relative paths are not supported. Ensure to add an initial slash\n");
|
||||
log_fatal("Filters with relative paths are not supported. Ensure to add an initial slash\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1222,7 +1218,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
||||
/* by default use a random hash seed */
|
||||
if (randomize(state->hashseed, HASH_MAX) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed to get random values.\n");
|
||||
log_fatal("Failed to retrieve random values.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1412,7 +1408,7 @@ static void state_map(struct snapraid_state* state)
|
||||
disk = find_disk_by_name(state, map->name);
|
||||
if (disk == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency for mapping '%s'\n", map->name);
|
||||
log_fatal("Internal inconsistency: Mapping not found for '%s'\n", map->name);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1481,11 +1477,11 @@ static void state_map(struct snapraid_state* state)
|
||||
|
||||
if (!state->opt.force_uuid && uuid_mismatch > state->level) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Too many disks have UUID changed from the latest 'sync'.\n");
|
||||
log_fatal("If this happens because you really replaced them,\n");
|
||||
log_fatal("you can '%s' anyway, using 'snapraid --force-uuid %s'.\n", state->command, state->command);
|
||||
log_fatal("Instead, it's possible that you messed up the disk mount points,\n");
|
||||
log_fatal("and you have to restore the mount points at the state of the latest sync.\n");
|
||||
log_fatal("Too many disks have changed UUIDs since the last 'sync'.\n");
|
||||
log_fatal("If this happened because you actually replaced them,\n");
|
||||
log_fatal("you can still '%s', using 'snapraid --force-uuid %s'.\n", state->command, state->command);
|
||||
log_fatal("Alternatively, you may have misconfigured the disk mount points,\n");
|
||||
log_fatal("and you need to restore the mount points to the state of the latest sync.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1502,7 +1498,7 @@ static void state_map(struct snapraid_state* state)
|
||||
/* ensure to don't go over the limit of the RAID engine */
|
||||
if (diskcount > RAID_DATA_MAX) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Too many data disks. No more than %u.\n", RAID_DATA_MAX);
|
||||
log_fatal("Too many data disks. Maximum allowed is %u.\n", RAID_DATA_MAX);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1514,15 +1510,15 @@ static void state_map(struct snapraid_state* state)
|
||||
if (!state->opt.no_warnings) {
|
||||
/* intentionally use log_fatal() instead of log_error() to give more visibility at the warning */
|
||||
if (diskcount >= 36 && state->level < 6) {
|
||||
log_fatal("WARNING! With %u disks it's recommended to use six parity levels.\n", diskcount);
|
||||
log_fatal("WARNING! For %u disks, it's recommended to use six parity levels.\n", diskcount);
|
||||
} else if (diskcount >= 29 && state->level < 5) {
|
||||
log_fatal("WARNING! With %u disks it's recommended to use five parity levels.\n", diskcount);
|
||||
log_fatal("WARNING! For %u disks, it's recommended to use five parity levels.\n", diskcount);
|
||||
} else if (diskcount >= 22 && state->level < 4) {
|
||||
log_fatal("WARNING! With %u disks it's recommended to use four parity levels.\n", diskcount);
|
||||
log_fatal("WARNING! For %u disks, it's recommended to use four parity levels.\n", diskcount);
|
||||
} else if (diskcount >= 15 && state->level < 3) {
|
||||
log_fatal("WARNING! With %u disks it's recommended to use three parity levels.\n", diskcount);
|
||||
log_fatal("WARNING! For %u disks, it's recommended to use three parity levels.\n", diskcount);
|
||||
} else if (diskcount >= 5 && state->level < 2) {
|
||||
log_fatal("WARNING! With %u disks it's recommended to use two parity levels.\n", diskcount);
|
||||
log_fatal("WARNING! For %u disks, it's recommended to use two parity levels.\n", diskcount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1543,7 +1539,7 @@ void state_refresh(struct snapraid_state* state)
|
||||
disk = find_disk_by_name(state, map->name);
|
||||
if (disk == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency for mapping '%s'\n", map->name);
|
||||
log_fatal("Internal inconsistency: Mapping not found for '%s'\n", map->name);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1551,7 +1547,7 @@ void state_refresh(struct snapraid_state* state)
|
||||
ret = fsinfo(disk->dir, 0, 0, &total_space, &free_space);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing disk '%s' to get file-system info. %s.\n", disk->dir, strerror(errno));
|
||||
log_fatal("Error accessing disk '%s' to retrieve file-system info. %s.\n", disk->dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1579,7 +1575,7 @@ void state_refresh(struct snapraid_state* state)
|
||||
ret = fsinfo(state->parity[l].split_map[s].path, 0, 0, &total_space, &free_space);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing file '%s' to get file-system info. %s.\n", state->parity[l].split_map[s].path, strerror(errno));
|
||||
log_fatal("Error accessing file '%s' to retrieve file-system info. %s.\n", state->parity[l].split_map[s].path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1609,13 +1605,13 @@ static void state_content_check(struct snapraid_state* state, const char* path)
|
||||
struct snapraid_map* other = j->data;
|
||||
if (strcmp(map->name, other->name) == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Colliding 'map' disk specification in '%s'\n", path);
|
||||
log_fatal("Conflicting 'map' disk specification in '%s'\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (map->position == other->position) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Colliding 'map' index specification in '%s'\n", path);
|
||||
log_fatal("Conflicting 'map' index specification in '%s'\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1714,7 +1710,7 @@ static void decoding_error(const char* path, STREAM* f)
|
||||
if (seof(f)) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Unexpected end of content file '%s' at offset %" PRIi64 "\n", path, stell(f));
|
||||
log_fatal("This content file is truncated. Use an alternate copy.\n");
|
||||
log_fatal("This content file is truncated. Please use an alternate copy.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1726,11 +1722,11 @@ static void decoding_error(const char* path, STREAM* f)
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
log_fatal("Decoding error in '%s' at offset %" PRIi64 "\n", path, stell(f));
|
||||
log_fatal("Error decoding '%s' at offset %" PRIi64 "\n", path, stell(f));
|
||||
|
||||
if (sdeplete(f, buf) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error flushing the content file '%s' at offset %" PRIi64 "\n", path, stell(f));
|
||||
log_fatal("Failed to flush content file '%s' at offset %" PRIi64 "\n", path, stell(f));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1745,11 +1741,11 @@ static void decoding_error(const char* path, STREAM* f)
|
||||
crc_stored = crc32c(crc_stored, buf, 4);
|
||||
|
||||
if (crc_computed != crc_stored) {
|
||||
log_fatal("Mismatching CRC in '%s'\n", path);
|
||||
log_fatal("This content file is damaged! Use an alternate copy.\n");
|
||||
log_fatal("CRC mismatch in '%s'\n", path);
|
||||
log_fatal("This content file is damaged! Please use an alternate copy.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
log_fatal("The file CRC is correct!\n");
|
||||
log_fatal("The CRC of the file is correct!\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1835,7 +1831,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (ret < 0 || mapping >= mapping_max) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency in mapping index!\n");
|
||||
log_fatal("Internal inconsistency: File mapping index out of range\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1852,7 +1848,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (state->block_size == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency due zero blocksize!\n");
|
||||
log_fatal("Internal inconsistency: Zero blocksize\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1861,7 +1857,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (v_size / state->block_size > blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency in file size too big!\n");
|
||||
log_fatal("Internal inconsistency: File size too big!\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1906,7 +1902,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (!*sub) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency for null file!\n");
|
||||
log_fatal("Internal inconsistency: Null file!\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1948,7 +1944,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (v_idx + v_count > file->blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency in block number!\n");
|
||||
log_fatal("Internal inconsistency: Block number out of range\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1956,7 +1952,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (v_pos + v_count > blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency in block size %u/%u!\n", blockmax, v_pos + v_count);
|
||||
log_fatal("Internal inconsistency: Block size %u/%u!\n", blockmax, v_pos + v_count);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_START */
|
||||
}
|
||||
@ -2080,7 +2076,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (v_pos + v_count > blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency in info size %u/%u!\n", blockmax, v_pos + v_count);
|
||||
log_fatal("Internal inconsistency: Info size %u/%u!\n", blockmax, v_pos + v_count);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2112,7 +2108,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (rehash && state->prevhash == HASH_UNDEFINED) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency for missing previous checksum!\n");
|
||||
log_fatal("Internal inconsistency: Missing previous checksum!\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2131,7 +2127,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (!info) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency for missing info!\n");
|
||||
log_fatal("Internal inconsistency: Missing info!\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2155,7 +2151,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (ret < 0 || mapping >= mapping_max) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency in mapping index!\n");
|
||||
log_fatal("Internal inconsistency: Hole mapping index out of range\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2178,7 +2174,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (v_pos + v_count > blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency in hole size %u/%u!\n", blockmax, v_pos + v_count);
|
||||
log_fatal("Internal inconsistency: Hole size %u/%u!\n", blockmax, v_pos + v_count);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2255,7 +2251,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (ret < 0 || mapping >= mapping_max) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency in mapping index!\n");
|
||||
log_fatal("Internal inconsistency: Symlink mapping index out of range\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2272,7 +2268,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (!*sub) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency for null symlink!\n");
|
||||
log_fatal("Internal inconsistency: Null symlink!\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2306,7 +2302,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (ret < 0 || mapping >= mapping_max) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency in mapping index!\n");
|
||||
log_fatal("Internal inconsistency: Hardlink mapping index out of range!\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2323,7 +2319,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (!*sub) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency for null hardlink!\n");
|
||||
log_fatal("Internal inconsistency: Null hardlink!\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2339,7 +2335,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (!*linkto) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency for empty hardlink '%s'!\n", sub);
|
||||
log_fatal("Internal inconsistency: Empty hardlink '%s'!\n", sub);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2364,7 +2360,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (ret < 0 || mapping >= mapping_max) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency in mapping index!\n");
|
||||
log_fatal("Internal inconsistency: Dir mapping index ouf of range!\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2381,7 +2377,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (!*sub) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal("Internal inconsistency for null dir!\n");
|
||||
log_fatal("Internal inconsistency: Null dir!\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2823,8 +2819,8 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
if (crc_stored != crc_computed) {
|
||||
/* LCOV_EXCL_START */
|
||||
/* here don't call decoding_error() because it's too late to get the crc */
|
||||
log_fatal("Mismatching CRC in '%s'\n", path);
|
||||
log_fatal("This content file is damaged! Use an alternate copy.\n");
|
||||
log_fatal("CRC mismatch in '%s'\n", path);
|
||||
log_fatal("The content file is damaged! Please use an alternate copy.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -2850,7 +2846,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
|
||||
if (!crc_checked) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Finished reading '%s' without finding the CRC\n", path);
|
||||
log_fatal("Reached the end of '%s' without finding the expected CRC\n", path);
|
||||
log_fatal("This content file is truncated or damaged! Use an alternate copy.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
@ -2862,7 +2858,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
||||
/* check that the stored parity size matches the loaded state */
|
||||
if (blockmax != parity_allocated_size(state)) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in parity size %u/%u in '%s' at offset %" PRIi64 "\n", blockmax, parity_allocated_size(state), path, stell(f));
|
||||
log_fatal("Internal inconsistency: Parity size %u/%u in '%s' at offset %" PRIi64 "\n", blockmax, parity_allocated_size(state), path, stell(f));
|
||||
if (state->opt.skip_content_check) {
|
||||
log_fatal("Overriding.\n");
|
||||
blockmax = parity_allocated_size(state);
|
||||
@ -3013,7 +3009,7 @@ static void* state_write_thread(void* arg)
|
||||
disk = find_disk_by_name(state, map->name);
|
||||
if (!disk) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency for unmapped disk '%s'\n", map->name);
|
||||
log_fatal("Internal inconsistency: Unmapped disk '%s'\n", map->name);
|
||||
return context;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -3134,7 +3130,7 @@ static void* state_write_thread(void* arg)
|
||||
break;
|
||||
default :
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in state for block %u state %u\n", v_pos, v_state);
|
||||
log_fatal("Internal inconsistency: State for block %u state %u\n", v_pos, v_state);
|
||||
return context;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -3344,8 +3340,8 @@ static void* state_write_thread(void* arg)
|
||||
/* with the one of the data written to the stream */
|
||||
if (crc != scrc_stream(f)) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("CRC mismatch writing the content stream.\n");
|
||||
log_fatal("DANGER! Your RAM memory is broken! DO NOT PROCEED UNTIL FIXED!\n");
|
||||
log_fatal("CRC mismatch while writing the content stream.\n");
|
||||
log_fatal("DANGER! Your RAM memory is faulty! DO NOT PROCEED UNTIL FIXED!\n");
|
||||
log_fatal("Try running a memory test like http://www.memtest86.com/\n");
|
||||
return context;
|
||||
/* LCOV_EXCL_STOP */
|
||||
@ -3439,7 +3435,7 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
disk = find_disk_by_name(state, map->name);
|
||||
if (!disk) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency for unmapped disk '%s'\n", map->name);
|
||||
log_fatal("Internal inconsistency: Unmapped disk '%s'\n", map->name);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -3728,7 +3724,7 @@ void state_read(struct snapraid_state* state)
|
||||
|
||||
/* otherwise continue */
|
||||
if (node->next) {
|
||||
log_fatal("WARNING! Content file '%s' not found, trying with another copy...\n", path);
|
||||
log_fatal("WARNING! Content file '%s' not found, attempting with another copy...\n", path);
|
||||
|
||||
/* ensure to rewrite all the content files */
|
||||
state->need_write = 1;
|
||||
@ -3866,7 +3862,7 @@ static void* state_verify_thread(void* arg)
|
||||
|
||||
if (sdeplete(f, buf) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error flushing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
|
||||
log_fatal("Failed to flush content file '%s'. %s.\n", serrorfile(f), strerror(errno));
|
||||
return context;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -3904,6 +3900,8 @@ static void state_verify_content(struct snapraid_state* state, uint32_t crc)
|
||||
tommy_node* i;
|
||||
int fail;
|
||||
|
||||
msg_progress("Verifying...\n");
|
||||
|
||||
/* start all reading threads */
|
||||
i = tommy_list_head(&state->contentlist);
|
||||
while (i) {
|
||||
@ -3912,8 +3910,6 @@ static void state_verify_content(struct snapraid_state* state, uint32_t crc)
|
||||
char tmp[PATH_MAX];
|
||||
STREAM* f;
|
||||
|
||||
msg_progress("Verifying %s...\n", content->content);
|
||||
|
||||
pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
|
||||
f = sopen_read(tmp);
|
||||
if (f == 0) {
|
||||
@ -4249,7 +4245,7 @@ void state_progress_end(struct snapraid_state* state, block_off_t countpos, bloc
|
||||
|
||||
elapsed = now - state->progress_whole_start - state->progress_wasted;
|
||||
|
||||
msg_bar("%u%% completed, %u MB accessed", countpos * 100 / countmax, countsize_MB);
|
||||
msg_bar("%u%% completed, %u MB accessed", muldiv(countpos, 100, countmax), countsize_MB);
|
||||
|
||||
msg_bar(" in %u:%02u", (unsigned)(elapsed / 3600), (unsigned)((elapsed % 3600) / 60));
|
||||
|
||||
@ -4409,7 +4405,7 @@ static void state_progress_graph(struct snapraid_state* state, struct snapraid_i
|
||||
struct snapraid_disk* disk = i->data;
|
||||
v = disk->progress_tick[current] - ref(disk->progress_tick, oldest);
|
||||
printr(disk->name, pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
|
||||
@ -4420,32 +4416,32 @@ static void state_progress_graph(struct snapraid_state* state, struct snapraid_i
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
v = state->parity[l].progress_tick[current] - ref(state->parity[l].progress_tick, oldest);
|
||||
printr(lev_config_name(l), pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
v = state->progress_tick_raid[current] - ref(state->progress_tick_raid, oldest);
|
||||
printr("raid", pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
|
||||
v = state->progress_tick_hash[current] - ref(state->progress_tick_hash, oldest);
|
||||
printr("hash", pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
|
||||
v = state->progress_tick_sched[current] - ref(state->progress_tick_sched, oldest);
|
||||
printr("sched", pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
|
||||
v = state->progress_tick_misc[current] - ref(state->progress_tick_misc, oldest);
|
||||
printr("misc", pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
|
||||
@ -4503,7 +4499,7 @@ int state_progress(struct snapraid_state* state, struct snapraid_io* io, block_o
|
||||
|
||||
/* completion percentage */
|
||||
if (countmax)
|
||||
out_perc = countpos * 100 / countmax;
|
||||
out_perc = muldiv(countpos, 100, countmax);
|
||||
|
||||
/* if we have at least 5 measures */
|
||||
if (state->progress_tick >= 5
|
||||
@ -4569,11 +4565,11 @@ int state_progress(struct snapraid_state* state, struct snapraid_io* io, block_o
|
||||
|
||||
/* estimate the cpu usage percentage */
|
||||
if (delta_tick_total != 0)
|
||||
out_cpu = (unsigned)(delta_tick_cpu * 100U / delta_tick_total);
|
||||
out_cpu = muldiv(delta_tick_cpu, 100, delta_tick_total);
|
||||
|
||||
/* estimate the remaining time in minutes */
|
||||
if (delta_pos != 0)
|
||||
out_eta = (countmax - countpos) * delta_time / (60 * delta_pos);
|
||||
out_eta = muldiv(countmax - countpos, delta_time, 60 * delta_pos);
|
||||
|
||||
if (state->opt.force_stats) {
|
||||
os_clear();
|
||||
@ -4738,7 +4734,7 @@ void state_fscheck(struct snapraid_state* state, const char* ope)
|
||||
|
||||
if (fs_check(disk) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in file-system for disk '%s' %s\n", disk->name, ope);
|
||||
log_fatal("Internal inconsistency: File-system check for disk '%s' %s\n", disk->name, ope);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
@ -119,6 +119,7 @@ struct snapraid_option {
|
||||
int auto_conf; /**< Allow to run without configuration file. */
|
||||
int force_stats; /**< Force stats print during process. */
|
||||
uint64_t parity_limit_size; /**< Test limit for parity files. */
|
||||
int skip_multi_scan; /**< Don't use threads in scan. */
|
||||
};
|
||||
|
||||
struct snapraid_state {
|
||||
|
@ -39,14 +39,6 @@ unsigned day_ago(time_t ref, time_t now)
|
||||
#define GRAPH_COLUMN 70
|
||||
#define GRAPH_ROW 15
|
||||
|
||||
static unsigned perc(uint64_t part, uint64_t total)
|
||||
{
|
||||
if (!total)
|
||||
return 0;
|
||||
|
||||
return (unsigned)(part * 100 / total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bit used to mark unscrubbed time info.
|
||||
*/
|
||||
@ -239,7 +231,7 @@ int state_status(struct snapraid_state* state)
|
||||
printf(" - ");
|
||||
} else {
|
||||
printf("%8" PRIu64, (disk_block_max - disk_block_count) * (uint64_t)state->block_size / GIGA);
|
||||
printf(" %3u%%", perc(disk_block_count, disk_block_max));
|
||||
printf(" %3u%%", muldiv(disk_block_count, 100, disk_block_max));
|
||||
}
|
||||
printf(" %s\n", disk->name);
|
||||
|
||||
@ -266,7 +258,7 @@ int state_status(struct snapraid_state* state)
|
||||
printf("%8.1f", (double)all_wasted / GIGA);
|
||||
printf("%8" PRIu64, file_size / GIGA);
|
||||
printf("%8" PRIu64, file_block_free * state->block_size / GIGA);
|
||||
printf(" %3u%%", perc(file_block_count, file_block_count + file_block_free));
|
||||
printf(" %3u%%", muldiv(file_block_count, 100, file_block_count + file_block_free));
|
||||
printf("\n");
|
||||
|
||||
/* warn about invalid data free info */
|
||||
@ -468,26 +460,26 @@ int state_status(struct snapraid_state* state)
|
||||
|
||||
if (unsynced_blocks) {
|
||||
printf("WARNING! The array is NOT fully synced.\n");
|
||||
printf("You have a sync in progress at %u%%.\n", (blockmax - unsynced_blocks) * 100 / blockmax);
|
||||
printf("You have a sync in progress at %u%%.\n", muldiv(blockmax - unsynced_blocks, 100, blockmax));
|
||||
} else {
|
||||
printf("No sync is in progress.\n");
|
||||
}
|
||||
|
||||
if (unscrubbed_blocks) {
|
||||
printf("The %u%% of the array is not scrubbed.\n", (unscrubbed_blocks * 100 + blockmax - 1) / blockmax);
|
||||
printf("%u%% of the array is not scrubbed.\n", muldiv_upper(unscrubbed_blocks, 100, blockmax));
|
||||
} else {
|
||||
printf("The full array was scrubbed at least one time.\n");
|
||||
}
|
||||
|
||||
if (file_zerosubsecond) {
|
||||
printf("You have %u files with zero sub-second timestamp.\n", file_zerosubsecond);
|
||||
printf("Run the 'touch' command to set it to a not zero value.\n");
|
||||
printf("You have %u files with a zero sub-second timestamp.\n", file_zerosubsecond);
|
||||
printf("Run 'snapraid touch' to set their sub-second timestamps to a non-zero value.\n");
|
||||
} else {
|
||||
printf("No file has a zero sub-second timestamp.\n");
|
||||
}
|
||||
|
||||
if (rehash) {
|
||||
printf("You have a rehash in progress at %u%%.\n", (count - rehash) * 100 / count);
|
||||
printf("You have a rehash in progress at %u%%.\n", muldiv(count - rehash, 100, count));
|
||||
} else {
|
||||
if (state->besthash != state->hash) {
|
||||
printf("No rehash is in progress, but for optimal performance one is recommended.\n");
|
||||
|
@ -426,7 +426,7 @@ const char* esc_tag(const char* str, char* buffer)
|
||||
|
||||
bail:
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Escape for log too long\n");
|
||||
log_fatal("Escape for log is too long\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -587,7 +587,7 @@ const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer
|
||||
|
||||
bail:
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Escape for shell too long\n");
|
||||
log_fatal("Escape for shell is too long\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -663,6 +663,20 @@ void pathcat(char* dst, size_t size, const char* src)
|
||||
memcpy(dst + dst_len, src, src_len + 1);
|
||||
}
|
||||
|
||||
void pathcatl(char* dst, size_t dst_len, size_t size, const char* src)
|
||||
{
|
||||
size_t src_len = strlen(src);
|
||||
|
||||
if (dst_len + src_len + 1 > size) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Path too long '%s%s'\n", dst, src);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
memcpy(dst + dst_len, src, src_len + 1);
|
||||
}
|
||||
|
||||
void pathcatc(char* dst, size_t size, char c)
|
||||
{
|
||||
size_t dst_len = strlen(dst);
|
||||
|
@ -265,6 +265,12 @@ void pathcpy(char* dst, size_t size, const char* src);
|
||||
*/
|
||||
void pathcat(char* dst, size_t size, const char* src);
|
||||
|
||||
/**
|
||||
* Concatenate a path limiting the size knowing the length.
|
||||
* Abort if too long.
|
||||
*/
|
||||
void pathcatl(char* dst, size_t dst_len, size_t size, const char* src);
|
||||
|
||||
/**
|
||||
* Concatenate a path limiting the size.
|
||||
* Abort if too long.
|
||||
|
@ -1456,7 +1456,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
||||
|
||||
if (blockstart > blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in the starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
|
||||
log_fatal("Error in the starting block %u. It is larger than the parity size %u.\n", blockstart, blockmax);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@ -1485,7 +1485,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
||||
|
||||
/* if the file is too small */
|
||||
if (parityblocks < used_paritymax) {
|
||||
log_fatal("WARNING! The %s parity has data only %u blocks instead of %u.\n", lev_name(l), parityblocks, used_paritymax);
|
||||
log_fatal("WARNING! The %s parity has only %u blocks instead of %u.\n", lev_name(l), parityblocks, used_paritymax);
|
||||
}
|
||||
|
||||
/* keep the smallest parity number of blocks */
|
||||
|
@ -58,7 +58,7 @@ void state_touch(struct snapraid_state* state)
|
||||
/* get a random nanosecond value */
|
||||
if (randomize(&nano, sizeof(nano)) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed to get random values.\n");
|
||||
log_fatal("Failed to retrieve random values.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
@ -474,7 +474,7 @@ static int devuuid_dev(uint64_t device, char* uuid, size_t uuid_size)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the UUID using liblkid.
|
||||
* Get the UUID using libblkid.
|
||||
* It uses a cache to work without root permission, resulting in UUID
|
||||
* not necessarily recent.
|
||||
* We could call blkid_probe_all() to refresh the UUID, but it would
|
||||
|
@ -672,3 +672,22 @@ int lock_unlock(int f)
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* muldiv */
|
||||
|
||||
unsigned muldiv(uint64_t v, uint64_t mul, uint64_t div)
|
||||
{
|
||||
if (!div)
|
||||
return 0;
|
||||
|
||||
return (uint32_t)(v * mul / div);
|
||||
}
|
||||
|
||||
unsigned muldiv_upper(uint64_t v, uint64_t mul, uint64_t div)
|
||||
{
|
||||
if (!div)
|
||||
return 0;
|
||||
|
||||
return (uint32_t)((v * mul + div - 1) / div);
|
||||
}
|
||||
|
||||
|
@ -251,5 +251,10 @@ static inline int bit_vect_test(bit_vect_t* bit_vect, size_t off)
|
||||
return (bit_vect[off / BIT_VECT_SIZE] & mask) != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
/****************************************************************************/
|
||||
/* muldiv */
|
||||
|
||||
unsigned muldiv(uint64_t v, uint64_t mul, uint64_t div);
|
||||
unsigned muldiv_upper(uint64_t v, uint64_t mul, uint64_t div);
|
||||
|
||||
#endif
|
||||
|
347
compile
347
compile
@ -1,347 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand '-c -o'.
|
||||
|
||||
scriptversion=2012-10-14.11; # UTC
|
||||
|
||||
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# We need space, tab and new line, in precisely that order. Quoting is
|
||||
# there to prevent tools from complaining about whitespace usage.
|
||||
IFS=" "" $nl"
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file lazy
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts. If the determined conversion
|
||||
# type is listed in (the comma separated) LAZY, no conversion will
|
||||
# take place.
|
||||
func_file_conv ()
|
||||
{
|
||||
file=$1
|
||||
case $file in
|
||||
/ | /[!/]*) # absolute file, and not a UNC file
|
||||
if test -z "$file_conv"; then
|
||||
# lazily determine how to convert abs files
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
file_conv=wine
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
case $file_conv/,$2, in
|
||||
*,$file_conv,*)
|
||||
;;
|
||||
mingw/*)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin/*)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine/*)
|
||||
file=`winepath -w "$file" || echo "$file"`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# func_cl_dashL linkdir
|
||||
# Make cl look for libraries in LINKDIR
|
||||
func_cl_dashL ()
|
||||
{
|
||||
func_file_conv "$1"
|
||||
if test -z "$lib_path"; then
|
||||
lib_path=$file
|
||||
else
|
||||
lib_path="$lib_path;$file"
|
||||
fi
|
||||
linker_opts="$linker_opts -LIBPATH:$file"
|
||||
}
|
||||
|
||||
# func_cl_dashl library
|
||||
# Do a library search-path lookup for cl
|
||||
func_cl_dashl ()
|
||||
{
|
||||
lib=$1
|
||||
found=no
|
||||
save_IFS=$IFS
|
||||
IFS=';'
|
||||
for dir in $lib_path $LIB
|
||||
do
|
||||
IFS=$save_IFS
|
||||
if $shared && test -f "$dir/$lib.dll.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.dll.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/$lib.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/lib$lib.a"; then
|
||||
found=yes
|
||||
lib=$dir/lib$lib.a
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$save_IFS
|
||||
|
||||
if test "$found" != yes; then
|
||||
lib=$lib.lib
|
||||
fi
|
||||
}
|
||||
|
||||
# func_cl_wrapper cl arg...
|
||||
# Adjust compile command to suit cl
|
||||
func_cl_wrapper ()
|
||||
{
|
||||
# Assume a capable shell
|
||||
lib_path=
|
||||
shared=:
|
||||
linker_opts=
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.[oO][bB][jJ])
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fo"$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fe"$file"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-I)
|
||||
eat=1
|
||||
func_file_conv "$2" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-I*)
|
||||
func_file_conv "${1#-I}" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-l)
|
||||
eat=1
|
||||
func_cl_dashl "$2"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-l*)
|
||||
func_cl_dashl "${1#-l}"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-L)
|
||||
eat=1
|
||||
func_cl_dashL "$2"
|
||||
;;
|
||||
-L*)
|
||||
func_cl_dashL "${1#-L}"
|
||||
;;
|
||||
-static)
|
||||
shared=false
|
||||
;;
|
||||
-Wl,*)
|
||||
arg=${1#-Wl,}
|
||||
save_ifs="$IFS"; IFS=','
|
||||
for flag in $arg; do
|
||||
IFS="$save_ifs"
|
||||
linker_opts="$linker_opts $flag"
|
||||
done
|
||||
IFS="$save_ifs"
|
||||
;;
|
||||
-Xlinker)
|
||||
eat=1
|
||||
linker_opts="$linker_opts $2"
|
||||
;;
|
||||
-*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
||||
func_file_conv "$1"
|
||||
set x "$@" -Tp"$file"
|
||||
shift
|
||||
;;
|
||||
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
||||
func_file_conv "$1" mingw
|
||||
set x "$@" "$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
if test -n "$linker_opts"; then
|
||||
linker_opts="-link$linker_opts"
|
||||
fi
|
||||
exec "$@" $linker_opts
|
||||
exit 1
|
||||
}
|
||||
|
||||
eat=
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand '-c -o'.
|
||||
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file 'INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
|
||||
func_cl_wrapper "$@" # Doesn't return...
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
# So we strip '-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no '-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# '.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
1421
config.guess
vendored
1421
config.guess
vendored
File diff suppressed because it is too large
Load Diff
420
config.h.in
420
config.h.in
@ -1,420 +0,0 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
#undef AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
/* Define to 1 if you have the `access' function. */
|
||||
#undef HAVE_ACCESS
|
||||
|
||||
/* Define to 1 if inline assembly should be used. */
|
||||
#undef HAVE_ASSEMBLY
|
||||
|
||||
/* Define to 1 if avx2 is supported by the assembler. */
|
||||
#undef HAVE_AVX2
|
||||
|
||||
/* Define to 1 if you have the `backtrace' function. */
|
||||
#undef HAVE_BACKTRACE
|
||||
|
||||
/* Define to 1 if you have the `backtrace_symbols' function. */
|
||||
#undef HAVE_BACKTRACE_SYMBOLS
|
||||
|
||||
/* Define to 1 if you have the <blkid/blkid.h> header file. */
|
||||
#undef HAVE_BLKID_BLKID_H
|
||||
|
||||
/* Define to 1 if you have the `blkid_devno_to_devname' function. */
|
||||
#undef HAVE_BLKID_DEVNO_TO_DEVNAME
|
||||
|
||||
/* Define to 1 if you have the `blkid_get_tag_value' function. */
|
||||
#undef HAVE_BLKID_GET_TAG_VALUE
|
||||
|
||||
/* Define to 1 if you have the <byteswap.h> header file. */
|
||||
#undef HAVE_BYTESWAP_H
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#undef HAVE_CLOCK_GETTIME
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define to 1 if you have the <execinfo.h> header file. */
|
||||
#undef HAVE_EXECINFO_H
|
||||
|
||||
/* Define to 1 if you have the `fallocate' function. */
|
||||
#undef HAVE_FALLOCATE
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the `ferror_unlocked' function. */
|
||||
#undef HAVE_FERROR_UNLOCKED
|
||||
|
||||
/* Define to 1 if you have the `flock' function. */
|
||||
#undef HAVE_FLOCK
|
||||
|
||||
/* Define to 1 if you have the `fnmatch' function. */
|
||||
#undef HAVE_FNMATCH
|
||||
|
||||
/* Define to 1 if you have the <fnmatch.h> header file. */
|
||||
#undef HAVE_FNMATCH_H
|
||||
|
||||
/* Define to 1 if you have the `fstatat' function. */
|
||||
#undef HAVE_FSTATAT
|
||||
|
||||
/* Define to 1 if you have the `fsync' function. */
|
||||
#undef HAVE_FSYNC
|
||||
|
||||
/* Define to 1 if you have the `ftruncate' function. */
|
||||
#undef HAVE_FTRUNCATE
|
||||
|
||||
/* Define to 1 if you have the `futimens' function. */
|
||||
#undef HAVE_FUTIMENS
|
||||
|
||||
/* Define to 1 if you have the `futimes' function. */
|
||||
#undef HAVE_FUTIMES
|
||||
|
||||
/* Define to 1 if you have the `futimesat' function. */
|
||||
#undef HAVE_FUTIMESAT
|
||||
|
||||
/* Define to 1 if you have the `getc_unlocked' function. */
|
||||
#undef HAVE_GETC_UNLOCKED
|
||||
|
||||
/* Define to 1 if you have the `getopt' function. */
|
||||
#undef HAVE_GETOPT
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#undef HAVE_GETOPT_H
|
||||
|
||||
/* Define to 1 if you have the `getopt_long' function. */
|
||||
#undef HAVE_GETOPT_LONG
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <io.h> header file. */
|
||||
#undef HAVE_IO_H
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if you have the <linux/fiemap.h> header file. */
|
||||
#undef HAVE_LINUX_FIEMAP_H
|
||||
|
||||
/* Define to 1 if you have the <linux/fs.h> header file. */
|
||||
#undef HAVE_LINUX_FS_H
|
||||
|
||||
/* Define to 1 if you have the `localtime_r' function. */
|
||||
#undef HAVE_LOCALTIME_R
|
||||
|
||||
/* Define to 1 if you have the `lutimes' function. */
|
||||
#undef HAVE_LUTIMES
|
||||
|
||||
/* Define to 1 if you have the `mach_absolute_time' function. */
|
||||
#undef HAVE_MACH_ABSOLUTE_TIME
|
||||
|
||||
/* Define to 1 if you have the <mach/mach_time.h> header file. */
|
||||
#undef HAVE_MACH_MACH_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <math.h> header file. */
|
||||
#undef HAVE_MATH_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#undef HAVE_MEMSET
|
||||
|
||||
/* Define to 1 if you have the `mkdir' function. */
|
||||
#undef HAVE_MKDIR
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the `posix_fadvise' function. */
|
||||
#undef HAVE_POSIX_FADVISE
|
||||
|
||||
/* Define to 1 if you have the `pthread_create' function. */
|
||||
#undef HAVE_PTHREAD_CREATE
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
#undef HAVE_PTHREAD_H
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
/* Define to 1 if sse2 is supported by the assembler. */
|
||||
#undef HAVE_SSE2
|
||||
|
||||
/* Define to 1 if sse4.2 is supported by the assembler. */
|
||||
#undef HAVE_SSE42
|
||||
|
||||
/* Define to 1 if ssse3 is supported by the assembler. */
|
||||
#undef HAVE_SSSE3
|
||||
|
||||
/* Define to 1 if you have the `statfs' function. */
|
||||
#undef HAVE_STATFS
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#undef HAVE_STDDEF_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#undef HAVE_STRCHR
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strrchr' function. */
|
||||
#undef HAVE_STRRCHR
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#undef HAVE_STRTOUL
|
||||
|
||||
/* Define to 1 if `d_ino' is a member of `struct dirent'. */
|
||||
#undef HAVE_STRUCT_DIRENT_D_INO
|
||||
|
||||
/* Define to 1 if `d_type' is a member of `struct dirent'. */
|
||||
#undef HAVE_STRUCT_DIRENT_D_TYPE
|
||||
|
||||
/* Define to 1 if `f_fstypename' is a member of `struct statfs'. */
|
||||
#undef HAVE_STRUCT_STATFS_F_FSTYPENAME
|
||||
|
||||
/* Define to 1 if `f_type' is a member of `struct statfs'. */
|
||||
#undef HAVE_STRUCT_STATFS_F_TYPE
|
||||
|
||||
/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_MTIMENSEC
|
||||
|
||||
/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
||||
|
||||
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
|
||||
/* Define to 1 if `st_nlink' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_NLINK
|
||||
|
||||
/* Define to 1 if you have the `sync_file_range' function. */
|
||||
#undef HAVE_SYNC_FILE_RANGE
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#undef HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mkdev.h> header file. */
|
||||
#undef HAVE_SYS_MKDEV_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mount.h> header file. */
|
||||
#undef HAVE_SYS_MOUNT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/statfs.h> header file. */
|
||||
#undef HAVE_SYS_STATFS_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sysmacros.h> header file. */
|
||||
#undef HAVE_SYS_SYSMACROS_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/vfs.h> header file. */
|
||||
#undef HAVE_SYS_VFS_H
|
||||
|
||||
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `utimensat' function. */
|
||||
#undef HAVE_UTIMENSAT
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
/* Define to 1 if assertions should be disabled. */
|
||||
#undef NDEBUG
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
# undef WORDS_BIGENDIAN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
#undef _UINT32_T
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
#undef _UINT64_T
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
#undef _UINT8_T
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to the type of a signed integer type of width exactly 8 bits if such
|
||||
a type exists and the standard includes do not define it. */
|
||||
#undef int8_t
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
#undef off_t
|
||||
|
||||
/* Define to the equivalent of the C99 'restrict' keyword, or to
|
||||
nothing if this is not supported. Do not define if restrict is
|
||||
supported directly. */
|
||||
#undef restrict
|
||||
/* Work around a bug in Sun C++: it does not support _Restrict or
|
||||
__restrict__, even though the corresponding Sun C compiler ends up with
|
||||
"#define restrict _Restrict" or "#define restrict __restrict__" in the
|
||||
previous line. Perhaps some future version of Sun C++ will work with
|
||||
restrict; if so, hopefully it defines __RESTRICT like Sun C does. */
|
||||
#if defined __SUNPRO_CC && !defined __RESTRICT
|
||||
# define _Restrict
|
||||
# define __restrict__
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef ssize_t
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 32 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef uint32_t
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 64 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef uint64_t
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 8 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef uint8_t
|
||||
|
||||
/* Define to empty if the keyword `volatile' does not work. Warning: valid
|
||||
code using `volatile' can become incorrect without. Disable with care. */
|
||||
#undef volatile
|
1807
config.sub
vendored
1807
config.sub
vendored
File diff suppressed because it is too large
Load Diff
58
configure.ac
58
configure.ac
@ -12,7 +12,7 @@ dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind],[])
|
||||
AC_CHECK_PROG([WINE],[wine],[wine],[])
|
||||
AC_CHECK_PROG([WINE],[wine64],[wine64],[])
|
||||
AC_CHECK_PROG([SDE],[sde],[sde],[])
|
||||
AC_CHECK_PROG([ADVD2],[advd2],[advd2],[])
|
||||
AM_CONDITIONAL(HAVE_ADVD2, [test x"$ADVD2" != x])
|
||||
@ -36,7 +36,7 @@ AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS([fcntl.h stddef.h stdint.h stdlib.h string.h limits.h])
|
||||
AC_CHECK_HEADERS([unistd.h getopt.h fnmatch.h io.h inttypes.h byteswap.h])
|
||||
AC_CHECK_HEADERS([pthread.h math.h])
|
||||
AC_CHECK_HEADERS([sys/file.h sys/ioctl.h sys/vfs.h sys/statfs.h sys/param.h sys/mount.h sys/sysmacros.h sys/mkdev.h])
|
||||
AC_CHECK_HEADERS([sys/file.h sys/ioctl.h sys/sysmacros.h sys/mkdev.h])
|
||||
AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h mach/mach_time.h execinfo.h])
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
@ -65,6 +65,38 @@ AC_CHECK_MEMBERS([struct stat.st_nlink, struct stat.st_mtim.tv_nsec, struct stat
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
]])
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS([memset strchr strerror strrchr mkdir gettimeofday strtoul])
|
||||
AC_CHECK_FUNCS([getopt getopt_long snprintf vsnprintf sigaction])
|
||||
AC_CHECK_FUNCS([ftruncate fallocate access])
|
||||
AC_CHECK_FUNCS([fsync posix_fadvise sync_file_range])
|
||||
AC_CHECK_FUNCS([getc_unlocked ferror_unlocked fnmatch])
|
||||
AC_CHECK_FUNCS([futimes futimens futimesat localtime_r lutimes utimensat])
|
||||
AC_CHECK_FUNCS([fstatat flock])
|
||||
AC_CHECK_FUNCS([mach_absolute_time])
|
||||
AC_CHECK_FUNCS([backtrace backtrace_symbols])
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
AC_CHECK_FUNCS([clock_gettime])
|
||||
AC_CHECK_CC_OPT([-pthread], CFLAGS="$CFLAGS -pthread", CFLAGS="$CFLAGS -D_REENTRANT")
|
||||
AC_CHECK_FUNCS([pthread_create])
|
||||
AC_SEARCH_LIBS([exp], [m])
|
||||
|
||||
dnl Checks for statfs for linux avoiding to include sys/mount.h that is required only in darwin
|
||||
dnl In glibc since 7eae6a91e9b1670330c9f15730082c91c0b1d570, milestone 2.36, sys/mount.h defines fsconfig_command which conflicts with linux/mount.h
|
||||
AC_CHECK_HEADERS([sys/vfs.h sys/statfs.h])
|
||||
AC_CHECK_DECLS([statfs], [], [
|
||||
AC_CHECK_HEADERS([sys/param.h sys/mount.h])
|
||||
], [[
|
||||
#if HAVE_SYS_VFS_H
|
||||
#include <sys/vfs.h>
|
||||
#endif
|
||||
#if HAVE_SYS_STATFS_H
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
]])
|
||||
AC_CHECK_FUNCS([statfs])
|
||||
|
||||
AC_CHECK_MEMBERS([struct statfs.f_type], [], [], [[
|
||||
#if HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
@ -79,6 +111,7 @@ AC_CHECK_MEMBERS([struct statfs.f_type], [], [], [[
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
]])
|
||||
|
||||
AC_CHECK_MEMBERS([struct statfs.f_fstypename], [], [], [[
|
||||
#if HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
@ -94,22 +127,6 @@ AC_CHECK_MEMBERS([struct statfs.f_fstypename], [], [], [[
|
||||
#endif
|
||||
]])
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS([memset strchr strerror strrchr mkdir gettimeofday strtoul])
|
||||
AC_CHECK_FUNCS([getopt getopt_long snprintf vsnprintf sigaction])
|
||||
AC_CHECK_FUNCS([ftruncate fallocate access])
|
||||
AC_CHECK_FUNCS([fsync posix_fadvise sync_file_range])
|
||||
AC_CHECK_FUNCS([getc_unlocked ferror_unlocked fnmatch])
|
||||
AC_CHECK_FUNCS([futimes futimens futimesat localtime_r lutimes utimensat])
|
||||
AC_CHECK_FUNCS([fstatat flock statfs])
|
||||
AC_CHECK_FUNCS([mach_absolute_time])
|
||||
AC_CHECK_FUNCS([backtrace backtrace_symbols])
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
AC_CHECK_FUNCS([clock_gettime])
|
||||
AC_CHECK_CC_OPT([-pthread], CFLAGS="$CFLAGS -pthread", CFLAGS="$CFLAGS -D_REENTRANT")
|
||||
AC_CHECK_FUNCS([pthread_create])
|
||||
AC_SEARCH_LIBS([exp], [m])
|
||||
|
||||
dnl Checks for libblkid
|
||||
AC_ARG_WITH([blkid],
|
||||
AS_HELP_STRING([--without-blkid], [Ignore presence of blkid and disable it]))
|
||||
@ -135,6 +152,9 @@ AC_CHECK_CC_OPT([-Wextra], CFLAGS="$CFLAGS -Wextra", [])
|
||||
AC_CHECK_CC_OPT([-Wuninitialized], CFLAGS="$CFLAGS -Wuninitialized", [])
|
||||
AC_CHECK_CC_OPT([-Wshadow], CFLAGS="$CFLAGS -Wshadow", [])
|
||||
|
||||
dnl Disable warning about zero-length-bounds raised by gcc 10 on linux kernel header on the fm_extents field
|
||||
AC_CHECK_CC_OPT([-Wno-zero-length-bounds], CFLAGS="$CFLAGS -Wno-zero-length-bounds", [])
|
||||
|
||||
dnl Checks for asm
|
||||
AC_ARG_ENABLE([asm],
|
||||
AS_HELP_STRING([--disable-asm], [Disable inline assembly]))
|
||||
@ -179,7 +199,7 @@ dnl Checks for AS supporting the SSE4.2 instructions.
|
||||
AC_MSG_CHECKING([for sse42])
|
||||
asmsse42=no
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
unsigned f(unsigned crc, unsigned char b)
|
||||
{
|
||||
asm volatile("crc32b %1, %0" : "+r" (crc) : "rm" (b));
|
||||
|
46
debian/changelog
vendored
Normal file
46
debian/changelog
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
snapraid (12.4-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 12.4
|
||||
|
||||
-- Mo Zhou <lumin@debian.org> Mon, 27 Jan 2025 00:21:49 -0500
|
||||
|
||||
snapraid (12.3-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 12.3
|
||||
|
||||
-- Mo Zhou <lumin@debian.org> Thu, 15 Feb 2024 13:56:08 -0500
|
||||
|
||||
snapraid (12.2-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 12.2
|
||||
|
||||
-- Mo Zhou <lumin@debian.org> Thu, 08 Sep 2022 21:54:28 -0400
|
||||
|
||||
snapraid (12.1-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 12.1
|
||||
|
||||
-- Mo Zhou <lumin@debian.org> Sun, 30 Jan 2022 12:47:06 -0500
|
||||
|
||||
snapraid (12.0-1) unstable; urgency=medium
|
||||
|
||||
[ Debian Janitor ]
|
||||
* Trim trailing whitespace.
|
||||
* Set upstream metadata fields: Repository, Repository-Browse.
|
||||
|
||||
[ Mo Zhou ]
|
||||
* New upstream version 12.0 (Closes: #995324)
|
||||
|
||||
-- Mo Zhou <lumin@debian.org> Sat, 08 Jan 2022 11:49:08 -0500
|
||||
|
||||
snapraid (11.5-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 11.5
|
||||
|
||||
-- Mo Zhou <lumin@debian.org> Sat, 25 Jul 2020 15:20:50 +0800
|
||||
|
||||
snapraid (11.4-1~exp1) experimental; urgency=medium
|
||||
|
||||
* Initial release. (Closes: #960816)
|
||||
|
||||
-- Mo Zhou <lumin@debian.org> Fri, 22 May 2020 00:42:52 +0800
|
43
debian/control
vendored
Normal file
43
debian/control
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
Source: snapraid
|
||||
Section: admin
|
||||
Homepage: https://github.com/amadvance/snapraid
|
||||
Priority: optional
|
||||
Standards-Version: 4.5.0
|
||||
Vcs-Git: https://salsa.debian.org/debian/snapraid.git
|
||||
Vcs-Browser: https://salsa.debian.org/debian/snapraid
|
||||
Maintainer: Mo Zhou <lumin@debian.org>
|
||||
Rules-Requires-Root: no
|
||||
Build-Depends: debhelper-compat (= 12),
|
||||
|
||||
Package: snapraid
|
||||
Architecture: any
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends},
|
||||
Pre-Depends: ${misc:Pre-Depends},
|
||||
Description: backup program for disk arrays
|
||||
SnapRAID is a backup program for disk arrays. It stores parity
|
||||
information of your data and it recovers from up to six disk
|
||||
failures.
|
||||
.
|
||||
SnapRAID is mainly targeted for a home media center, where you
|
||||
have a lot of big files that rarely change.
|
||||
.
|
||||
Beside the ability to recover from disk failures, the other
|
||||
features of SnapRAID are:
|
||||
.
|
||||
* You can use disk already filled with files, without the need to
|
||||
reformat them. You will access them like now.
|
||||
* All your data is hashed to ensure data integrity and to avoid
|
||||
silent corruption.
|
||||
* If the failed disks are too many to allow a recovery,
|
||||
you lose the data only on the failed disks.
|
||||
All the data in the other disks is safe.
|
||||
* If you accidentally delete some files in a disk, you can
|
||||
recover them.
|
||||
* The disks can have different sizes.
|
||||
* You can add disks at any time.
|
||||
* It doesn't lock-in your data. You can stop using SnapRAID at any
|
||||
time without the need to reformat or move data.
|
||||
* To access a file, only a single disk needs to spin, saving power and
|
||||
producing less noise.
|
||||
.
|
||||
The official site of SnapRAID is: http://www.snapraid.it/
|
166
debian/copyright
vendored
Normal file
166
debian/copyright
vendored
Normal file
@ -0,0 +1,166 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Source: https://github.com/amadvance/snapraid
|
||||
|
||||
Files: *
|
||||
cmdline/*
|
||||
Copyright: 2011-2016, Andrea Mazzoleni
|
||||
License: GPL-3.0+
|
||||
|
||||
Files: raid/*
|
||||
Copyright: 2013-2015, Andrea Mazzoleni
|
||||
License: GPL-2.0+
|
||||
|
||||
Files: tommyds/*
|
||||
Copyright: 2010, Andrea Mazzoleni.
|
||||
License: BSD-2-Clause
|
||||
|
||||
Files: cmdline/fnmatch.c
|
||||
cmdline/fnmatch.h
|
||||
Copyright: 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
|
||||
License: LGPL-2.0+
|
||||
|
||||
Files: cmdline/metro.c
|
||||
Copyright: 2019, Andrea Mazzoleni
|
||||
License: Apache-2.0 AND GPL-3.0+
|
||||
|
||||
Files: cmdline/murmur3.c
|
||||
Copyright: 2011, Andrea Mazzoleni
|
||||
License: GPL-3.0+ AND public-domain
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2020, Mo Zhou <lumin@debian.org>
|
||||
License: LGPL-3.0+
|
||||
|
||||
##############################################################################
|
||||
|
||||
License: public-domain
|
||||
This is free and unencumbered software released into the public domain.
|
||||
.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
.
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
.
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
|
||||
License: GPL-2.0+
|
||||
This package is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
|
||||
License: GPL-3.0+
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
|
||||
License: Apache-2.0
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
.
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
.
|
||||
On Debian systems, the complete text of the Apache version 2.0 license
|
||||
can be found in "/usr/share/common-licenses/Apache-2.0".
|
||||
|
||||
License: BSD-2-Clause
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
License: LGPL-2.0+
|
||||
This package is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU Lesser General
|
||||
Public License can be found in "/usr/share/common-licenses/LGPL-2.0".
|
||||
|
||||
License: LGPL-3.0+
|
||||
This package is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU Lesser General
|
||||
Public License can be found in "/usr/share/common-licenses/LGPL-3".
|
5
debian/rules
vendored
Executable file
5
debian/rules
vendored
Executable file
@ -0,0 +1,5 @@
|
||||
#!/usr/bin/make -f
|
||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||
|
||||
%:
|
||||
dh $@
|
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
3
debian/upstream/metadata
vendored
Normal file
3
debian/upstream/metadata
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
Repository: https://github.com/amadvance/snapraid.git
|
||||
Repository-Browse: https://github.com/amadvance/snapraid
|
5
debian/watch
vendored
Normal file
5
debian/watch
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
version=4
|
||||
opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%snapraid-$1.tar.gz%" \
|
||||
https://github.com/amadvance/snapraid/tags \
|
||||
(?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate
|
||||
|
501
install-sh
501
install-sh
@ -1,501 +0,0 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2013-12-25.23; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# 'make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
tab=' '
|
||||
nl='
|
||||
'
|
||||
IFS=" $tab$nl"
|
||||
|
||||
# Set DOITPROG to "echo" to test this script.
|
||||
|
||||
doit=${DOITPROG-}
|
||||
doit_exec=${doit:-exec}
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
is_target_a_directory=possibly
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-T) is_target_a_directory=never;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# We allow the use of options -d and -T together, by making -d
|
||||
# take the precedence; this is for compatibility with GNU install.
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
if test -n "$dst_arg"; then
|
||||
echo "$0: target directory not allowed when installing a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call 'install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
||||
if test ! -d "$dst_arg"; then
|
||||
echo "$0: $dst_arg: Is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst_arg
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test "$is_target_a_directory" = never; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
dstdir=`dirname "$dst"`
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test X"$d" = X && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
set +f &&
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
16
makecov.sh
Executable file
16
makecov.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Run the Coverage test
|
||||
#
|
||||
|
||||
make distclean
|
||||
|
||||
if ! ./configure --enable-coverage --enable-sde; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make lcov_reset check lcov_capture lcov_html; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
47
makedist.sh
Executable file
47
makedist.sh
Executable file
@ -0,0 +1,47 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
|
||||
CHECK=check
|
||||
DEBUG=
|
||||
|
||||
if test "x$1" = "x-f"; then
|
||||
CHECK=all
|
||||
fi
|
||||
|
||||
if test "x$1" = "x-d"; then
|
||||
DEBUG=--enable-debug
|
||||
fi
|
||||
|
||||
make distclean
|
||||
|
||||
# Reconfigure (with force) to get the latest revision from git
|
||||
autoreconf -f
|
||||
|
||||
if ! ./configure.windows-x86 $DEBUG; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make distwindows-x86 distclean; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! ./configure.windows-x64 $DEBUG; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make -j4 $CHECK; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make distwindows-x64 distclean; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! ./configure ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make dist; then
|
||||
exit 1
|
||||
fi
|
||||
|
67
makesan.sh
Executable file
67
makesan.sh
Executable file
@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Run all the Sanitizers available
|
||||
#
|
||||
|
||||
# Compiler to use
|
||||
COMPILER=clang
|
||||
|
||||
# Options for configure
|
||||
# --disable-asm
|
||||
# Inline assembly is not supported by the Sanitizers
|
||||
# --without-blkid
|
||||
# External libraries are not supported by the Sanitizers
|
||||
OPTIONS="--disable-asm --without-blkid"
|
||||
|
||||
# Source directory
|
||||
SOURCE=`pwd`
|
||||
|
||||
# Dest directory
|
||||
DEST=`mktemp -d`
|
||||
|
||||
make distclean
|
||||
|
||||
cd $DEST
|
||||
|
||||
# AddressSanitizer
|
||||
if ! $SOURCE/configure --enable-asan $OPTIONS CC=$COMPILER; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make check distclean; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# UndefinedBehaviourSanitizer
|
||||
if ! $SOURCE/configure --enable-ubsan $OPTIONS CC=$COMPILER; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make check distclean; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# MemorySanitizer
|
||||
if ! $SOURCE/configure --enable-msan $OPTIONS CC=$COMPILER; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make check distclean; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ThreadSanitizer
|
||||
if ! $SOURCE/configure --enable-tsan $OPTIONS CC=$COMPILER; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make check distclean; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $SOURCE
|
||||
|
||||
if ! ./configure; then
|
||||
exit 1
|
||||
fi
|
||||
|
30
makescan.sh
Executable file
30
makescan.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Run the Coverity Scan static analyzer
|
||||
#
|
||||
|
||||
rm -r cov-int
|
||||
|
||||
make distclean
|
||||
|
||||
# Reconfigure (with force) to get the latest revision from git
|
||||
autoreconf -f
|
||||
|
||||
if ! ./configure ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export PATH=$PATH:contrib/cov-analysis-linux64-2020.09/bin
|
||||
|
||||
if ! cov-build --dir cov-int make; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REVISION=`sh autover.sh`
|
||||
|
||||
tar czf snapraid-$REVISION.tgz cov-int
|
||||
|
||||
rm -r cov-int
|
||||
|
||||
echo snapraid-$REVISION.tgz ready to upload to https://scan.coverity.com/projects/1986/builds/new
|
||||
|
5
makesum.sh
Executable file
5
makesum.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo sha256 > CHECKSUMS
|
||||
cd archive && sha256sum * | sort -k 2 -V >> ../CHECKSUMS
|
||||
|
63
maketest.sh
Executable file
63
maketest.sh
Executable file
@ -0,0 +1,63 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Run all the Coverage and Valgrind tests
|
||||
#
|
||||
|
||||
# Source directory
|
||||
SOURCE=`pwd`
|
||||
|
||||
# Dest directory
|
||||
DEST=`mktemp -d`
|
||||
|
||||
make distclean
|
||||
|
||||
cd $DEST
|
||||
|
||||
# Coverage
|
||||
if ! $SOURCE/configure --enable-coverage --enable-sde; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make lcov_reset check lcov_capture lcov_html; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp -a cov $SOURCE/cov
|
||||
|
||||
if ! make distclean; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Valgrind
|
||||
if ! $SOURCE/configure --enable-valgrind; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make check distclean; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Helgrind
|
||||
if ! $SOURCE/configure --enable-helgrind; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make check distclean; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Drd
|
||||
if ! $SOURCE/configure --enable-drd; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! make check distclean; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $SOURCE
|
||||
|
||||
if ! ./configure; then
|
||||
exit 1
|
||||
fi
|
||||
|
215
missing
215
missing
@ -1,215 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Common wrapper for a few potentially missing GNU programs.
|
||||
|
||||
scriptversion=2013-10-28.13; # UTC
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
|
||||
--is-lightweight)
|
||||
# Used by our autoconf macros to check whether the available missing
|
||||
# script is modern enough.
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--run)
|
||||
# Back-compat with the calling convention used by older automake.
|
||||
shift
|
||||
;;
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
||||
to PROGRAM being missing or too old.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal autoconf autoheader autom4te automake makeinfo
|
||||
bison yacc flex lex help2man
|
||||
|
||||
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
|
||||
'g' are ignored when checking the name.
|
||||
|
||||
Send bug reports to <bug-automake@gnu.org>."
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing $scriptversion (GNU Automake)"
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: unknown '$1' option"
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Run the given program, remember its exit status.
|
||||
"$@"; st=$?
|
||||
|
||||
# If it succeeded, we are done.
|
||||
test $st -eq 0 && exit 0
|
||||
|
||||
# Also exit now if we it failed (or wasn't found), and '--version' was
|
||||
# passed; such an option is passed most likely to detect whether the
|
||||
# program is present and works.
|
||||
case $2 in --version|--help) exit $st;; esac
|
||||
|
||||
# Exit code 63 means version mismatch. This often happens when the user
|
||||
# tries to use an ancient version of a tool on a file that requires a
|
||||
# minimum version.
|
||||
if test $st -eq 63; then
|
||||
msg="probably too old"
|
||||
elif test $st -eq 127; then
|
||||
# Program was missing.
|
||||
msg="missing on your system"
|
||||
else
|
||||
# Program was found and executed, but failed. Give up.
|
||||
exit $st
|
||||
fi
|
||||
|
||||
perl_URL=http://www.perl.org/
|
||||
flex_URL=http://flex.sourceforge.net/
|
||||
gnu_software_URL=http://www.gnu.org/software
|
||||
|
||||
program_details ()
|
||||
{
|
||||
case $1 in
|
||||
aclocal|automake)
|
||||
echo "The '$1' program is part of the GNU Automake package:"
|
||||
echo "<$gnu_software_URL/automake>"
|
||||
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/autoconf>"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
autoconf|autom4te|autoheader)
|
||||
echo "The '$1' program is part of the GNU Autoconf package:"
|
||||
echo "<$gnu_software_URL/autoconf/>"
|
||||
echo "It also requires GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice ()
|
||||
{
|
||||
# Normalize program name to check for.
|
||||
normalized_program=`echo "$1" | sed '
|
||||
s/^gnu-//; t
|
||||
s/^gnu//; t
|
||||
s/^g//; t'`
|
||||
|
||||
printf '%s\n' "'$1' is $msg."
|
||||
|
||||
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
||||
case $normalized_program in
|
||||
autoconf*)
|
||||
echo "You should only need it if you modified 'configure.ac',"
|
||||
echo "or m4 files included by it."
|
||||
program_details 'autoconf'
|
||||
;;
|
||||
autoheader*)
|
||||
echo "You should only need it if you modified 'acconfig.h' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'autoheader'
|
||||
;;
|
||||
automake*)
|
||||
echo "You should only need it if you modified 'Makefile.am' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'automake'
|
||||
;;
|
||||
aclocal*)
|
||||
echo "You should only need it if you modified 'acinclude.m4' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'aclocal'
|
||||
;;
|
||||
autom4te*)
|
||||
echo "You might have modified some maintainer files that require"
|
||||
echo "the 'autom4te' program to be rebuilt."
|
||||
program_details 'autom4te'
|
||||
;;
|
||||
bison*|yacc*)
|
||||
echo "You should only need it if you modified a '.y' file."
|
||||
echo "You may want to install the GNU Bison package:"
|
||||
echo "<$gnu_software_URL/bison/>"
|
||||
;;
|
||||
lex*|flex*)
|
||||
echo "You should only need it if you modified a '.l' file."
|
||||
echo "You may want to install the Fast Lexical Analyzer package:"
|
||||
echo "<$flex_URL>"
|
||||
;;
|
||||
help2man*)
|
||||
echo "You should only need it if you modified a dependency" \
|
||||
"of a man page."
|
||||
echo "You may want to install the GNU Help2man package:"
|
||||
echo "<$gnu_software_URL/help2man/>"
|
||||
;;
|
||||
makeinfo*)
|
||||
echo "You should only need it if you modified a '.texi' file, or"
|
||||
echo "any other file indirectly affecting the aspect of the manual."
|
||||
echo "You might want to install the Texinfo package:"
|
||||
echo "<$gnu_software_URL/texinfo/>"
|
||||
echo "The spurious makeinfo call might also be the consequence of"
|
||||
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
||||
echo "want to install GNU make:"
|
||||
echo "<$gnu_software_URL/make/>"
|
||||
;;
|
||||
*)
|
||||
echo "You might have modified some files without having the proper"
|
||||
echo "tools for further handling them. Check the 'README' file, it"
|
||||
echo "often tells you about the needed prerequisites for installing"
|
||||
echo "this package. You may also peek at any GNU archive site, in"
|
||||
echo "case some other package contains this missing '$1' program."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||
-e '2,$s/^/ /' >&2
|
||||
|
||||
# Propagate the correct exit status (expected to be 127 for a program
|
||||
# not found, 63 for a program that failed due to version mismatch).
|
||||
exit $st
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
43
raid/COPYING
43
raid/COPYING
@ -1,12 +1,12 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@ -225,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@ -335,5 +335,6 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
|
428
raid/mktables.c
Normal file
428
raid/mktables.c
Normal file
@ -0,0 +1,428 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Multiplication a*b in GF(2^8).
|
||||
*/
|
||||
static uint8_t gfmul(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint8_t v;
|
||||
|
||||
v = 0;
|
||||
while (b) {
|
||||
if ((b & 1) != 0)
|
||||
v ^= a;
|
||||
|
||||
if ((a & 0x80) != 0) {
|
||||
a <<= 1;
|
||||
a ^= 0x1d;
|
||||
} else {
|
||||
a <<= 1;
|
||||
}
|
||||
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inversion (1/a) in GF(2^8).
|
||||
*/
|
||||
uint8_t gfinv[256];
|
||||
|
||||
/**
|
||||
* Number of parities.
|
||||
* This is the number of rows of the generator matrix.
|
||||
*/
|
||||
#define PARITY 6
|
||||
|
||||
/**
|
||||
* Number of disks.
|
||||
* This is the number of columns of the generator matrix.
|
||||
*/
|
||||
#define DISK (257 - PARITY)
|
||||
|
||||
/**
|
||||
* Setup the Cauchy matrix used to generate the parity.
|
||||
*/
|
||||
static void set_cauchy(uint8_t *matrix)
|
||||
{
|
||||
int i, j;
|
||||
uint8_t inv_x, y;
|
||||
|
||||
/*
|
||||
* The first row of the generator matrix is formed by all 1.
|
||||
*
|
||||
* The generator matrix is an Extended Cauchy matrix built from
|
||||
* a Cauchy matrix adding at the top a row of all 1.
|
||||
*
|
||||
* Extending a Cauchy matrix in this way maintains the MDS property
|
||||
* of the matrix.
|
||||
*
|
||||
* For example, considering a generator matrix of 4x6 we have now:
|
||||
*
|
||||
* 1 1 1 1 1 1
|
||||
* - - - - - -
|
||||
* - - - - - -
|
||||
* - - - - - -
|
||||
*/
|
||||
for (i = 0; i < DISK; ++i)
|
||||
matrix[0 * DISK + i] = 1;
|
||||
|
||||
/*
|
||||
* Second row is formed with powers 2^i, and it's the first
|
||||
* row of the Cauchy matrix.
|
||||
*
|
||||
* Each element of the Cauchy matrix is in the form 1/(x_i + y_j)
|
||||
* where all x_i and y_j must be different for any i and j.
|
||||
*
|
||||
* For the first row with j=0, we choose x_i = 2^-i and y_0 = 0
|
||||
* and we obtain a first row formed as:
|
||||
*
|
||||
* 1/(x_i + y_0) = 1/(2^-i + 0) = 2^i
|
||||
*
|
||||
* with 2^-i != 0 for any i
|
||||
*
|
||||
* In the example we get:
|
||||
*
|
||||
* x_0 = 1
|
||||
* x_1 = 142
|
||||
* x_2 = 71
|
||||
* x_3 = 173
|
||||
* x_4 = 216
|
||||
* x_5 = 108
|
||||
* y_0 = 0
|
||||
*
|
||||
* with the matrix:
|
||||
*
|
||||
* 1 1 1 1 1 1
|
||||
* 1 2 4 8 16 32
|
||||
* - - - - - -
|
||||
* - - - - - -
|
||||
*/
|
||||
inv_x = 1;
|
||||
for (i = 0; i < DISK; ++i) {
|
||||
matrix[1 * DISK + i] = inv_x;
|
||||
inv_x = gfmul(2, inv_x);
|
||||
}
|
||||
|
||||
/*
|
||||
* The rest of the Cauchy matrix is formed choosing for each row j
|
||||
* a new y_j = 2^j and reusing the x_i already assigned in the first
|
||||
* row obtaining :
|
||||
*
|
||||
* 1/(x_i + y_j) = 1/(2^-i + 2^j)
|
||||
*
|
||||
* with 2^-i + 2^j != 0 for any i,j with i>=0,j>=1,i+j<255
|
||||
*
|
||||
* In the example we get:
|
||||
*
|
||||
* y_1 = 2
|
||||
* y_2 = 4
|
||||
*
|
||||
* with the matrix:
|
||||
*
|
||||
* 1 1 1 1 1 1
|
||||
* 1 2 4 8 16 32
|
||||
* 244 83 78 183 118 47
|
||||
* 167 39 213 59 153 82
|
||||
*/
|
||||
y = 2;
|
||||
for (j = 0; j < PARITY - 2; ++j) {
|
||||
inv_x = 1;
|
||||
for (i = 0; i < DISK; ++i) {
|
||||
uint8_t x = gfinv[inv_x];
|
||||
|
||||
matrix[(j + 2) * DISK + i] = gfinv[y ^ x];
|
||||
inv_x = gfmul(2, inv_x);
|
||||
}
|
||||
|
||||
y = gfmul(2, y);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally we adjust the matrix multiplying each row for
|
||||
* the inverse of the first element in the row.
|
||||
*
|
||||
* Also this operation maintains the MDS property of the matrix.
|
||||
*
|
||||
* Resulting in:
|
||||
*
|
||||
* 1 1 1 1 1 1
|
||||
* 1 2 4 8 16 32
|
||||
* 1 245 210 196 154 113
|
||||
* 1 187 166 215 7 106
|
||||
*/
|
||||
for (j = 0; j < PARITY - 2; ++j) {
|
||||
uint8_t f = gfinv[matrix[(j + 2) * DISK]];
|
||||
|
||||
for (i = 0; i < DISK; ++i)
|
||||
matrix[(j + 2) * DISK + i] = gfmul(matrix[(j + 2) * DISK + i], f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the Power matrix used to generate the parity.
|
||||
*/
|
||||
static void set_power(uint8_t *matrix)
|
||||
{
|
||||
unsigned i;
|
||||
uint8_t v;
|
||||
|
||||
v = 1;
|
||||
for (i = 0; i < DISK; ++i)
|
||||
matrix[0 * DISK + i] = v;
|
||||
|
||||
v = 1;
|
||||
for (i = 0; i < DISK; ++i) {
|
||||
matrix[1 * DISK + i] = v;
|
||||
v = gfmul(2, v);
|
||||
}
|
||||
|
||||
v = 1;
|
||||
for (i = 0; i < DISK; ++i) {
|
||||
matrix[2 * DISK + i] = v;
|
||||
v = gfmul(0x8e, v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Next power of 2.
|
||||
*/
|
||||
static unsigned np(unsigned v)
|
||||
{
|
||||
--v;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
++v;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint8_t v;
|
||||
int i, j, k, p;
|
||||
uint8_t matrix[PARITY * 256];
|
||||
|
||||
printf("/*\n");
|
||||
printf(" * Copyright (C) 2013 Andrea Mazzoleni\n");
|
||||
printf(" *\n");
|
||||
printf(" * This program is free software: you can redistribute it and/or modify\n");
|
||||
printf(" * it under the terms of the GNU General Public License as published by\n");
|
||||
printf(" * the Free Software Foundation, either version 2 of the License, or\n");
|
||||
printf(" * (at your option) any later version.\n");
|
||||
printf(" *\n");
|
||||
printf(" * This program is distributed in the hope that it will be useful,\n");
|
||||
printf(" * but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
|
||||
printf(" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
|
||||
printf(" * GNU General Public License for more details.\n");
|
||||
printf(" */\n");
|
||||
printf("\n");
|
||||
|
||||
printf("#include \"internal.h\"\n");
|
||||
printf("\n");
|
||||
|
||||
/* a*b */
|
||||
printf("const uint8_t __aligned(256) raid_gfmul[256][256] =\n");
|
||||
printf("{\n");
|
||||
for (i = 0; i < 256; ++i) {
|
||||
printf("\t{\n");
|
||||
for (j = 0; j < 256; ++j) {
|
||||
if (j % 8 == 0)
|
||||
printf("\t\t");
|
||||
v = gfmul(i, j);
|
||||
if (v == 1)
|
||||
gfinv[i] = j;
|
||||
printf("0x%02x,", (unsigned)v);
|
||||
if (j % 8 == 7)
|
||||
printf("\n");
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
printf("\t},\n");
|
||||
}
|
||||
printf("};\n\n");
|
||||
|
||||
/* 2^a */
|
||||
printf("const uint8_t __aligned(256) raid_gfexp[256] =\n");
|
||||
printf("{\n");
|
||||
v = 1;
|
||||
for (i = 0; i < 256; ++i) {
|
||||
if (i % 8 == 0)
|
||||
printf("\t");
|
||||
printf("0x%02x,", v);
|
||||
v = gfmul(v, 2);
|
||||
if (i % 8 == 7)
|
||||
printf("\n");
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
printf("};\n\n");
|
||||
|
||||
/* 1/a */
|
||||
printf("const uint8_t __aligned(256) raid_gfinv[256] =\n");
|
||||
printf("{\n");
|
||||
printf("\t/* note that the first element is not significative */\n");
|
||||
for (i = 0; i < 256; ++i) {
|
||||
if (i % 8 == 0)
|
||||
printf("\t");
|
||||
if (i == 0)
|
||||
v = 0;
|
||||
else
|
||||
v = gfinv[i];
|
||||
printf("0x%02x,", v);
|
||||
if (i % 8 == 7)
|
||||
printf("\n");
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
printf("};\n\n");
|
||||
|
||||
/* power matrix */
|
||||
set_power(matrix);
|
||||
|
||||
printf("/**\n");
|
||||
printf(" * Power matrix used to generate parity.\n");
|
||||
printf(" * This matrix is valid for up to %u parity with %u data disks.\n", 3, DISK);
|
||||
printf(" *\n");
|
||||
for (p = 0; p < 3; ++p) {
|
||||
printf(" *");
|
||||
for (i = 0; i < DISK; ++i)
|
||||
printf(" %02x", matrix[p * DISK + i]);
|
||||
printf("\n");
|
||||
}
|
||||
printf(" */\n");
|
||||
printf("const uint8_t __aligned(256) raid_gfvandermonde[%u][256] =\n", 3);
|
||||
printf("{\n");
|
||||
for (p = 0; p < 3; ++p) {
|
||||
printf("\t{\n");
|
||||
for (i = 0; i < DISK; ++i) {
|
||||
if (i % 8 == 0)
|
||||
printf("\t\t");
|
||||
printf("0x%02x,", matrix[p * DISK + i]);
|
||||
if (i != DISK - 1) {
|
||||
if (i % 8 == 7)
|
||||
printf("\n");
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
printf("\n\t},\n");
|
||||
}
|
||||
printf("};\n\n");
|
||||
|
||||
/* cauchy matrix */
|
||||
set_cauchy(matrix);
|
||||
|
||||
printf("/**\n");
|
||||
printf(" * Cauchy matrix used to generate parity.\n");
|
||||
printf(" * This matrix is valid for up to %u parity with %u data disks.\n", PARITY, DISK);
|
||||
printf(" *\n");
|
||||
for (p = 0; p < PARITY; ++p) {
|
||||
printf(" *");
|
||||
for (i = 0; i < DISK; ++i)
|
||||
printf(" %02x", matrix[p * DISK + i]);
|
||||
printf("\n");
|
||||
}
|
||||
printf(" */\n");
|
||||
printf("const uint8_t __aligned(256) raid_gfcauchy[%u][256] =\n", PARITY);
|
||||
printf("{\n");
|
||||
for (p = 0; p < PARITY; ++p) {
|
||||
printf("\t{\n");
|
||||
for (i = 0; i < DISK; ++i) {
|
||||
if (i % 8 == 0)
|
||||
printf("\t\t");
|
||||
printf("0x%02x,", matrix[p * DISK + i]);
|
||||
if (i != DISK - 1) {
|
||||
if (i % 8 == 7)
|
||||
printf("\n");
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
printf("\n\t},\n");
|
||||
}
|
||||
printf("};\n\n");
|
||||
|
||||
printf("#ifdef CONFIG_X86\n");
|
||||
printf("/**\n");
|
||||
printf(" * PSHUFB tables for the Cauchy matrix.\n");
|
||||
printf(" *\n");
|
||||
printf(" * Indexes are [DISK][PARITY - 2][LH].\n");
|
||||
printf(" * Where DISK is from 0 to %u, PARITY from 2 to %u, LH from 0 to 1.\n", DISK - 1, PARITY - 1);
|
||||
printf(" */\n");
|
||||
printf("const uint8_t __aligned(256) raid_gfcauchypshufb[%u][%u][2][16] =\n", DISK, np(PARITY - 2));
|
||||
printf("{\n");
|
||||
for (i = 0; i < DISK; ++i) {
|
||||
printf("\t{\n");
|
||||
for (p = 2; p < PARITY; ++p) {
|
||||
printf("\t\t{\n");
|
||||
for (j = 0; j < 2; ++j) {
|
||||
printf("\t\t\t{ ");
|
||||
for (k = 0; k < 16; ++k) {
|
||||
v = gfmul(matrix[p * DISK + i], k);
|
||||
if (j == 1)
|
||||
v = gfmul(v, 16);
|
||||
printf("0x%02x", (unsigned)v);
|
||||
if (k != 15)
|
||||
printf(", ");
|
||||
}
|
||||
printf(" },\n");
|
||||
}
|
||||
printf("\t\t},\n");
|
||||
}
|
||||
printf("\t},\n");
|
||||
}
|
||||
printf("};\n");
|
||||
printf("#endif\n\n");
|
||||
|
||||
printf("#ifdef CONFIG_X86\n");
|
||||
printf("/**\n");
|
||||
printf(" * PSHUFB tables for generic multiplication.\n");
|
||||
printf(" *\n");
|
||||
printf(" * Indexes are [MULTIPLIER][LH].\n");
|
||||
printf(" * Where MULTIPLIER is from 0 to 255, LH from 0 to 1.\n");
|
||||
printf(" */\n");
|
||||
printf("const uint8_t __aligned(256) raid_gfmulpshufb[256][2][16] =\n");
|
||||
printf("{\n");
|
||||
for (i = 0; i < 256; ++i) {
|
||||
printf("\t{\n");
|
||||
for (j = 0; j < 2; ++j) {
|
||||
printf("\t\t{ ");
|
||||
for (k = 0; k < 16; ++k) {
|
||||
v = gfmul(i, k);
|
||||
if (j == 1)
|
||||
v = gfmul(v, 16);
|
||||
printf("0x%02x", (unsigned)v);
|
||||
if (k != 15)
|
||||
printf(", ");
|
||||
}
|
||||
printf(" },\n");
|
||||
}
|
||||
printf("\t},\n");
|
||||
}
|
||||
printf("};\n");
|
||||
printf("#endif\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
70
raid/raid.c
70
raid/raid.c
@ -20,50 +20,50 @@
|
||||
* the primitive polynomial x^8 + x^4 + x^3 + x^2 + 1 (285 decimal), and
|
||||
* supporting up to six parity levels.
|
||||
*
|
||||
* For RAID5 and RAID6 it works as as described in the H. Peter Anvin's
|
||||
* For RAID5 and RAID6, it works as described in H. Peter Anvin's
|
||||
* paper "The mathematics of RAID-6" [1]. Please refer to this paper for a
|
||||
* complete explanation.
|
||||
*
|
||||
* To support triple parity, it was first evaluated and then dropped, an
|
||||
* To support triple parity, it was first evaluated and then dropped; an
|
||||
* extension of the same approach, with additional parity coefficients set
|
||||
* as powers of 2^-1, with equations:
|
||||
*
|
||||
* P = sum(Di)
|
||||
* Q = sum(2^i * Di)
|
||||
* R = sum(2^-i * Di) with 0<=i<N
|
||||
* R = sum(2^-i * Di) with 0 <= i < N
|
||||
*
|
||||
* This approach works well for triple parity and it's very efficient,
|
||||
* This approach works well for triple parity and is very efficient
|
||||
* because we can implement very fast parallel multiplications and
|
||||
* divisions by 2 in GF(2^8).
|
||||
*
|
||||
* It's also similar at the approach used by ZFS RAIDZ3, with the
|
||||
* It is also similar to the approach used by ZFS RAIDZ3, with the
|
||||
* difference that ZFS uses powers of 4 instead of 2^-1.
|
||||
*
|
||||
* Unfortunately it doesn't work beyond triple parity, because whatever
|
||||
* Unfortunately, it doesn't work beyond triple parity because whatever
|
||||
* value we choose to generate the power coefficients to compute other
|
||||
* parities, the resulting equations are not solvable for some
|
||||
* combinations of missing disks.
|
||||
*
|
||||
* This is expected, because the Vandermonde matrix used to compute the
|
||||
* This is expected because the Vandermonde matrix used to compute the
|
||||
* parity has no guarantee to have all submatrices not singular
|
||||
* [2, Chap 11, Problem 7] and this is a requirement to have
|
||||
* a MDS (Maximum Distance Separable) code [2, Chap 11, Theorem 8].
|
||||
* [2, Chap 11, Problem 7], and this is a requirement to have
|
||||
* an MDS (Maximum Distance Separable) code [2, Chap 11, Theorem 8].
|
||||
*
|
||||
* To overcome this limitation, we use a Cauchy matrix [3][4] to compute
|
||||
* the parity. A Cauchy matrix has the property to have all the square
|
||||
* submatrices not singular, resulting in always solvable equations,
|
||||
* the parity. A Cauchy matrix has the property of having all square
|
||||
* submatrices not singular, resulting in always solvable equations
|
||||
* for any combination of missing disks.
|
||||
*
|
||||
* The problem of this approach is that it requires the use of
|
||||
* The problem with this approach is that it requires the use of
|
||||
* generic multiplications, and not only by 2 or 2^-1, potentially
|
||||
* affecting badly the performance.
|
||||
* affecting performance negatively.
|
||||
*
|
||||
* Hopefully there is a method to implement parallel multiplications
|
||||
* using SSSE3 or AVX2 instructions [1][5]. Method competitive with the
|
||||
* Hopefully, there is a method to implement parallel multiplications
|
||||
* using SSSE3 or AVX2 instructions [1][5], a method competitive with the
|
||||
* computation of triple parity using power coefficients.
|
||||
*
|
||||
* Another important property of the Cauchy matrix is that we can setup
|
||||
* the first two rows with coefficients equal at the RAID5 and RAID6 approach
|
||||
* Another important property of the Cauchy matrix is that we can set up
|
||||
* the first two rows with coefficients equal to the RAID5 and RAID6 approach
|
||||
* described, resulting in a compatible extension, and requiring SSSE3
|
||||
* or AVX2 instructions only if triple parity or beyond is used.
|
||||
*
|
||||
@ -71,7 +71,7 @@
|
||||
* to make the first column of all 1, to optimize the computation for
|
||||
* the first disk.
|
||||
*
|
||||
* This results in the matrix A[row,col] defined as:
|
||||
* This results in the matrix A[row, col] defined as:
|
||||
*
|
||||
* 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01...
|
||||
* 01 02 04 08 10 20 40 80 1d 3a 74 e8 cd 87 13 26 4c 98 2d 5a b4 75...
|
||||
@ -80,25 +80,25 @@
|
||||
* 01 97 7f 9c 7c 18 bd a2 58 1a da 74 70 a3 e5 47 29 07 f5 80 23 e9...
|
||||
* 01 2b 3f cf 73 2c d6 ed cb 74 15 78 8a c1 17 c9 89 68 21 ab 76 3b...
|
||||
*
|
||||
* This matrix supports 6 level of parity, one for each row, for up to 251
|
||||
* This matrix supports 6 levels of parity, one for each row, for up to 251
|
||||
* data disks, one for each column, with all the 377,342,351,231 square
|
||||
* submatrices not singular, verified also with brute-force.
|
||||
* submatrices not singular, verified also with brute force.
|
||||
*
|
||||
* This matrix can be extended to support any number of parities, just
|
||||
* adding additional rows, and removing one column for each new row.
|
||||
* (see mktables.c for more details in how the matrix is generated)
|
||||
* adding additional rows and removing one column for each new row.
|
||||
* (see mktables.c for more details on how the matrix is generated)
|
||||
*
|
||||
* In details, parity is computed as:
|
||||
* In detail, parity is computed as:
|
||||
*
|
||||
* P = sum(Di)
|
||||
* Q = sum(2^i * Di)
|
||||
* Q = sum(2^i * Di)
|
||||
* R = sum(A[2,i] * Di)
|
||||
* S = sum(A[3,i] * Di)
|
||||
* T = sum(A[4,i] * Di)
|
||||
* U = sum(A[5,i] * Di) with 0<=i<N
|
||||
* U = sum(A[5,i] * Di) with 0 <= i < N
|
||||
*
|
||||
* To recover from a failure of six disks at indexes x,y,z,h,v,w,
|
||||
* with 0<=x<y<z<h<v<w<N, we compute the parity of the available N-6
|
||||
* To recover from a failure of six disks at indexes x, y, z, h, v, w,
|
||||
* with 0 <= x < y < z < h < v < w < N, we compute the parity of the available N-6
|
||||
* disks as:
|
||||
*
|
||||
* Pa = sum(Di)
|
||||
@ -106,7 +106,7 @@
|
||||
* Ra = sum(A[2,i] * Di)
|
||||
* Sa = sum(A[3,i] * Di)
|
||||
* Ta = sum(A[4,i] * Di)
|
||||
* Ua = sum(A[5,i] * Di) with 0<=i<N,i!=x,i!=y,i!=z,i!=h,i!=v,i!=w.
|
||||
* Ua = sum(A[5,i] * Di) with 0 <= i < N, i != x, i != y, i != z, i != h, i != v, i != w.
|
||||
*
|
||||
* And if we define:
|
||||
*
|
||||
@ -126,13 +126,13 @@
|
||||
* Td = A[4,x] * Dx + A[4,y] * Dy + A[4,z] * Dz + A[4,h] * Dh + A[4,v] * Dv + A[4,w] * Dw
|
||||
* Ud = A[5,x] * Dx + A[5,y] * Dy + A[5,z] * Dz + A[5,h] * Dh + A[5,v] * Dv + A[5,w] * Dw
|
||||
*
|
||||
* A linear system always solvable because the coefficients matrix is
|
||||
* always not singular due the properties of the matrix A[].
|
||||
* A linear system is always solvable because the coefficients matrix is
|
||||
* always not singular due to the properties of the matrix A[].
|
||||
*
|
||||
* Resulting speed in x64, with 8 data disks, using a stripe of 256 KiB,
|
||||
* The resulting speed in x64, with 8 data disks, using a stripe of 256 KiB,
|
||||
* for a Core i5-4670K Haswell Quad-Core 3.4GHz is:
|
||||
*
|
||||
* int8 int32 int64 sse2 ssse3 avx2
|
||||
* int8 int32 int64 sse2 ssse3 avx2
|
||||
* gen1 13339 25438 45438 50588
|
||||
* gen2 4115 6514 21840 32201
|
||||
* gen3 814 10154 18613
|
||||
@ -143,18 +143,18 @@
|
||||
* Values are in MiB/s of data processed by a single thread, not counting
|
||||
* generated parity.
|
||||
*
|
||||
* You can replicate these results in your machine using the
|
||||
* You can replicate these results on your machine using the
|
||||
* "raid/test/speedtest.c" program.
|
||||
*
|
||||
* For comparison, the triple parity computation using the power
|
||||
* coefficients "1,2,2^-1" is only a little faster than the one based on
|
||||
* the Cauchy matrix if SSSE3 or AVX2 is present.
|
||||
*
|
||||
* int8 int32 int64 sse2 ssse3 avx2
|
||||
* int8 int32 int64 sse2 ssse3 avx2
|
||||
* genz 2337 2874 10920 18944
|
||||
*
|
||||
* In conclusion, the use of power coefficients, and specifically powers
|
||||
* of 1,2,2^-1, is the best option to implement triple parity in CPUs
|
||||
* of 1, 2, 2^-1, is the best option to implement triple parity in CPUs
|
||||
* without SSSE3 and AVX2.
|
||||
* But if a modern CPU with SSSE3 or AVX2 is available, the Cauchy
|
||||
* matrix is the best option because it provides a fast and general
|
||||
|
@ -192,7 +192,7 @@ int raid_check(int nr, int *ir, int nd, int np, size_t size, void **v);
|
||||
* This function identifies the failed data and parity blocks using the
|
||||
* available redundancy.
|
||||
*
|
||||
* It uses a brute force method, and then the call can be expansive.
|
||||
* It uses a brute force method, and then the call can be expensive.
|
||||
* The expected execution time is proportional at the binomial coefficient
|
||||
* @np + @nd choose @np - 1, usually written as:
|
||||
*
|
||||
|
106
raid/tag.c
106
raid/tag.c
@ -14,76 +14,78 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
typedef void (void_f)(void);
|
||||
|
||||
static struct raid_func {
|
||||
const char *name;
|
||||
void (*p)();
|
||||
void_f* func;
|
||||
} RAID_FUNC[] = {
|
||||
{ "int8", raid_gen3_int8 },
|
||||
{ "int8", raid_gen4_int8 },
|
||||
{ "int8", raid_gen5_int8 },
|
||||
{ "int8", raid_gen6_int8 },
|
||||
{ "int32", raid_gen1_int32 },
|
||||
{ "int64", raid_gen1_int64 },
|
||||
{ "int32", raid_gen2_int32 },
|
||||
{ "int64", raid_gen2_int64 },
|
||||
{ "int32", raid_genz_int32 },
|
||||
{ "int64", raid_genz_int64 },
|
||||
{ "int8", raid_rec1_int8 },
|
||||
{ "int8", raid_rec2_int8 },
|
||||
{ "int8", raid_recX_int8 },
|
||||
{ "int8", (void_f*)raid_gen3_int8 },
|
||||
{ "int8", (void_f*)raid_gen4_int8 },
|
||||
{ "int8", (void_f*)raid_gen5_int8 },
|
||||
{ "int8", (void_f*)raid_gen6_int8 },
|
||||
{ "int32", (void_f*)raid_gen1_int32 },
|
||||
{ "int64", (void_f*)raid_gen1_int64 },
|
||||
{ "int32", (void_f*)raid_gen2_int32 },
|
||||
{ "int64", (void_f*)raid_gen2_int64 },
|
||||
{ "int32", (void_f*)raid_genz_int32 },
|
||||
{ "int64", (void_f*)raid_genz_int64 },
|
||||
{ "int8", (void_f*)raid_rec1_int8 },
|
||||
{ "int8", (void_f*)raid_rec2_int8 },
|
||||
{ "int8", (void_f*)raid_recX_int8 },
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
{ "sse2", raid_gen1_sse2 },
|
||||
{ "sse2", raid_gen2_sse2 },
|
||||
{ "sse2", raid_genz_sse2 },
|
||||
{ "sse2", (void_f*)raid_gen1_sse2 },
|
||||
{ "sse2", (void_f*)raid_gen2_sse2 },
|
||||
{ "sse2", (void_f*)raid_genz_sse2 },
|
||||
#endif
|
||||
#ifdef CONFIG_SSSE3
|
||||
{ "ssse3", raid_gen3_ssse3 },
|
||||
{ "ssse3", raid_gen4_ssse3 },
|
||||
{ "ssse3", raid_gen5_ssse3 },
|
||||
{ "ssse3", raid_gen6_ssse3 },
|
||||
{ "ssse3", raid_rec1_ssse3 },
|
||||
{ "ssse3", raid_rec2_ssse3 },
|
||||
{ "ssse3", raid_recX_ssse3 },
|
||||
{ "ssse3", (void_f*)raid_gen3_ssse3 },
|
||||
{ "ssse3", (void_f*)raid_gen4_ssse3 },
|
||||
{ "ssse3", (void_f*)raid_gen5_ssse3 },
|
||||
{ "ssse3", (void_f*)raid_gen6_ssse3 },
|
||||
{ "ssse3", (void_f*)raid_rec1_ssse3 },
|
||||
{ "ssse3", (void_f*)raid_rec2_ssse3 },
|
||||
{ "ssse3", (void_f*)raid_recX_ssse3 },
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
{ "avx2", raid_gen1_avx2 },
|
||||
{ "avx2", raid_gen2_avx2 },
|
||||
{ "avx2", raid_rec1_avx2 },
|
||||
{ "avx2", raid_rec2_avx2 },
|
||||
{ "avx2", raid_recX_avx2 },
|
||||
{ "avx2", (void_f*)raid_gen1_avx2 },
|
||||
{ "avx2", (void_f*)raid_gen2_avx2 },
|
||||
{ "avx2", (void_f*)raid_rec1_avx2 },
|
||||
{ "avx2", (void_f*)raid_rec2_avx2 },
|
||||
{ "avx2", (void_f*)raid_recX_avx2 },
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_SSE2
|
||||
{ "sse2e", raid_gen2_sse2ext },
|
||||
{ "sse2e", raid_genz_sse2ext },
|
||||
{ "sse2e", (void_f*)raid_gen2_sse2ext },
|
||||
{ "sse2e", (void_f*)raid_genz_sse2ext },
|
||||
#endif
|
||||
#ifdef CONFIG_SSSE3
|
||||
{ "ssse3e", raid_gen3_ssse3ext },
|
||||
{ "ssse3e", raid_gen4_ssse3ext },
|
||||
{ "ssse3e", raid_gen5_ssse3ext },
|
||||
{ "ssse3e", raid_gen6_ssse3ext },
|
||||
{ "ssse3e", (void_f*)raid_gen3_ssse3ext },
|
||||
{ "ssse3e", (void_f*)raid_gen4_ssse3ext },
|
||||
{ "ssse3e", (void_f*)raid_gen5_ssse3ext },
|
||||
{ "ssse3e", (void_f*)raid_gen6_ssse3ext },
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
{ "avx2e", raid_gen3_avx2ext },
|
||||
{ "avx2e", raid_genz_avx2ext },
|
||||
{ "avx2e", raid_gen4_avx2ext },
|
||||
{ "avx2e", raid_gen5_avx2ext },
|
||||
{ "avx2e", raid_gen6_avx2ext },
|
||||
{ "avx2e", (void_f*)raid_gen3_avx2ext },
|
||||
{ "avx2e", (void_f*)raid_genz_avx2ext },
|
||||
{ "avx2e", (void_f*)raid_gen4_avx2ext },
|
||||
{ "avx2e", (void_f*)raid_gen5_avx2ext },
|
||||
{ "avx2e", (void_f*)raid_gen6_avx2ext },
|
||||
#endif
|
||||
#endif
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static const char *raid_tag(void (*func)())
|
||||
static const char *raid_tag(void_f* func)
|
||||
{
|
||||
struct raid_func *i = RAID_FUNC;
|
||||
|
||||
while (i->name != 0) {
|
||||
if (i->p == func)
|
||||
if (i->func == func)
|
||||
return i->name;
|
||||
++i;
|
||||
}
|
||||
@ -95,51 +97,51 @@ static const char *raid_tag(void (*func)())
|
||||
|
||||
const char *raid_gen1_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[0]);
|
||||
return raid_tag((void_f*)raid_gen_ptr[0]);
|
||||
}
|
||||
|
||||
const char *raid_gen2_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[1]);
|
||||
return raid_tag((void_f*)raid_gen_ptr[1]);
|
||||
}
|
||||
|
||||
const char *raid_genz_tag(void)
|
||||
{
|
||||
return raid_tag(raid_genz_ptr);
|
||||
return raid_tag((void_f*)raid_genz_ptr);
|
||||
}
|
||||
|
||||
const char *raid_gen3_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[2]);
|
||||
return raid_tag((void_f*)raid_gen_ptr[2]);
|
||||
}
|
||||
|
||||
const char *raid_gen4_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[3]);
|
||||
return raid_tag((void_f*)raid_gen_ptr[3]);
|
||||
}
|
||||
|
||||
const char *raid_gen5_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[4]);
|
||||
return raid_tag((void_f*)raid_gen_ptr[4]);
|
||||
}
|
||||
|
||||
const char *raid_gen6_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[5]);
|
||||
return raid_tag((void_f*)raid_gen_ptr[5]);
|
||||
}
|
||||
|
||||
const char *raid_rec1_tag(void)
|
||||
{
|
||||
return raid_tag(raid_rec_ptr[0]);
|
||||
return raid_tag((void_f*)raid_rec_ptr[0]);
|
||||
}
|
||||
|
||||
const char *raid_rec2_tag(void)
|
||||
{
|
||||
return raid_tag(raid_rec_ptr[1]);
|
||||
return raid_tag((void_f*)raid_rec_ptr[1]);
|
||||
}
|
||||
|
||||
const char *raid_recX_tag(void)
|
||||
{
|
||||
return raid_tag(raid_rec_ptr[2]);
|
||||
return raid_tag((void_f*)raid_rec_ptr[2]);
|
||||
}
|
||||
|
||||
|
36
snapraid-rpm.spec
Normal file
36
snapraid-rpm.spec
Normal file
@ -0,0 +1,36 @@
|
||||
Name: snapraid
|
||||
Summary: Disk array backup for many large rarely-changed files
|
||||
Version: 12.2
|
||||
Release: 3%{?dist}
|
||||
License: GPLv3+
|
||||
Group: Applications/System
|
||||
URL: http://www.snapraid.it/
|
||||
Source: https://github.com/amadvance/snapraid/releases/download/v%{version}/snapraid-%{version}.tar.gz
|
||||
BuildRequires: gcc
|
||||
|
||||
%description
|
||||
SnapRAID is a backup program for disk arrays. It stores parity
|
||||
information of your data and it's able to recover from up to six disk
|
||||
failures. SnapRAID is mainly targeted for a home media center, with a
|
||||
lot of big files that rarely change.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
%configure
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%check
|
||||
make check
|
||||
|
||||
%install
|
||||
make install DESTDIR=%{buildroot}
|
||||
|
||||
%files
|
||||
%doc COPYING AUTHORS HISTORY README
|
||||
%{_bindir}/snapraid
|
||||
%{_mandir}/man1/snapraid.1*
|
||||
|
||||
%changelog
|
||||
|
67
snapraid.1
67
snapraid.1
@ -68,42 +68,39 @@ snapraid [\-V, \-\-version] [\-H, \-\-help] [\-C, \-\-gen\-conf CONTENT]
|
||||
.PP
|
||||
.PD
|
||||
.SH DESCRIPTION
|
||||
SnapRAID is a backup program for disk arrays. It stores parity
|
||||
information of your data and it recovers from up to six disk
|
||||
failures.
|
||||
SnapRAID is a backup program designed for disk arrays, storing
|
||||
parity information for data recovery in the event of up to six
|
||||
disk failures.
|
||||
.PP
|
||||
SnapRAID is mainly targeted for a home media center, with a lot of
|
||||
big files that rarely change.
|
||||
.PP
|
||||
Beside the ability to recover from disk failures, other
|
||||
features of SnapRAID are:
|
||||
Primarily intended for home media centers with large,
|
||||
infrequently changing files, SnapRAID offers several features:
|
||||
.PD 0
|
||||
.IP \(bu
|
||||
You can use disk already filled with files, without the need to
|
||||
reformat them. You will access them like now.
|
||||
You can utilize disks already filled with files without the
|
||||
need to reformat them, accessing them as usual.
|
||||
.IP \(bu
|
||||
All your data is hashed to ensure data integrity and to avoid
|
||||
All your data is hashed to ensure data integrity and prevent
|
||||
silent corruption.
|
||||
.IP \(bu
|
||||
If the failed disks are too many to allow a recovery,
|
||||
you lose the data only on the failed disks.
|
||||
All the data in the other disks is safe.
|
||||
When the number of failed disks exceeds the parity count,
|
||||
data loss is confined to the affected disks; data on
|
||||
other disks remains accessible.
|
||||
.IP \(bu
|
||||
If you accidentally delete some files in a disk, you can
|
||||
recover them.
|
||||
If you accidentally delete files on a disk, recovery is
|
||||
possible.
|
||||
.IP \(bu
|
||||
The disks can have different sizes.
|
||||
Disks can have different sizes.
|
||||
.IP \(bu
|
||||
You can add disks at any time.
|
||||
.IP \(bu
|
||||
It doesn\'t lock\-in your data. You can stop using SnapRAID at any
|
||||
time without the need to reformat or move data.
|
||||
SnapRAID doesn\'t lock in your data; you can stop using it
|
||||
anytime without reformatting or moving data.
|
||||
.IP \(bu
|
||||
To access a file, only a single disk needs to spin, saving power and
|
||||
producing less noise.
|
||||
To access a file, only a single disk needs to spin, saving
|
||||
power and reducing noise.
|
||||
.PD
|
||||
.PP
|
||||
The official site of SnapRAID is:
|
||||
For more information, please visit the official SnapRAID site:
|
||||
.PP
|
||||
.RS 4
|
||||
http://www.snapraid.it/
|
||||
@ -118,30 +115,30 @@ consider before using it.
|
||||
.PP
|
||||
The main one is that if a disk fails, and you haven\'t recently synced,
|
||||
you may be unable to do a complete recover.
|
||||
More specifically, you may be unable to recover up to the size of the
|
||||
amount of the changed or deleted files from the last sync operation.
|
||||
More specifically, you may be unable to recover up to the size of
|
||||
the changed or deleted files from the last sync operation.
|
||||
This happens even if the files changed or deleted are not in the
|
||||
failed disk. This is the reason because SnapRAID is better suited for
|
||||
failed disk. This is why SnapRAID is better suited for
|
||||
data that rarely change.
|
||||
.PP
|
||||
Instead the new added files don\'t prevent the recovering of the already
|
||||
existing files. You may only lose the just added files, if they are on
|
||||
On the other hand, newly added files don\'t prevent recovering already
|
||||
existing files. You may only lose the recently added files, if they are on
|
||||
the failed disk.
|
||||
.PP
|
||||
Other limitations are:
|
||||
Other SnapRAID limitations are:
|
||||
.PD 0
|
||||
.IP \(bu
|
||||
You have different file\-systems for each disk.
|
||||
Using a RAID you have only a big file\-system.
|
||||
With SnapRAID, you still have separate file\-systems for each disk.
|
||||
With RAID you get a single large file\-system.
|
||||
.IP \(bu
|
||||
It doesn\'t stripe data.
|
||||
SnapRAID doesn\'t stripe data.
|
||||
With RAID you get a speed boost with striping.
|
||||
.IP \(bu
|
||||
It doesn\'t support real\-time recovery.
|
||||
SnapRAID doesn\'t support real\-time recovery.
|
||||
With RAID you do not have to stop working when a disk fails.
|
||||
.IP \(bu
|
||||
It\'s able to recover damages only from a limited number of disks.
|
||||
With a Backup you are able to recover from a complete
|
||||
SnapRAID is able to recover damages only from a limited number of disks.
|
||||
With a Backup you can recover from a complete
|
||||
failure of the whole disk array.
|
||||
.IP \(bu
|
||||
Only file, time\-stamps, symlinks and hardlinks are saved.
|
||||
@ -1363,7 +1360,7 @@ WARNING! This option is for experts only, and it\'s highly
|
||||
recommended to not change it. To change again this value in
|
||||
future you\'ll have to recreate the whole parity!
|
||||
.PP
|
||||
A reason to use a different hashsize is if you have a lot of small
|
||||
A reason to use a different blocksize is if you have a lot of small
|
||||
files. In the order of many millions.
|
||||
.PP
|
||||
For each file, even of few bytes, a whole block of parity is allocated,
|
||||
|
67
snapraid.d
67
snapraid.d
@ -21,33 +21,30 @@ Synopsis
|
||||
:snapraid [-V, --version] [-H, --help] [-C, --gen-conf CONTENT]
|
||||
|
||||
Description
|
||||
SnapRAID is a backup program for disk arrays. It stores parity
|
||||
information of your data and it recovers from up to six disk
|
||||
failures.
|
||||
SnapRAID is a backup program designed for disk arrays, storing
|
||||
parity information for data recovery in the event of up to six
|
||||
disk failures.
|
||||
|
||||
SnapRAID is mainly targeted for a home media center, with a lot of
|
||||
big files that rarely change.
|
||||
Primarily intended for home media centers with large,
|
||||
infrequently changing files, SnapRAID offers several features:
|
||||
|
||||
Beside the ability to recover from disk failures, other
|
||||
features of SnapRAID are:
|
||||
|
||||
* You can use disk already filled with files, without the need to
|
||||
reformat them. You will access them like now.
|
||||
* All your data is hashed to ensure data integrity and to avoid
|
||||
* You can utilize disks already filled with files without the
|
||||
need to reformat them, accessing them as usual.
|
||||
* All your data is hashed to ensure data integrity and prevent
|
||||
silent corruption.
|
||||
* If the failed disks are too many to allow a recovery,
|
||||
you lose the data only on the failed disks.
|
||||
All the data in the other disks is safe.
|
||||
* If you accidentally delete some files in a disk, you can
|
||||
recover them.
|
||||
* The disks can have different sizes.
|
||||
* When the number of failed disks exceeds the parity count,
|
||||
data loss is confined to the affected disks; data on
|
||||
other disks remains accessible.
|
||||
* If you accidentally delete files on a disk, recovery is
|
||||
possible.
|
||||
* Disks can have different sizes.
|
||||
* You can add disks at any time.
|
||||
* It doesn't lock-in your data. You can stop using SnapRAID at any
|
||||
time without the need to reformat or move data.
|
||||
* To access a file, only a single disk needs to spin, saving power and
|
||||
producing less noise.
|
||||
* SnapRAID doesn't lock in your data; you can stop using it
|
||||
anytime without reformatting or moving data.
|
||||
* To access a file, only a single disk needs to spin, saving
|
||||
power and reducing noise.
|
||||
|
||||
The official site of SnapRAID is:
|
||||
For more information, please visit the official SnapRAID site:
|
||||
|
||||
:http://www.snapraid.it/
|
||||
|
||||
@ -58,26 +55,26 @@ Limitations
|
||||
|
||||
The main one is that if a disk fails, and you haven't recently synced,
|
||||
you may be unable to do a complete recover.
|
||||
More specifically, you may be unable to recover up to the size of the
|
||||
amount of the changed or deleted files from the last sync operation.
|
||||
More specifically, you may be unable to recover up to the size of
|
||||
the changed or deleted files from the last sync operation.
|
||||
This happens even if the files changed or deleted are not in the
|
||||
failed disk. This is the reason because SnapRAID is better suited for
|
||||
failed disk. This is why SnapRAID is better suited for
|
||||
data that rarely change.
|
||||
|
||||
Instead the new added files don't prevent the recovering of the already
|
||||
existing files. You may only lose the just added files, if they are on
|
||||
On the other hand, newly added files don't prevent recovering already
|
||||
existing files. You may only lose the recently added files, if they are on
|
||||
the failed disk.
|
||||
|
||||
Other limitations are:
|
||||
Other SnapRAID limitations are:
|
||||
|
||||
* You have different file-systems for each disk.
|
||||
Using a RAID you have only a big file-system.
|
||||
* It doesn't stripe data.
|
||||
* With SnapRAID, you still have separate file-systems for each disk.
|
||||
With RAID you get a single large file-system.
|
||||
* SnapRAID doesn't stripe data.
|
||||
With RAID you get a speed boost with striping.
|
||||
* It doesn't support real-time recovery.
|
||||
* SnapRAID doesn't support real-time recovery.
|
||||
With RAID you do not have to stop working when a disk fails.
|
||||
* It's able to recover damages only from a limited number of disks.
|
||||
With a Backup you are able to recover from a complete
|
||||
* SnapRAID is able to recover damages only from a limited number of disks.
|
||||
With a Backup you can recover from a complete
|
||||
failure of the whole disk array.
|
||||
* Only file, time-stamps, symlinks and hardlinks are saved.
|
||||
Permissions, ownership and extended attributes are not saved.
|
||||
@ -1062,7 +1059,7 @@ Configuration
|
||||
recommended to not change it. To change again this value in
|
||||
future you'll have to recreate the whole parity!
|
||||
|
||||
A reason to use a different hashsize is if you have a lot of small
|
||||
A reason to use a different blocksize is if you have a lot of small
|
||||
files. In the order of many millions.
|
||||
|
||||
For each file, even of few bytes, a whole block of parity is allocated,
|
||||
|
67
snapraid.txt
67
snapraid.txt
@ -28,33 +28,30 @@ snapraid [-V, --version] [-H, --help] [-C, --gen-conf CONTENT]
|
||||
2 DESCRIPTION
|
||||
=============
|
||||
|
||||
SnapRAID is a backup program for disk arrays. It stores parity
|
||||
information of your data and it recovers from up to six disk
|
||||
failures.
|
||||
SnapRAID is a backup program designed for disk arrays, storing
|
||||
parity information for data recovery in the event of up to six
|
||||
disk failures.
|
||||
|
||||
SnapRAID is mainly targeted for a home media center, with a lot of
|
||||
big files that rarely change.
|
||||
Primarily intended for home media centers with large,
|
||||
infrequently changing files, SnapRAID offers several features:
|
||||
|
||||
Beside the ability to recover from disk failures, other
|
||||
features of SnapRAID are:
|
||||
|
||||
* You can use disk already filled with files, without the need to
|
||||
reformat them. You will access them like now.
|
||||
* All your data is hashed to ensure data integrity and to avoid
|
||||
* You can utilize disks already filled with files without the
|
||||
need to reformat them, accessing them as usual.
|
||||
* All your data is hashed to ensure data integrity and prevent
|
||||
silent corruption.
|
||||
* If the failed disks are too many to allow a recovery,
|
||||
you lose the data only on the failed disks.
|
||||
All the data in the other disks is safe.
|
||||
* If you accidentally delete some files in a disk, you can
|
||||
recover them.
|
||||
* The disks can have different sizes.
|
||||
* When the number of failed disks exceeds the parity count,
|
||||
data loss is confined to the affected disks; data on
|
||||
other disks remains accessible.
|
||||
* If you accidentally delete files on a disk, recovery is
|
||||
possible.
|
||||
* Disks can have different sizes.
|
||||
* You can add disks at any time.
|
||||
* It doesn't lock-in your data. You can stop using SnapRAID at any
|
||||
time without the need to reformat or move data.
|
||||
* To access a file, only a single disk needs to spin, saving power and
|
||||
producing less noise.
|
||||
* SnapRAID doesn't lock in your data; you can stop using it
|
||||
anytime without reformatting or moving data.
|
||||
* To access a file, only a single disk needs to spin, saving
|
||||
power and reducing noise.
|
||||
|
||||
The official site of SnapRAID is:
|
||||
For more information, please visit the official SnapRAID site:
|
||||
|
||||
http://www.snapraid.it/
|
||||
|
||||
@ -68,26 +65,26 @@ consider before using it.
|
||||
|
||||
The main one is that if a disk fails, and you haven't recently synced,
|
||||
you may be unable to do a complete recover.
|
||||
More specifically, you may be unable to recover up to the size of the
|
||||
amount of the changed or deleted files from the last sync operation.
|
||||
More specifically, you may be unable to recover up to the size of
|
||||
the changed or deleted files from the last sync operation.
|
||||
This happens even if the files changed or deleted are not in the
|
||||
failed disk. This is the reason because SnapRAID is better suited for
|
||||
failed disk. This is why SnapRAID is better suited for
|
||||
data that rarely change.
|
||||
|
||||
Instead the new added files don't prevent the recovering of the already
|
||||
existing files. You may only lose the just added files, if they are on
|
||||
On the other hand, newly added files don't prevent recovering already
|
||||
existing files. You may only lose the recently added files, if they are on
|
||||
the failed disk.
|
||||
|
||||
Other limitations are:
|
||||
Other SnapRAID limitations are:
|
||||
|
||||
* You have different file-systems for each disk.
|
||||
Using a RAID you have only a big file-system.
|
||||
* It doesn't stripe data.
|
||||
* With SnapRAID, you still have separate file-systems for each disk.
|
||||
With RAID you get a single large file-system.
|
||||
* SnapRAID doesn't stripe data.
|
||||
With RAID you get a speed boost with striping.
|
||||
* It doesn't support real-time recovery.
|
||||
* SnapRAID doesn't support real-time recovery.
|
||||
With RAID you do not have to stop working when a disk fails.
|
||||
* It's able to recover damages only from a limited number of disks.
|
||||
With a Backup you are able to recover from a complete
|
||||
* SnapRAID is able to recover damages only from a limited number of disks.
|
||||
With a Backup you can recover from a complete
|
||||
failure of the whole disk array.
|
||||
* Only file, time-stamps, symlinks and hardlinks are saved.
|
||||
Permissions, ownership and extended attributes are not saved.
|
||||
@ -1138,7 +1135,7 @@ WARNING! This option is for experts only, and it's highly
|
||||
recommended to not change it. To change again this value in
|
||||
future you'll have to recreate the whole parity!
|
||||
|
||||
A reason to use a different hashsize is if you have a lot of small
|
||||
A reason to use a different blocksize is if you have a lot of small
|
||||
files. In the order of many millions.
|
||||
|
||||
For each file, even of few bytes, a whole block of parity is allocated,
|
||||
|
@ -35,7 +35,7 @@
|
||||
* All the elements are reallocated in a single resize operation done inside
|
||||
* tommy_hashdyn_insert() or tommy_hashdyn_remove().
|
||||
*
|
||||
* Note that the resize operation takes approximatively 100 [ms] with 1 million of elements,
|
||||
* Note that the resize operation takes approximately 100 [ms] with 1 million of elements,
|
||||
* and 1 [second] with 10 millions. This could be a problem in real-time applications.
|
||||
*
|
||||
* The resize also fragment the heap, as it involves allocating a double-sized table, copy elements,
|
||||
|
7
valgrind.supp
Normal file
7
valgrind.supp
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
printf reports false positives when printing more than one variables at time
|
||||
exp-sgcheck:SorG
|
||||
...
|
||||
fun:printf
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user