1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link href="style.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
<title>Benchmarking backup tools</title>
</head>
<body>
<div class=top>
<img alt="DAR's Documentation" src="dar_s_doc.jpg" style="float:left;">
<div class=h1>
<h1>Benchmarking backup tools</h1>
<h1>Test logs</h1>
</div>
</div>
<h2>Introduction</h2>
<p>
This document keep trace of the tests performed that lead to the summarized results presented in the
<a href="benchmark.html">benchmark document</a>. Several <a href="#scripts">helper scripts</a>
detailed at the end of this document have been necessary to obtain these results.
</p>
<h2>Testing Context</h2>
<h3>Software under test</h3>
<ul>
<li><b>dar</b> version 2.7.0</li>
<li><b>rsync</b> version 3.1.3</li>
<li><b>tar</b> GNU tar 1.30 under Linux and GNU tar (gdar) 1.32 under FreeBSD</li>
</ul>
<h3>Hardware used for testing</h3>
<p>
Performance tests has been performed on an <a href="https://www.hpe.com">HPE</a> Proliant server
(a <i>ProLiant XL230a Gen9</i> running two <i>Intel(R) Xeon(R) CPU E5-2690 v3 @ 2.60GHz</i> processors) running
a Devuan beowulf Linux system. Other tests have been run from Virtual Machines (<a href="https://www.freebsd.org">FreeBSD</a> 12.1,
<a href="https://www.devuan.org">Devuan</a> 3.0.0)
of a <a href="https://www.proxmox.com/en/">Proxmox</a> hypervisor running one on an
<i>Intel Core i5-7400 (3 GHz)</i> based computer.
</p>
<h2>Test logs</h2>
<h3><a name"completness">Completness</a> of backup and restoration</h3>
<h4>Dar</h4>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# ./build_test_tree.bash SRC</b>
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.00395381 s, 265 MB/s
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.00621889 s, 169 MB/s
1+0 records in
1+0 records out
1 byte copied, 0.000386102 s, 2.6 kB/s
<b>root@terre:/mnt/localdisk/Benchmark_tools# dar -c backup -R SRC</b>
--------------------------------------------
14 inode(s) saved
including 3 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
0 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 14
--------------------------------------------
EA saved for 1 inode(s)
FSA saved for 5 inode(s)
--------------------------------------------
<b>root@terre:/mnt/localdisk/Benchmark_tools# mkdir DST</b>
<b>root@terre:/mnt/localdisk/Benchmark_tools# dar -x backup -R DST</b>
--------------------------------------------
14 inode(s) restored
including 3 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
0 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 14
--------------------------------------------
EA restored for 1 inode(s)
FSA restored for 1 inode(s)
--------------------------------------------
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
We simply performed backup of <code>SRC</code> directory with dar's default options, then
restore this backup into the <code>DST</code> directory, let's now compare <code>SRC</code> and <code>DST</code> contents:
</p>
<code class=block>
<b>root@terre:/mnt/localdisk# du -s SRC DST</b>
2068 SRC
<e>1048</e> DST
<b>root@terre:/mnt/localdisk#</b>
</code>
<p>
The space used by <code>DST</code> is less than the space used by <code>SRC</code>! At first
we could beleive that not all data could be restored, let's looking for the explanation:
</p>
<code class=block>
<b>root@terre:/mnt/localdisk#ls -iRl SRC DST</b>
DST:
total 1044
414844 drwxr-xr-x 2 root root 4096 Oct 28 11:09 SUB
414850 drwxr-xr-x 2 root root 4096 Oct 22 11:09 dev
414848 brw-r--r-- 1 root root 2, 1 Oct 28 11:09 fd1
414842 crw-r--r-- 1 root root 3, 1 Oct 28 11:09 null
<e class="red">414841</e> prw-r--r-- 2 root root 0 Oct 28 11:09 pipe
414840 -rw-rwxr--+ 1 root root 1048576 Oct 28 11:09 plain_zeroed
414849 -rw-r--r-- 1 nobody root 1048582 Oct 28 11:09 random
<e>414843</e> -rw-r--r-- 2 root root 10240000 Oct 28 11:09 sparse_file
DST/SUB:
total 4
<e class="red">414841</e> prw-r--r-- 2 root root 0 Oct 28 11:09 hard_linked_pipe
<e class="blue">414846</e> srw-rw-rw- 2 root root 0 Oct 12 23:00 hard_linked_socket
<e>414843</e> -rw-r--r-- 2 root root 10240000 Oct 28 11:09 hard_linked_sparse_file
414845 lrwxrwxrwx 1 root root 6 Oct 28 11:09 symlink-broken -> random
414847 lrwxrwxrwx 1 bin daemon 9 Oct 28 11:09 symlink-valid -> ../random
DST/dev:
total 0
<e class="blue">414846</e> srw-rw-rw- 2 root root 0 Oct 12 23:00 log
SRC:
total 2064
411386 drwxr-xr-x 2 root root 4096 Oct 28 11:09 SUB
414836 drwxr-xr-x 2 root root 4096 Oct 22 11:09 dev
414835 brw-r--r-- 1 root root 2, 1 Oct 28 11:09 fd1
414834 crw-r--r-- 1 root root 3, 1 Oct 28 11:09 null
414832 prw-r--r-- 2 root root 0 Oct 28 11:09 pipe
414826 -rw-rwxr--+ 1 root root 1048576 Oct 28 11:09 plain_zeroed
414827 -rw-r--r-- 1 nobody root 1048582 Oct 28 11:09 random
414828 -rw-r--r-- 2 root root 10240000 Oct 28 11:09 sparse_file
SRC/SUB:
total 4
414832 prw-r--r-- 2 root root 0 Oct 28 11:09 hard_linked_pipe
414837 srw-rw-rw- 2 root root 0 Oct 12 23:00 hard_linked_socket
414828 -rw-r--r-- 2 root root 10240000 Oct 28 11:09 hard_linked_sparse_file
414830 lrwxrwxrwx 1 root root 6 Oct 28 11:09 symlink-broken -> random
414831 lrwxrwxrwx 1 bin daemon 9 Oct 28 11:09 symlink-valid -> ../random
SRC/dev:
total 0
414837 srw-rw-rw- 2 root root 0 Oct 12 23:00 log
<b>root@terre:/mnt/localdisk#</b>
</code>
<p>
All files are present in <code>DST</code> and use the expected space usage, as reported by the <code>ls</code> command.
We can also see that the hard linked inode were properly restored for plain file, named pipe and unix socket: the
inode number in first column is the same (see colorized output above).
</p>
<p>
Maybe something is missing elsewhere?
</p>
<code class=block>
<b>root@terre:/mnt/localdisk# getfacl SRC/plain_zeroed DST/plain_zeroed</b>
# file: SRC/plain_zeroed
# owner: root
# group: root
user::rw-
<e>user:nobody:rwx</e>
group::r--
mask::rwx
other::r--
# file: DST/plain_zeroed
# owner: root
# group: root
user::rw-
<e>user:nobody:rwx</e>
group::r--
mask::rwx
other::r--
<b>root@terre:/mnt/localdisk# getfattr -d SRC/plain_zeroed DST/plain_zeroed</b>
# file: SRC/plain_zeroed
<e>user.hello="hello world!!!"</e>
# file: DST/plain_zeroed
<e>user.hello="hello world!!!"</e>
<b>root@terre:/mnt/localdisk/Benchmark_tools# lsattr SRC/plain_zeroed DST/plain_zeroed</b>
<e>s---i-d-------e----</e> SRC/plain_zeroed
<e>s---i-d-------e----</e> DST/plain_zeroed
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
To summarize:
</p>
<ul>
<li>user and group ownership are restored</li>
<li>permission are set correctly</li>
<li>ACL are properly restored</li>
<li>Extended Attributes also</li>
<li>file system specific attributes are too</li>
<li>hard links are restored</li>
</ul>
<p>
So what? Let's rerun <code>du</code> file by file:
</p>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# du -B1 SRC/* DST/*</b>
8192 SRC/SUB
4096 SRC/dev
0 SRC/fd1
0 SRC/null
<e>1048576 SRC/plain_zeroed</e>
1052672 SRC/random
8192 DST/SUB
4096 DST/dev
0 DST/fd1
0 DST/null
<e>4096 DST/plain_zeroed</e>
1052672 DST/random
<b>root@terre:/mnt/localdisk/Benchmark_tools# ls -l SRC/plain_zeroed DST/plain_zeroed</b>
-rw-rwxr--+ 1 root root <e>1048576</e> Oct 21 18:40 DST/plain_zeroed
-rw-rwxr--+ 1 root root <e>1048576</e> Oct 21 18:40 SRC/plain_zeroed
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
OK here is the explanation: <code>plain_zeroed</code> file was using 1048576 bytes of disk space in SRC
and consumes only 4096 bytes in DST, but it has its file size is still officially 1048576, it has thus become
now a sparse file (not all zeroed bytes are stored).
</p>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# diff -s SRC/plain_zeroed DST/plain_zeroed</b>
Files SRC/plain_zeroed and DST/plain_zeroed are <e>identical</e>
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
But nothing changes from the user point of view, the restoration process with dar just optimized
the space usage.
</p>
<p>
Let's continue checking the inode dates. As you know, Unix inode have several dates:
</p>
<ul>
<li><b>atime</b>, the access time, gives the last time the file's data has been accessed (read)</li>
<li><b>mtime</b>, the modification time, gives the last time the file's data has been modified (wrote)</li>
<li><b>ctime</b>, the change time, gives the last time the file's metadata in other word the inode properties (ownership, ACL, permissions, dates, ...) have been modified</li>
<li><b>btime</b>, the birth time or yet creation time, gives the time the file has been created on the current filesystem, this date is not present on all Unix system</li>
</ul>
<p>
The <code>ls -iRl</code> command we used so far does only show the <i>mtime</i> date moreover with
a time accuracy of only one minute, while modern systems provide nanosecond precision. For that
reason we will use the <code>stat</code> command instead to have all dates at the system time accuracy:
</p>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# stat SRC/random DST/random</b>
File: SRC/random
Size: 1048576 Blocks: 2048 IO Block: 4096 regular file
Device: 802h/2050d Inode: 414840 Links: 1
Access: (0644/-rw-r--r--) Uid: (65534/ nobody) Gid: ( 0/ root)
<e>Access: 2020-10-22 12:13:01.813319506 +0200</e>
<e>Modify: 2020-10-22 12:12:57.765328555 +0200</e>
<e class=red>Change: 2020-10-22 12:12:59.805323991 +0200</e>
Birth: -
File: DST/random
Size: 1048576 Blocks: 2048 IO Block: 4096 regular file
Device: 802h/2050d Inode: 414889 Links: 1
Access: (0644/-rw-r--r--) Uid: (65534/ nobody) Gid: ( 0/ root)
<e>Access: 2020-10-22 12:13:01.813319506 +0200</e>
<e>Modify: 2020-10-22 12:12:57.765328555 +0200</e>
<e class=red>Change: 2020-10-22 12:14:34.877131738 +0200</e>
Birth: -
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
From the above output we see that:
</p>
<ul>
<li>atime is restored</li>
<li>mtime is restored</li>
<li>ctime is not restored</li>
</ul>
<p>
As we targeted this benchmark mainly for Linux which has not yet the <code>btime</code> available
(Well some Linux <a href="https://en.wikipedia.org/wiki/Comparison_of_file_systems#Metadata">file systems</a> support
<i>btime</i> but its access is not yet fully available to applications), we will thus momentarily change to a BSD system
to play with <code>btime</code>. BSD systems include MACOS X, FreeBSD, NetBSD, butterflyBSD,... we will use FreeBSD here.
Under FreeBSD, the <code>stat</code> command is not as easy to read as under Linux, however it is
very flexible which we will leverage to mimic the Linux output:
</p>
<code class=block>
<b>root@FreeBSD:~denis # which mystat</b>
mystat: aliased to <e>stat -f "%N%nAccess: %Sa%nModify: %Sm%nChange: %Sc%nBirth: %SB%n" !*</e>
<b>root@FreeBSD:~denis # mystat SRC/random</b>
SRC/random
Access: Oct 27 13:28:41 2020
Modify: Oct 22 15:34:07 2020
Change: Oct 22 15:34:09 2020
<e>Birth: Oct 22 15:34:07 2020</e>
<b>root@FreeBSD:~denis # dar -c backup -R SRC -q</b>
<b>root@FreeBSD:~denis # mkdir DST</b>
<b>root@FreeBSD:~denis # dar -x backup -R DST -q</b>
<b>root@FreeBSD:~denis # mystat DST/random</b>
DST/random
Access: Oct 27 13:28:41 2020
Modify: Oct 22 15:34:07 2020
Change: Oct 27 13:31:50 2020
<e>Birth: Oct 22 15:34:07 2020</e>
<b>root@FreeBSD:~denis #</b>
</code>
<p>
In conclusion <i>dar</i> also saves and restores <code>btime</code> properly.
</p>
<h4>Rsync</h4>
<p>
Let's do the same we did previously using <b>rsync</b>. We start by copying <code>SRC</code> directory to <code>DST</code>:
</p>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# chattr -i DST/plain_zeroed</b>
<b>root@terre:/mnt/localdisk/Benchmark_tools# rm -rf DST</b>
<b>root@terre:/mnt/localdisk/Benchmark_tools# mkdir DST</b>
<b>root@terre:/mnt/localdisk/Benchmark_tools# rsync -arvHAXS SRC/* DST</b>
sending incremental file list
created directory DST
fd1
null
pipe
plain_zeroed
random
SUB/
SUB/hard_linked_pipe => pipe
SUB/hard_linked_socket
SUB/hard_linked_sparse_file
SUB/symlink-broken -> random
SUB/symlink-valid -> ../random
dev/
dev/log => SUB/hard_linked_socket
sparse_file => SUB/hard_linked_sparse_file
sent 12,340,852 bytes received 198 bytes 24,682,100.00 bytes/sec
total size is 22,577,173 speedup is 1.83
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
First note, the backup and restoration is done in one step, where <i>dar</i> was decorelating the backup operation
from the restoration operation. The resulting backup needs not software to be restored (<code>DST</code>
is a copy of <code>SRC</code>). For dar to reach the same result (without using storage for the backup) this
implies two dar commands: <code> dar -c - -R SRC | dar -x - --sequential-read -R DST</code>. The situation is
similar with <code>tar</code>, you need two commands to perform the same task: <code>tar -cf - | tar -xf -</code>
</p>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# du -s SRC DST</b>
2056 SRC
<e>1028</e> DST
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
Here too, the restored data uses less space than the original data, sparse file have been taken into
account (need specifying -S option) and space optimization of non sparse file is performed.
</p>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# ls -iRl SRC DST</b>
DST:
total 12060
414843 drwxr-xr-x 2 root root 4096 Oct 28 11:09 SUB
414844 drwxr-xr-x 2 root root 4096 Oct 22 11:09 dev
414840 brw-r--r-- 1 root root 2, 1 Oct 28 11:09 fd1
414841 crw-r--r-- 1 root root 3, 1 Oct 28 11:09 null
<e class=red>414842</e> prw-r--r-- 2 root root 0 Oct 28 11:09 pipe
414848 -rw-rwxr--+ 1 root root 1048576 Oct 28 11:09 plain_zeroed
414849 -rw-r--r-- 1 nobody root 1048582 Oct 28 11:09 random
<e>414850</e> -rw-r--r-- 2 root root 10240000 Oct 28 11:09 sparse_file
DST/SUB:
total 10000
<e class=red>414842</e> prw-r--r-- 2 root root 0 Oct 28 11:09 hard_linked_pipe
<e class=blue>414845</e> srw-rw-rw- 2 root root 0 Oct 12 23:00 hard_linked_socket
<e>414850</e> -rw-r--r-- 2 root root 10240000 Oct 28 11:09 hard_linked_sparse_file
414846 lrwxrwxrwx 1 root root 6 Oct 28 11:09 symlink-broken -> random
414847 lrwxrwxrwx 1 bin daemon 9 Oct 28 11:09 symlink-valid -> ../random
DST/dev:
total 0
<e class=blue>414845</e> srw-rw-rw- 2 root root 0 Oct 12 23:00 log
SRC:
total 2064
411386 drwxr-xr-x 2 root root 4096 Oct 28 11:09 SUB
414836 drwxr-xr-x 2 root root 4096 Oct 22 11:09 dev
414835 brw-r--r-- 1 root root 2, 1 Oct 28 11:09 fd1
414834 crw-r--r-- 1 root root 3, 1 Oct 28 11:09 null
414832 prw-r--r-- 2 root root 0 Oct 28 11:09 pipe
414826 -rw-rwxr--+ 1 root root 1048576 Oct 28 11:09 plain_zeroed
414827 -rw-r--r-- 1 nobody root 1048582 Oct 28 11:09 random
414828 -rw-r--r-- 2 root root 10240000 Oct 28 11:09 sparse_file
SRC/SUB:
total 4
414832 prw-r--r-- 2 root root 0 Oct 28 11:09 hard_linked_pipe
414837 srw-rw-rw- 2 root root 0 Oct 12 23:00 hard_linked_socket
414828 -rw-r--r-- 2 root root 10240000 Oct 28 11:09 hard_linked_sparse_file
414830 lrwxrwxrwx 1 root root 6 Oct 28 11:09 symlink-broken -> random
414831 lrwxrwxrwx 1 bin daemon 9 Oct 28 11:09 symlink-valid -> ../random
SRC/dev:
total 0
414837 srw-rw-rw- 2 root root 0 Oct 12 23:00 log
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
All files are present in <code>DST</code> and use the expected space usage, as reported by the <code>ls</code>.
We can also see that all three hard linked inode (plain file, socket and named pipe) are restored properly.
So we can suspect the cause of the size difference to be linked with sparse files:
</p>
<p>
Let's now check file's metadata:
</p>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# getfacl SRC/plain_zeroed DST/plain_zeroed</b>
# file: SRC/plain_zeroed
# owner: root
# group: root
user::rw-
<e>user:nobody:rwx</e>
group::r--
mask::rwx
other::r--
# file: DST/plain_zeroed
# owner: root
# group: root
user::rw-
<e>user:nobody:rwx</e>
group::r--
group::rwx
other::r--
<b>root@terre:/mnt/localdisk/Benchmark_tools# getfattr -d SRC/plain_zeroed DST/plain_zeroed</b>
# file: SRC/plain_zeroed
<e>user.hello="hello world!!!"</e>
# file: DST/plain_zeroed
<e>user.hello="hello world!!!"</e>
<br/>
<b>root@terre:/mnt/localdisk/Benchmark_tools# lsattr SRC/plain_zeroed DST/plain_zeroed</b>
<e class=red>s---i-d-------e----</e> SRC/plain_zeroed
<e class=red>--------------e----</e> DST/plain_zeroed
<b>root@terre:/mnt/localdisk/Benchmark_tools#stat SRC/random DST/random</b>
File: SRC/random
Size: 1048582 Blocks: 2056 IO Block: 4096 regular file
Device: 802h/2050d Inode: 414827 Links: 1
Access: (0644/-rw-r--r--) Uid: (65534/ nobody) Gid: ( 0/ root)
<e class=red>Access: 2020-10-28 11:09:59.977926733 +0100</e>
<e>Modify: 2020-10-28 11:09:57.973931318 +0100</e>
<e class=red>Change: 2020-10-28 11:09:57.973931318 +0100</e>
Birth: -
File: DST/random
Size: 1048582 Blocks: 2056 IO Block: 4096 regular file
Device: 802h/2050d Inode: 414849 Links: 1
Access: (0644/-rw-r--r--) Uid: (65534/ nobody) Gid: ( 0/ root)
<e class=red>Access: 2020-10-28 12:07:53.622841733 +0100</e>
<e>Modify: 2020-10-28 11:09:57.973931318 +0100</e>
<e class=red>Change: 2020-10-28 12:07:53.622841733 +0100</e>
Birth: -
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
So in summary:
</p>
<ul>
<li>Permission are restored,</li>
<li>user and group ownership are restored too,</li>
<li>mtime is restored,</li>
<li>File ACL are restored,</li>
<li>Extended Attributes are restored</li>
</ul>
<p>
But
</p>
<ul>
<li>filesystem specific attributes are not restored,</li>
<li>atime is not restored,</li>
<li>ctime is not restored</li>
</ul>
<p>
For <b>btime</b> as we did before, let's test under a FreeBSD system:
</p>
<code class=block>
<b>root@FreeBSD:~denis # rm -rf DST</b>
<b>root@FreeBSD:/home/denis # which mystat</b>
mystat: aliased to stat -f "%N%nAccess: %Sa%nModify: %Sm%nChange: %Sc%nBirth: %SB%n" !*
<b>root@FreeBSD:/home/denis # mystat SRC/random</b>
SRC/random
Access: Oct 27 14:27:59 2020
Modify: Oct 22 15:34:07 2020
Change: Oct 22 15:34:09 2020
<e>Birth: Oct 22 15:34:07 2020</e>
root@FreeBSD:/home/denis # mkdir DST
root@FreeBSD:/home/denis # rsync -arv SRC/* DST
sending incremental file list
fd1
null
pipe
plain_zeroed
random
sparse_file
SUB/
SUB/hard_linked_socket
SUB/hard_linked_sparse_file
SUB/symlink-broken -> random
SUB/symlink-valid -> ../random
dev/
dev/log -> /var/run/log
sent 22,583,283 bytes received 129 bytes 45,166,824.00 bytes/sec
total size is 22,577,179 speedup is 1.00
root@FreeBSD:/home/denis # mystat DST/random
DST/random
Access: Oct 27 14:28:53 2020
Modify: Oct 22 15:34:07 2020
Change: Oct 27 14:28:53 2020
<e>Birth: Oct 22 15:34:07 2020</e>
<b>root@FreeBSD:/home/denis #</b>
</code>
<p>
So, birthtime is properly restored.
</p>
<h4>Tar</h4>
<p>
As done with previously, let's save and restore the <code>SRC</code> directory to <code>DST</code>... Note that by default
no sparse file is taken into account (this is why we added the <code>-S option</code>), same with acl (so we added
the <code>--acl</code> option) and Extended Attributes (unless <code>--xattrs</code> is added). The
<i>tar</i> command-line becomes thus a bit longer:
</p>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# rm -rf DST</b>
<b>root@terre:/mnt/localdisk/Benchmark_tools# cd SRC</b>
<b>root@terre:/mnt/localdisk/Benchmark_tools/SRC# tar --acl --xattrs -cSf ../backup.tar *</b>
tar: SUB/hard_linked_socket: socket ignored
tar: dev/log: socket ignored
<b>root@terre:/mnt/localdisk/Benchmark_tools/SRC# cd ../</b>
<b>root@terre:/mnt/localdisk/Benchmark_tools# mkdir DST</b>
<b>root@terre:/mnt/localdisk/Benchmark_tools# cd DST</b>
<b>root@terre:/mnt/localdisk/Benchmark_tools/DST# tar --acl --xattrs -xSf ../backup.tar</b>
<b>root@terre:/mnt/localdisk/Benchmark_tools/DST# cd ..</b>
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
Now let's compare the restored data with the original:
</p>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# du -s SRC DST</b>
2068 SRC
<e>2068</e> DST
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
The sparse file has been properly restored (thanks to the <code>-S option</code> for that) but not space optimization
has been performed.
</p>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# ls -iRl SRC DST</b>
DST:
total 12060
414841 drwxr-xr-x 2 root root 4096 Oct 28 11:09 SUB
414846 drwxr-xr-x 2 root root 4096 Oct 22 11:09 dev
414847 brw-r--r-- 1 root root 2, 1 Oct 28 11:09 fd1
414848 crw-r--r-- 1 root root 3, 1 Oct 28 11:09 null
414849 prw-r--r-- <e class=red>1</e> root root 0 Oct 28 11:09 pipe
414850 -rw-rwxr-- 1 root root 1048576 Oct 28 11:09 plain_zeroed
414852 -rw-r--r-- 1 nobody root 1048582 Oct 28 11:09 random
<e>414843</e> -rw-r--r-- 2 root root 10240000 Oct 28 11:09 sparse_file
DST/SUB:
total 10000
414845 prw-r--r-- 1 root root 0 Oct 28 11:09 hard_linked_pipe
<e>414843</e> -rw-r--r-- 2 root root 10240000 Oct 28 11:09 hard_linked_sparse_file
414842 lrwxrwxrwx 1 root root 6 Oct 28 11:09 symlink-broken -> random
414844 lrwxrwxrwx 1 bin daemon 9 Oct 28 11:09 symlink-valid -> ../random
DST/dev:
total 0
SRC:
total 2064
411386 drwxr-xr-x 2 root root 4096 Oct 28 11:09 SUB
414836 drwxr-xr-x 2 root root 4096 Oct 22 11:09 dev
414835 brw-r--r-- 1 root root 2, 1 Oct 28 11:09 fd1
414834 crw-r--r-- 1 root root 3, 1 Oct 28 11:09 null
414832 prw-r--r-- <e class=red>2</e> root root 0 Oct 28 11:09 pipe
414826 -rw-rwxr--+ 1 root root 1048576 Oct 28 11:09 plain_zeroed
414827 -rw-r--r-- 1 nobody root 1048582 Oct 28 11:09 random
414828 -rw-r--r-- 2 root root 10240000 Oct 28 11:09 sparse_file
SRC/SUB:
total 4
414832 prw-r--r-- 2 root root 0 Oct 28 11:09 hard_linked_pipe
<e class=red>414837 srw-rw-rw- 2 root root 0 Oct 12 23:00 hard_linked_socket</e>
414828 -rw-r--r-- 2 root root 10240000 Oct 28 11:09 hard_linked_sparse_file
414830 lrwxrwxrwx 1 root root 6 Oct 28 11:09 symlink-broken -> random
414831 lrwxrwxrwx 1 bin daemon 9 Oct 28 11:09 symlink-valid -> ../random
SRC/dev:
total 0
<e class=red>414837 srw-rw-rw- 2 root root 0 Oct 12 23:00 log</e>
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
The warning was not vain, <code>SUB/hard_linked_socket</code> and <code>log</code> are missing in <code>DST</code>.
This is however a minor problem as usually unix sockets get recreated by the process using them. However
we might have some permission and ownership to set back, by hand. A possible use case is <code>syslog</code> daemon,
when let available for a chrooted process or container (MTA, or other network service).
</p>
<p>
The second problem is a bit more annoying: the hard linked fifo (aka named pipe)
is silently restored as two independent named pipes (the inode number are different in the first column
for <code>pipe</code> and <code>SUB/hard_linked_pipe</code> and their respective link count was <code>2</code>
in <code>SRC</code> but is now <code>1</code> in <code>DST</code>. If two processes in different namespaces or
chrooted environment, exchange data by mean of such hardlinked pipe, after restoration, if you are not
aware of this failure, it will thus be difficult to identify why the two processes are just locked out, one
waiting for data that will never come from the pipe, the other stuck for the pipe to be read.
</p>
<p>
Let's continue by checking the file's metadata:
</p>
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# getfacl SRC/plain_zeroed DST/plain_zeroed</b>
# file: SRC/plain_zeroed
# owner: root
# group: root
user::rw-
<e>user:nobody:rwx</e>
group::r--
mask::rwx
other::r--
# file: DST/plain_zeroed
# owner: root
# group: root
user::rw-
<e>user:nobody:rwx</e>
group::r--
mask::rwx
other::r--
root@terre:/mnt/localdisk/Benchmark_tools# getfattr -d SRC/plain_zeroed DST/plain_zeroed
# file: SRC/plain_zeroed
<e>user.hello="hello world!!!"</e>
# file: DST/plain_zeroed
<e>user.hello="hello world!!!"</e>
<b>root@terre:/mnt/localdisk/Benchmark_tools# lsattr SRC/plain_zeroed DST/plain_zeroed</b>
<e class=red>s---i-d-------e----</e> SRC/plain_zeroed
<e class=red>--------------e----</e> DST/plain_zeroed
<b>root@terre:/mnt/localdisk/Benchmark_tools#</b>
</code>
<p>
Note that without <code>--xattrs</code> at creation time the timestamp accuracy of <i>tar</i>
is 1 second:
<code class=block>
<b>root@terre:/mnt/localdisk/Benchmark_tools# stat SRC/random DST/random</b>
File: SRC/random
Size: 1048576 Blocks: 2048 IO Block: 4096 regular file
Device: 802h/2050d Inode: 414841 Links: 1
Access: (0644/-rw-r--r--) Uid: (65534/ nobody) Gid: ( 0/ root)
<e class=red>Access: 2020-10-27 14:03:46.064046436 +0100</e>
<e>Modify: 2020-10-27 14:03:42.016050420 +0100</e>
<e class=red>Change: 2020-10-27 14:03:44.048048418 +0100</e>
Birth: -
File: DST/random
Size: 1048576 Blocks: 2048 IO Block: 4096 regular file
Device: 802h/2050d Inode: 414890 Links: 1
Access: (0644/-rw-r--r--) Uid: (65534/ nobody) Gid: ( 0/ root)
<e class=red>Access: 2020-10-27 19:08:14.932424226 +0100</e>
<e>Modify: 2020-10-27 14:03:42</e>.<e class=red>000000000 +0100</e>
<e class=red>Change: 2020-10-27 19:08:14.932424226 +0100</e>
Birth: -
root@terre:/mnt/localdisk/Benchmark_tools#
</code>
<p>
From the above output we see that:
</p>
<ul>
<li>permission are restored,</li>
<li>user and group ownership are restored too,</li>
<li>mtime is restored but it needs <code>--xattrs</code> to take into account today's system common time accuracy of one nanosecond</li>
<li>ACL are restored,</li>
<li>Extended Attributes are restored</li>
</ul>
<p>
But
</p>
<ul>
<li>filesystem attributes are not restored,</li>
<li>atime is not restored,</li>
<li>ctime is not restored</li>
</ul>
<p>
For the last date, <b>birthtime</b> again we will perform the test under FreeBSD:
</p>
<code class=block>
<b>root@FreeBSD:~denis # which mystat</b>
mystat: aliased to stat -f "%N%nAccess: %Sa%nModify: %Sm%nChange: %Sc%nBirth: %SB%n" !*
<b>root@FreeBSD:~denis # mystat SRC/random</b>
SRC/random
Access: Oct 27 19:40:13 2020
Modify: Oct 22 15:34:07 2020
Change: Oct 22 15:34:09 2020
<e>Birth: Oct 22 15:34:07 2020</e>
<b>root@FreeBSD:~denis # cd SRC</b>
<b>root@FreeBSD:~denis/SRC # gtar -cf ../backup.tar random</b>
<b>root@FreeBSD:~denis/SRC # cd ..</b>
<b>root@FreeBSD:~denis # mkdir DST</b>
<b>root@FreeBSD:~denis # cd DST</b>
<b>root@FreeBSD:~denis/DST # tar -xf ../backup.tar</b>
<b>root@FreeBSD:~denis/DST # cd ..</b>
<b>root@FreeBSD:~denis # mystat DST/random</b>
DST/random
Access: Oct 28 15:43:30 2020
Modify: Oct 22 15:34:07 2020
Change: Oct 28 15:43:30 2020
<e>Birth: Oct 22 15:34:07 2020</e>
<b>root@FreeBSD:~denis #</b>
</code>
<p>
<i>gtar</i> saved and restored the birthtime
</p>
<h3><a name="features">Feature</a> set</h3>
<h4>Historization</h4>
<p>
To evaluate this feature, in a first time we will create two files <i>A.txt</i> and <i>B.txt</i>
and make a first backup. Then we remove <i>A.txt</i> and add <i>C.txt</i> then make
a second backup. We should be able to restore the data in both states (A+B and B+C).
To simplify the operation we use the <a href="#historization_feature"><i>historization_feature</i></a>
script described at the end of this document.
</p>
<h5>Dar</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# rm -rf SRC</b>
<b>root@terre:/mnt/memdisk# ./historization_feature SRC phase1</b>
<b>root@terre:/mnt/memdisk# dar -c full -g SRC -q</b>
<b>root@terre:/mnt/memdisk# ./historization_feature SRC phase2</b>
<b>root@terre:/mnt/memdisk# dar -c diff -A full -g SRC -q</b>
<b>root@terre:/mnt/memdisk# mkdir DST</b>
<b>root@terre:/mnt/memdisk# dar -x full -R DST -q</b>
<b>root@terre:/mnt/memdisk# ls -lR DST</b>
DST:
total 0
drwxr-xr-x 2 root root 80 Nov 6 18:37 SRC
DST/SRC:
total 8
-rw-r--r-- 1 root root 13 Nov 6 18:37 <e>A.txt</e>
-rw-r--r-- 1 root root 24 Nov 6 18:37 <e>B.txt</e>
<b>root@terre:/mnt/memdisk# dar -x diff -R DST -w -q</b>
<b>root@terre:/mnt/memdisk# ls -lR DST</b>
DST:
total 0
drwxr-xr-x 2 root root 80 Nov 6 18:38 SRC
DST/SRC:
total 8
-rw-r--r-- 1 root root 24 Nov 6 18:37 <e>B.txt</e>
-rw-r--r-- 1 root root 21 Nov 6 18:38 <e>C.txt</e>
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
Historization is present, we can get back from backup both saved states
</p>
<p>
In complement <i>dar</i> proposes a manager <i>dar_manager</i> to easily locate file's status between the archives
the database has been feeded with, as well as the file's data present in each archive:
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# dar_manager -C base.dmd</b>
<b>root@terre:/mnt/memdisk# dar_manager -B base.dmd -A full</b>
<b>root@terre:/mnt/memdisk# dar_manager -B base.dmd -A diff</b>
<b>root@terre:/mnt/memdisk# dar_manager -B base.dmd -f SRC/A.txt</b>
1 Fri Nov 6 18:37:51 2020 saved absent
2 Fri Nov 6 18:38:04 2020 removed absent
<b>root@terre:/mnt/memdisk# dar_manager -B base.dmd -f SRC/B.txt</b>
1 Fri Nov 6 18:37:51 2020 saved absent
2 Fri Nov 6 18:37:51 2020 present absent
<b>root@terre:/mnt/memdisk# dar_manager -B base.dmd -f SRC/C.txt</b>
2 Fri Nov 6 18:38:04 2020 saved absent
<b>root@terre:/mnt/memdisk# dar_manager -B base.dmd -l</b>
dar path :
dar options :
database version: 5
compression used: gzip
archive # | path | basename
------------+--------------+---------------
1 . full
2 . diff
<b>root@terre:/mnt/memdisk# dar_manager -B base.dmd -u 1</b>
[ Saved ][ ] SRC/B.txt
[ Saved ][ ] SRC/A.txt
<b>root@terre:/mnt/memdisk# dar_manager -B base.dmd -u 2</b>
[ Saved ][ ] SRC
[ Saved ][ ] SRC/C.txt
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
<i>dar_manager</i> can even take for you the actions to invoke <i>dar</i> as many time as necessary
get the file's status of a given date for a given set of subset of the saved files:
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# dar_manager -v -B base.dmd -e "-R DST -w" -r SRC</b>
Decompressing and loading database to memory...
Looking in archives for requested files, classifying files archive by archive...
Checking chronological ordering of files between the archives...
File recorded as removed at this date in database: SRC/A.txt
CALLING DAR: restoring 1 files from archive ./full using anonymous pipe to transmit configuration to the dar process
Arguments sent through anonymous pipe are:
dar -x ./full -R DST -w -g SRC/B.txt
--------------------------------------------
2 inode(s) restored
including 0 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
1 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 3
--------------------------------------------
EA restored for 0 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
CALLING DAR: restoring 2 files from archive ./diff using anonymous pipe to transmit configuration to the dar process
Arguments sent through anonymous pipe are:
dar -x ./diff -R DST -w -g SRC -g SRC/C.txt
Error while restoring /mnt/memdisk/DST/SRC/A.txt : Cannot remove non-existent file from filesystem: /mnt/memdisk/DST/SRC/A.txt
--------------------------------------------
2 inode(s) restored
including 0 hard link(s)
1 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
0 inode(s) ignored (excluded by filters)
1 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 4
--------------------------------------------
EA restored for 0 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
Final memory cleanup...
All files asked could not be restored
DAR sub-process has terminated with exit code 5 Continue anyway ? [return = YES | Esc = NO]
Continuing...
<b>root@terre:/mnt/memdisk# ls -lR DST</b>
DST:
total 0
drwxr-xr-x 2 root root 80 Nov 6 18:38 SRC
DST/SRC:
total 8
-rw-r--r-- 1 root root 24 Nov 6 18:37 <e>B.txt</e>
-rw-r--r-- 1 root root 21 Nov 6 18:38 <e>C.txt</e>
<b>root@terre:/mnt/memdisk#</b>
</code>
<h5>Rsync</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# ./historization_feature SRC phase1</b>
<b>root@terre:/mnt/memdisk# rsync -arvHAX SRC DST</b>
sending incremental file list
created directory DST
SRC/
SRC/A.txt
SRC/B.txt
sent 229 bytes received 84 bytes 626.00 bytes/sec
total size is 37 speedup is 0.12
<b>root@terre:/mnt/memdisk# ./historization_feature SRC phase2</b>
<b>root@terre:/mnt/memdisk# rsync -arvHAX SRC DST</b>
sending incremental file list
SRC/
SRC/C.txt
sent 172 bytes received 39 bytes 422.00 bytes/sec
total size is 45 speedup is 0.21
<b>root@terre:/mnt/memdisk# ls -l</b>
total 4
drwxr-xr-x 3 root root 60 Nov 6 17:06 DST
drwxr-xr-x 2 root root 80 Nov 6 17:06 SRC
-rwxr--r-- 1 root root 589 Nov 6 16:32 historization_feature
<b>root@terre:/mnt/memdisk# ls -l DST</b>
total 0
drwxr-xr-x 2 root root 100 Nov 6 17:06 SRC
<b>root@terre:/mnt/memdisk# ls -l DST/SRC</b>
total 12
<e>-rw-r--r-- 1 root root 13 Nov 6 17:05 A.txt</e>
<e>-rw-r--r-- 1 root root 24 Nov 6 17:05 B.txt</e>
<e>-rw-r--r-- 1 root root 21 Nov 6 17:06 C.txt</e>
<b>root@terre:/mnt/memdisk# rsync -arvHAX --delete SRC DST</b>
sending incremental file list
deleting SRC/A.txt
sent 101 bytes received 26 bytes 254.00 bytes/sec
total size is 45 speedup is 0.35
<b>root@terre:/mnt/memdisk# ls -l DST/SRC</b>
total 8
<e>-rw-r--r-- 1 root root 24 Nov 6 17:05 B.txt</e>
<e>-rw-r--r-- 1 root root 21 Nov 6 17:06 C.txt</e>
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
the "backup" contains all three files, <i>A.txt</i>, <i>B.txt</i>
and <i>C.txt</i> while the first and the later never existed at the
same time. Such backup does not allow to have neither the state of
the <i>phase1</i> nor the state of the <i>phase2</i>.
</p>
<p>
We added the <code>--delete</code> option and as result we got
to be the <i>phase2</i> state only. But then we cannot restore to the <i>phase1</i> state as the
file <i>A.txt</i> has been deleted from the backup.
</p>
<p>
To have both states with <i>rsync</i>, we should call rsync to a different destination directory
at each new backup time, which would consume a lot of space and would also defeat one of the main
features of <i>rsync</i> which is its ability to synchronize two directories exchanging only
the minimal information that was modified.
</p>
<h5>Tar</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# rmdir SRC</b>
<b>root@terre:/mnt/memdisk# ./historization_feature SRC phase1</b>
<b>root@terre:/mnt/memdisk# tar --listed-incremental=snapshot.file -cf full.tar SRC</b>
<b>root@terre:/mnt/memdisk# ./historization_feature SRC phase2</b>
<b>root@terre:/mnt/memdisk# tar --listed-incremental=snapshot.file -cf diff.tar SRC</b>
<b>root@terre:/mnt/memdisk# mkdir DST</b>
<b>root@terre:/mnt/memdisk# cd DST</b>
<b>root@terre:/mnt/memdisk/DST# tar --listed-incremental=snapshot.file -xf ../full.tar</b>
<b>root@terre:/mnt/memdisk/DST# ls -l SRC</b>
total 8
<e>-rw-r--r-- 1 root root 13 Nov 6 18:20 A.txt</e>
<e>-rw-r--r-- 1 root root 24 Nov 6 18:20 B.txt</e>
<b>root@terre:/mnt/memdisk/DST# tar --listed-incremental=snapshot.file -xf ../diff.tar</b>
<b>root@terre:/mnt/memdisk/DST# ls -l SRC</b>
total 8
<e>-rw-r--r-- 1 root root 24 Nov 6 18:20 B.txt</e>
<e>-rw-r--r-- 1 root root 21 Nov 6 18:21 C.txt</e>
<b>root@terre:/mnt/memdisk/DST#</b>
</code>
<p>
We could restore from backup both the phase1 and phase2 status, historization is available with tar.
</p>
<h4>Data filtering by directory</h4>
<h5>Dar</h5>
<p>
We want to save <code>/lib</code> except the content of <code>/lib/modules</code>:
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# dar -c backup -R /lib -P modules -vs -q</b>
<e>Skipping file: /lib/modules</e>
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
What if we want to exclude all of to exclude <code>/lib/module</code> except
<code>/lib/module/4.19.0-12-amd64</code>?
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# rm backup.1.dar</b>
rm: remove regular file 'backup.1.dar'? y
<b>root@terre:/mnt/memdisk# dar -c backup -R /lib -am -P modules -g modules/4.19.0-12-amd64 -vs -q</b>
<e>Skipping file: /lib/modules/4.19.0-11-amd64</e>
<e>Skipping file: /lib/modules/4.19.0-10-amd64</e>
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
OK, we can mix included directories and excluded directories
</p>
<h5>Rsync</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# rm -rf DST</b>
<b>root@terre:/mnt/memdisk# mkdir DST</b>
<b>root@terre:/mnt/memdisk# rsync -arHAXS --exclude /lib/modules /lib DST</b>
<b>root@terre:/mnt/memdisk# ls -ld DST/lib/m*</b>
drwxr-xr-x 2 root root 80 Jun 11 23:33 DST/lib/modprobe.d
<b>root@terre:/mnt/memdisk#</b>
<b>root@terre:/mnt/memdisk# ls -l DST/lib/modules</b>
ls: cannot access <e>'DST/lib/modules': No such file or directory</e>
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
We could exclude <code>/lib/modules</code> as expected. As previously, let's exclude it
except <code>/lib/modules/4.19.0-12-amd64</code>:
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# rm -rf DST</b>
<b>root@terre:/mnt/memdisk# rsync -arHAXS -f "+ /lib/modules" -f "- /lib/modules/4.19.0-12-amd64" /lib DST</b>
<b>root@terre:/mnt/memdisk# la DST/lib/modules/</b>
total 0
drwxr-xr-x 4 root root 80 Oct 22 10:33 .
drwxr-xr-x 19 root root 420 Oct 22 11:20 ..
<e>drwxr-xr-x 3 root root 280 Aug 8 12:58 4.19.0-10-amd64</e>
<e>drwxr-xr-x 3 root root 280 Oct 12 11:25 4.19.0-11-amd64</e>
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
OK, we can mix included directories and excluded directories
</p>
<h5>Tar</h5>
<p>
Let's save /lib and excluding /lib/module again:
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# tar --exclude /lib/modules -cf backup.tar /lib</b>
tar: Removing leading `/' from member names
<b>root@terre:/mnt/memdisk# tar -tf backup.tar | grep modules</b>
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
Now let's exclude <code>/lib/modules</code> except <code>/lib/modules/4.19.0-12-amd64</code>:
<p>
<code class=block>
<b>root@terre:/mnt/memdisk# tar -cf backup.tar /lib/modules/4.19.0-12-amd64/ --exclude /lib/modules /lib</b>
tar: Removing leading `/' from member names
tar: Removing leading `/' from hard link targets
<b>root@terre:/mnt/memdisk# tar -tf backup.tar | wc -l</b>
6017
<b>root@terre:/mnt/memdisk# tar -tf backup.tar | grep -v "lib/modules/4.19.0-12-amd64" | wc -l</b>
1626
<b>root@terre:/mnt/memdisk# tar -tf backup.tar | grep "lib/modules/4.19.0-12-amd64" | wc -l</b>
4391
<b>root@terre:/mnt/memdisk# tar -tf backup.tar | grep "lib/modules" | wc -l</b>
4391
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
The backup contains a total of 6017 entries, 1626 are out of the <code>lib/modules/4.19.0-12-amd64</code>
directory, the rest is all in that previous directory, nothing else is found in <code>lib/modules</code>
while there was <code>lib/modules/4.19.0-11-amd64</code> and <code>lib/modules/4.19.0-10-amd64</code>
subdirectory. We can thus mix included and included directories.
</p>
<h4>Data filtering by filename</h4>
<h5>Dar</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# dar -c backup -R /lib -X "*.ko"</b>
--------------------------------------------
4122 inode(s) saved
including 0 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
<e>10677 inode(s) ignored (excluded by filters)</e>
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 14799
--------------------------------------------
EA saved for 0 inode(s)
FSA saved for 3945 inode(s)
--------------------------------------------
<b>root@terre:/mnt/memdisk# mkdir DST</b>
<b>root@terre:/mnt/memdisk# dar -x backup -R DST --fsa-scope none</b>
--------------------------------------------
4122 inode(s) restored
including 0 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
0 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 4122
--------------------------------------------
EA restored for 0 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
<b>root@terre:/mnt/memdisk# find DST -name "*.ko" -ls</b>
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
we would exclude all file having the <code>ko</code> extension, what if we do not
want to exclude those that start with <code>ext</code>?
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# dar -c backup -R /lib -am -X "*.ko" -I "ext*"</b>
--------------------------------------------
4128 inode(s) saved
including 0 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
10671 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 14799
--------------------------------------------
EA saved for 0 inode(s)
FSA saved for 3951 inode(s)
--------------------------------------------
<b>root@terre:/mnt/memdisk# rm -rf DST</b>
<b>root@terre:/mnt/memdisk# mkdir DST</b>
<b>root@terre:/mnt/memdisk# dar -x backup -R DST --fsa-scope none -q</b>
<b>root@terre:/mnt/memdisk# find DST -name "*.ko" -print</b>
DST/modules/4.19.0-10-amd64/kernel/fs/ext4/ext4.ko
DST/modules/4.19.0-10-amd64/kernel/drivers/extcon/extcon-core.ko
DST/modules/4.19.0-11-amd64/kernel/fs/ext4/ext4.ko
DST/modules/4.19.0-11-amd64/kernel/drivers/extcon/extcon-core.ko
DST/modules/4.19.0-12-amd64/kernel/fs/ext4/ext4.ko
DST/modules/4.19.0-12-amd64/kernel/drivers/extcon/extcon-core.ko
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
OK, we got what we wanted
</p>
<h5>Rsync</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# rm -rf DST</b>
<b>root@terre:/mnt/memdisk# rsync -arHAXS -f "- *.ko" /lib DST</b>
<b>root@terre:/mnt/memdisk# find DST -name "*.ko" -print</b>
<b>root@terre:/mnt/memdisk# ls DST</b>
lib
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
Same as previously, we don't want to exclude <code>ko</code> files starting by <code>ext</code>:
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# rm -rf DST</b>
<b>root@terre:/mnt/memdisk# rsync -arHAXS -f "+ ext*" -f "- *.ko" /lib DST</b>
<b>root@terre:/mnt/memdisk# find DST -name "*.ko" -print</b>
DST/lib/modules/4.19.0-12-amd64/kernel/fs/ext4/ext4.ko
DST/lib/modules/4.19.0-12-amd64/kernel/drivers/extcon/extcon-core.ko
DST/lib/modules/4.19.0-11-amd64/kernel/fs/ext4/ext4.ko
DST/lib/modules/4.19.0-11-amd64/kernel/drivers/extcon/extcon-core.ko
DST/lib/modules/4.19.0-10-amd64/kernel/fs/ext4/ext4.ko
DST/lib/modules/4.19.0-10-amd64/kernel/drivers/extcon/extcon-core.ko
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
OK, we got what we wanted
</p>
<h5>Tar</h5>
<p>Same as previously, let's filter out kernel object files</p>
<code class=block>
<b>root@terre:/mnt/memdisk# tar -cf backup.tar --exclude "*.ko" /lib</b>
tar: Removing leading `/' from member names
<b>root@terre:/mnt/memdisk# rm -rf DST</b>
<b>root@terre:/mnt/memdisk# mkdir DST</b>
<b>root@terre:/mnt/memdisk# cd DST</b>
<b>root@terre:/mnt/memdisk/DST# tar -xf ../backup.tar</b>
<b>root@terre:/mnt/memdisk/DST# find . -name "*.ko" -print</b>
<b>root@terre:/mnt/memdisk/DST#</b>
</code>
<p>Now, we want to keep only those kernel object files starting with <code>ext</code></p>
<code class=block>
<b>root@terre:/mnt/memdisk# tar -cf backup.tar "ext*" --exclude "*.ko" /lib</b>
tar: ext*: Cannot stat: No such file or directory
tar: Removing leading `/' from member names
tar: Removing leading `/' from hard link targets
tar: Exiting with failure status due to previous errors
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
Well, argument passed out of option do not seem expanded by tar thus using mask is not
possible to include some pattern. It seems the only option is to use file listing, thing
we will evaluate below.
</p>
<h4>Data filtering by filesystem</h4>
<p>
We will use a tmpfs filesystem mounted twice thanks to mount's --bind option. The objective
is first to save every thing except a few given filesystems, or only one or save inside a few
given filesystems. Here is the preparation phase:
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# mkdir SRC</b>
<b>root@terre:/mnt/memdisk# mkdir SRC/D1 SRC/D2 SRC/D3</b>
<b>root@terre:/mnt/memdisk# mount -t tmpfs tmpfs SRC/D1</b>
<b>root@terre:/mnt/memdisk# mount --bind SRC/D1 SRC/D2</b>
<b>root@terre:/mnt/memdisk# mount -t tmpfs tmpfs SRC/D3</b>
<b>root@terre:/mnt/memdisk# ls SRC/D1 SRC/D2</b>
SRC/D1:
SRC/D2:
<b>root@terre:/mnt/memdisk# echo "Hello World" > SRC/D1/file.txt</b>
<b>root@terre:/mnt/memdisk# ls SRC/D1 SRC/D2</b>
SRC/D1:
file.txt
SRC/D2:
file.txt
<b>root@terre:/mnt/memdisk# echo "give me your data, I'll tell your needs and what to buy" > SRC/gafam.com</b>
<b>root@terre:/mnt/memdisk# echo "sight" > SRC/D3/democracy.org</b>
<b>root@terre:/mnt/memdisk#</b>
</code>
<h5>Dar</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# dar -c backup -R SRC -MX:/mnt/memdisk/SRC/D1 -vs -vt -q</b>
Adding folder to archive: /mnt/memdisk/SRC/D3
Adding file to archive: /mnt/memdisk/SRC/D3/democracy.org
Adding file to archive: /mnt/memdisk/SRC/gafam.com
Skipping file: /mnt/memdisk/SRC/D2
Skipping file: /mnt/memdisk/SRC/D1
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
We could exclude a filesystem, and its second appearance in D2 was also excluded,
whithout having to mention it. Let's include only <code>D1</code> now:
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# rm -f backup.1.dar</b>
<b>root@terre:/mnt/memdisk# dar -c backup -R SRC -MI:/mnt/memdisk/SRC/D1 -vs -vt -q</b>
Skipping file: /mnt/memdisk/SRC/D3
Adding file to archive: /mnt/memdisk/SRC/gafam.com
Adding folder to archive: /mnt/memdisk/SRC/D2
Adding file to archive: /mnt/memdisk/SRC/D2/file.txt
Adding folder to archive: /mnt/memdisk/SRC/D1
Adding file to archive: /mnt/memdisk/SRC/D1/file.txt
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
OK, we got what we wanted
</p>
<h5>Rsync</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# rsync -arvHAXS --one-file-system SRC DST</b>
sending incremental file list
created directory DST
SRC/
SRC/gafam.com
SRC/D1/
SRC/D2/
SRC/D3/
sent 283 bytes received 77 bytes 720.00 bytes/sec
total size is 56 speedup is 0.16
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
<i>rsync</i> has ony one option about filesystems, it sticks recursion to the filesystem
of the source directory, we cannot exclude specifically some filesystems, they are all excluded,
and we cannot include specifically some filesystems, none is excluded (default behavior without this option)
</p>
<h5>Tar</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# tar -cvf backup.tar --one-file-system SRC</b>
SRC/
SRC/D3/
tar: SRC/D3/: file is on a different filesystem; not dumped
SRC/gafam.com
SRC/D2/
tar: SRC/D2/: file is on a different filesystem; not dumped
SRC/D1/
tar: SRC/D1/: file is on a different filesystem; not dumped
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
<i>tar</i> does not behaves better than rsync on that topic
</p>
<h4>Data filtering by tag</h4>
<p>
by tag we mean any mark the user can add to a file that will drive its fate when backup will be done.
The most common is the <i>dump</i> flag, but it is not always available, using some other mechanisms
(Extended Attributes,...) can be an interesting alternative.
</p>
<h5>Dar</h5>
<code class=block>
<b>root@terre:/var/tmp# mkdir SRC</b>
<b>root@terre:/var/tmp# echo "Hello" > file1.txt</b>
<b>root@terre:/var/tmp# echo "World" > file2.txt</b>
<b>root@terre:/var/tmp# chattr <e class=blue>+d</e> file1.txt</b>
<b>root@terre:/var/tmp# setfattr -n <e>user.no_dump</e> file2.txt</b>
<b>root@terre:/var/tmp# mv file1.txt file2.txt SRC</b>
<b>root@terre:/var/tmp# dar -c backup -w -R SRC <e class=blue>--nodump</e> -vt -q</b>
<e>Adding file to archive: /var/tmp/SRC/file2.txt</e>
Saving Extended Attributes for /var/tmp/SRC/file2.txt
Saving Filesystem Specific Attributes for /var/tmp/SRC/file2.txt
<b>root@terre:/var/tmp# dar -c backup -w -R SRC <e>--exclude-by-ea=user.no_dump</e> -vt -q</b>
<e class=blue>Adding file to archive: /var/tmp/SRC/file1.txt</e>
Saving Filesystem Specific Attributes for /var/tmp/SRC/file1.txt
<b>root@terre:/var/tmp#</b>
</code>
<p>
We have two mechanisms, one based on the <i>dump</i> flag and an arbitrary extended attribute.
However <i>dar</i> only supports exclusion of file, not inclusion for backup based on a tag.
</p>
<h5>Rsync</h5>
<p>
<i>rsync</i> does not seem to be able to filter based on an arbitrary mark
</p>
<h5>Tar</h5>
<p>
<i>rsync</i> does not seem to be able to filter based on an arbitrary mark
</p>
<h4>Data filtering by files listing</h4>
<p>
We build a file listing and expect to either have only those file saved
or excluded from the performed backup. Here is the listing preparation:
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# find /lib -name "*.ko" -o -print > include.txt</b>
<b>root@terre:/mnt/memdisk# wc -l include.txt</b>
4123 include.txt
<b>root@terre:/mnt/memdisk# find /lib -name "*.ko" -print > exclude.txt</b>
<b>root@terre:/mnt/memdisk# wc -l exclude.txt</b>
10677 exclude.txt
<b>root@terre:/mnt/memdisk#</b>
</code>
<h5>Dar</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# dar -c backup -R /lib -[ include.txt</b>
--------------------------------------------
<e>4122 inode(s) saved</e>
including 0 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
<e>10677 inode(s) ignored (excluded by filters)</e>
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 14799
--------------------------------------------
EA saved for 0 inode(s)
FSA saved for 3945 inode(s)
--------------------------------------------
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
file inclusion is available, let's see file exclusion:
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# dar -c backup -R /lib -] exclude.txt</b>
--------------------------------------------
<e>4122 inode(s) saved</e>
including 0 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
<e>10677 inode(s) ignored (excluded by filters)</e>
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 14799
--------------------------------------------
EA saved for 0 inode(s)
FSA saved for 3945 inode(s)
--------------------------------------------
<b>root@terre:/mnt/memdisk#</b>
</code>
<h5>Rsync</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# rsync -aHAXS --files-from=include.txt / DST</b>
<b>root@terre:/mnt/memdisk# find DST -print | wc -l</b>
4124
<b>root@terre:/mnt/memdisk# find DST -name "*.ko" -print</b>
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
file inclusion is available. However if we can exclude a list of pattern
defined in a file, we cannot exclude a list of files. We should prepend each
entry by "- " seen the filtering syntax of rsync:
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# sed -r 's/^/- /' exclude.txt > rsync-exclude.txt</b>
<b>root@terre:/mnt/memdisk# rm -rf DST</b>
<b>root@terre:/mnt/memdisk# rsync -aHAXS --exclude-from=rsync-exclude.txt /lib DST</b>
<b>root@terre:/mnt/memdisk# find DST -print | wc -l</b>
4124
<b>root@terre:/mnt/memdisk# find DST -name "*.ko" -print | wc -l</b>
0
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
So we are good with this <i>sed</i> additional listing adaptation.
</p>
<h5>Tar</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# tar -cvf backup.tar --files-from=include.txt | wc -l</b>
tar: Removing leading `/' from member names
98017
<b>root@terre:/mnt/memdisk# tar -tf backup.tar | grep .ko | wc -l</b>
73392
<b>root@terre:/mnt/memdisk# grep .ko include.txt | wc -l</b>
3
<b>root@terre:/mnt/memdisk# grep .ko include.txt</b>
/lib/modules/4.19.0-12-amd64/kernel/sound/pci/korg1212
/lib/modules/4.19.0-11-amd64/kernel/sound/pci/korg1212
/lib/modules/4.19.0-10-amd64/kernel/sound/pci/korg1212
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
the include.txt file does not contain any file with the ko extension, however <i>tar</i>
saved all of them. Reading back the man page concerning this --files-from option
<i>The names read are handled the same way as command line arguments</i> explains that
in the listing where all <code>"*.ko"</code> files have been removed, remain their parent
directory, which implies saving all its content. In consequence we must not list
directories only their content (which will restrict us saving empty directories as such).
Let's modify the include.txt file that way:
</p>
<code class=block>
find /lib -type d -o -name "*.ko" -o -print > tar-include.txt
<b>root@terre:/mnt/memdisk# tar -cvf backup.tar --files-from=tar-include.txt | wc -l</b>
tar: Removing leading `/' from member names
1532
<b>root@terre:/mnt/memdisk# tar -tvf backup.tar | grep "*.ko"</b>
<b>root@terre:/mnt/memdisk# wc -l tar-include.txt</b>
1532 tar-include.txt
<b>root@terre:/mnt/memdisk# wc -l include.txt</b>
4123 include.txt
</code>
<p>
the difference between the 1532 entries saved by <i>tar</i> and the
4123 saved by <i>rsync</i> or <i>dar</i> comes from the many empty directories
that cannot be saved as such by <i>tar</i> using this method.
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# tar -cvf backup.tar --exclude-from=exclude.txt /lib | wc -l</b>
tar: Removing leading `/' from member names
4123
<b>root@terre:/mnt/memdisk# wc -l exclude.txt</b>
10677 exclude.txt
<b>root@terre:/mnt/memdisk# tar -tf backup.tar | egrep "\.ko$"</b>
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
The file listing exclusion works as expected
</p>
<h4>Slicing</h4>
<p>
For this test we will backup the content of /usr/bin of the running system.
We select a slice size smaller than the biggest file under backup. The use case for
slicing implies compression (remote storage, cloud storage, limited removable
media storage...).
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# ls -lh --sort=size /usr/bin | tac | tail</b>
-rwxr-xr-x 1 root root 8.0M Dec 18 2018 luajittex
-rwxr-xr-x 1 root root 8.1M Dec 18 2018 luatex53
-rwxr-xr-x 1 root root 8.1M Dec 18 2018 luatex
-rwxr-xr-x 1 root root 8.2M May 27 2019 wireshark
-rwxr-xr-x 1 root root 12M Dec 21 2018 kstars
-rwxr-xr-x 1 root root 15M Mar 12 2018 doxygen
-rwxr-xr-x 1 root root 16M Jan 4 2019 stellarium
-rwxr-xr-x 1 root root 19M Oct 12 19:46 mysql_embedded
-rwxr-xr-x 1 root root <e>39M</e> Sep 5 2019 emacs-gtk
total 430M
<b>root@terre:/mnt/memdisk#</b>
</code>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup -R /usr/bin -z6 <e>-s 20M</e> -q</b>
<b>terre:/mnt/memdisk# ls -lh backup.*</b>
-rw-r--r-- 1 root root <e>20M</e> Nov 13 11:30 backup.1.dar
-rw-r--r-- 1 root root 20M Nov 13 11:30 backup.2.dar
-rw-r--r-- 1 root root 20M Nov 13 11:30 backup.3.dar
-rw-r--r-- 1 root root 20M Nov 13 11:30 backup.4.dar
-rw-r--r-- 1 root root 20M Nov 13 11:30 backup.5.dar
-rw-r--r-- 1 root root 20M Nov 13 11:30 backup.6.dar
-rw-r--r-- 1 root root 20M Nov 13 11:30 backup.7.dar
-rw-r--r-- 1 root root <e>7.7M</e> Nov 13 11:30 backup.8.dar
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# dar -x backup -R DST -g emacs-gtk <e>-E "echo openning slice %p/%b.%N.%e"</e></b>
<e>openning slice /mnt/memdisk/backup.8.dar</e>
<e>openning slice /mnt/memdisk/backup.4.dar</e>
<e>openning slice /mnt/memdisk/backup.5.dar</e>
Restoration of FSA for /mnt/memdisk/DST/emacs-gtk aborted: Failed reading existing extX family FSA: Inappropriate ioctl for device
Restoration of linux immutable FSA for /mnt/memdisk/DST/emacs-gtk aborted: Failed reading existing extX family FSA: Inappropriate ioctl for device
--------------------------------------------
1 inode(s) restored
including 0 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
2591 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 2592
--------------------------------------------
EA restored for 0 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# diff DST/emacs-gtk /usr/bin/emacs-gtk</b>
memdiskerre:/mnt/memdisk# echo $?
0
<b>terre:/mnt/memdisk#</b>
</code>
<p>
We can also specify a different size for the first slice when using <i>dar</i>, this was used in the past
to fulfill a disk partially filled by a previous incremental backup when saving onto CD-RW
and DVD-RW, but that may still make sense when using USB keys or any other removable media.
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# dar -c backup -R /usr/bin <e class=blue>-s 20M</e> <e>-S 1M</e> -q --min-digit 3</b>
<b>root@terre:/mnt/memdisk# ls -lh</b>
total 361M
-rw-r--r-- 1 root root <e>1.0M</e> Nov 6 18:57 backup.001.dar
-rw-r--r-- 1 root root <e class=blue>20M</e> Nov 6 18:57 backup.002.dar
-rw-r--r-- 1 root root <e class=blue>20M</e> Nov 6 18:57 backup.003.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.004.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.005.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.006.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.007.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.008.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.009.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.010.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.011.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.012.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.013.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.014.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.015.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.016.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.017.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.018.dar
-rw-r--r-- 1 root root 20M Nov 6 18:57 backup.019.dar
<b>root@terre:/mnt/memdisk# dar -c backup -R /usr/bin -s 20M <e>-S 200M</e> -q --min-digit 3</b>
<b>root@terre:/mnt/memdisk# ls -lh</b>
total 361M
-rw-r--r-- 1 root root <e>200M</e> Nov 6 18:58 backup.001.dar
-rw-r--r-- 1 root root 20M Nov 6 18:59 backup.002.dar
-rw-r--r-- 1 root root 20M Nov 6 18:59 backup.003.dar
-rw-r--r-- 1 root root 20M Nov 6 18:59 backup.004.dar
-rw-r--r-- 1 root root 20M Nov 6 18:59 backup.005.dar
-rw-r--r-- 1 root root 20M Nov 6 18:59 backup.006.dar
-rw-r--r-- 1 root root 20M Nov 6 18:59 backup.007.dar
-rw-r--r-- 1 root root 20M Nov 6 18:59 backup.008.dar
-rw-r--r-- 1 root root 20M Nov 6 18:59 backup.009.dar
-rw-r--r-- 1 root root 913K Nov 6 18:59 backup.010.dar
<b>root@terre:/mnt/memdisk#</b>
</code>
<h5>Rsync</h5>
<p>
<i>rsync</i> cannot split any file in slices, and it does not generate any backup, but it copies files.
You cannot thus split data into slices to fit a particular restricted storage space.
</p>
<h5>Tar</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# tar -czf backup.tar -M -L 20480 /usr/bin</b>
<e class=red>tar: Cannot use multi-volume compressed archives</e>
Try 'tar --help' or 'tar --usage' for more information.
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
As reported by <i>tar</i> above, if a multi-volume support exists, it is quite restrictive as
one cannot use compression at the same time.
</p>
<code class=block>
<b>terre:/mnt/memdisk# tar -cf backup -M -L 20480 /usr/bin</b>
tar: Removing leading `/' from member names
<e class=red>Prepare volume #2 for 'backup' and hit return:</e>
tar: Removing leading `/' from hard link targets
<e class=red>Prepare volume #3 for 'backup' and hit return:</e>
<e class=red>Prepare volume #4 for 'backup' and hit return:</e>
<e class=red>Prepare volume #5 for 'backup' and hit return:</e>
<e class=red>Prepare volume #6 for 'backup' and hit return:</e>
<e class=red>Prepare volume #7 for 'backup' and hit return:</e>
<e class=red>Prepare volume #8 for 'backup' and hit return:</e>
<e class=red>Prepare volume #9 for 'backup' and hit return:</e>
<e class=red>Prepare volume #10 for 'backup' and hit return:</e>
<e class=red>Prepare volume #11 for 'backup' and hit return:</e>
<e class=red>Prepare volume #12 for 'backup' and hit return:</e>
<e class=red>Prepare volume #13 for 'backup' and hit return:</e>
<e class=red>Prepare volume #14 for 'backup' and hit return:</e>
<e class=red>Prepare volume #15 for 'backup' and hit return:</e>
<e class=red>Prepare volume #16 for 'backup' and hit return:</e>
<e class=red>Prepare volume #17 for 'backup' and hit return:</e>
<e class=red>Prepare volume #18 for 'backup' and hit return:</e>
<e class=red>Prepare volume #19 for 'backup' and hit return:</e>
<e class=red>Prepare volume #20 for 'backup' and hit return:</e>
<e class=red>Prepare volume #21 for 'backup' and hit return:</e>
<b>terre:/mnt/memdisk#</b>
<b>terre:/mnt/memdisk# ls -l backup*</b>
-rw-r--r-- 1 root root 19527680 Nov 13 11:40 backup
<b>terre:/mnt/memdisk#</b>
</code>
<p>
But even without compression, <i>tar</i> is still restrictive: it does not produce
different files, you have each new volume around and <code>hit return</code> at each time.
<br/>
Note also that without compression, the space required passes
from 8 volumes with <i>dar</i> to 21 volumes with <i>tar</i>.
</p>
<p>
The multi-volume support for <i>tar</i> seems well defined for
local tape removable devices, but will cost more than twice more
tape than what you can do with <i>dar</i> even if tape media
is your only target. Here is an example with <i>dar</i> on how
to write to mutli-volume and compressed backup to tape and pause
between each volume as <i>tar</i> does:
</p>
<code class=block>
<b>terre:/mnt/memdisk# <e>dar</e> -c backup -R /usr/bin -z6 -s 20M <e class=green>-E "echo writing volume %N to tape"</e> <e>-E "cat < %p/%b.%N.%e > /dev/mt"</e> <e class=blue>-p</e></b>
class=green>writing volume 1 to tape
Finished writing to file 1, ready to continue ? [return = YES | Esc = NO]
Continuing...
writing volume 2 to tape
Finished writing to file 2, ready to continue ? [return = YES | Esc = NO]
Continuing...
writing volume 3 to tape
Finished writing to file 3, ready to continue ? [return = YES | Esc = NO]
Continuing...
writing volume 4 to tape
Finished writing to file 4, ready to continue ? [return = YES | Esc = NO]
Continuing...
writing volume 5 to tape
Finished writing to file 5, ready to continue ? [return = YES | Esc = NO]
Continuing...
writing volume 6 to tape
Finished writing to file 6, ready to continue ? [return = YES | Esc = NO]
Continuing...
writing volume 7 to tape
Finished writing to file 7, ready to continue ? [return = YES | Esc = NO]
Continuing...
writing volume 8 to tape
--------------------------------------------
2592 inode(s) saved
including 5 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
0 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 2592
--------------------------------------------
EA saved for 3 inode(s)
FSA saved for 2152 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk#</b>
</code>
<h4>Symmetric encryption</h4>
<p>
Encryption has for target relatively long term lifetime, having compression at the same
time to increase security as it increases data "randomness" of the data to cipher. So we will use both in our tests (gzip with a compresion level of 6).
</p>
<p>
A point to pay attention to concerns the way the password/passphrase can be provided. Putting this
to the command-line could let other users on this same system read it. Having interactive
prompt is better as well as having the password set in a read access restricted file, which
in addition allows automation.
</p>
<h5>Dar</h5>
<code class=block>
<b>root@terre:/mnt/memdisk# dar -c backup -R / -g usr/bin -K aes256: -q -z6</b>
Archive backup <e>requires a password:</e>
Please <e>confirm your password:</e>
<b>root@terre:/mnt/memdisk# dar -l backup -q</b>
Archive backup <e>requires a password:</e>
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
Archive version format : 11
Compression algorithm used : <e>gzip</e>
Compression block size used : 0
Symmetric key encryption used : <e>AES 256</e>
Asymmetric key encryption used : none
Archive is signed : no
Sequential reading marks : present
User comment : N/A
KDF iteration count : <e>10000</e>
KDF hash algorithm : <e>argon2</e>
<e>Salt</e> size : 32 bytes
Catalogue size in archive : 101907 bytes
Archive is composed of 1 file(s)
File size: 155070897 bytes
The global data compression ratio is: 64%
CATALOGUE CONTENTS :
total number of inode : 2589
fully saved : 2589
binay delta patch : 0
inode metadata only : 0
distribution of inode(s)
- directories : 2
- plain files : 2152
- symbolic links : 435
- named pipes : 0
- unix sockets : 0
- character devices : 0
- block devices : 0
- Door entries : 0
hard links information
- number of inode with hard link : 5
- number of reference to hard linked inodes: 10
destroyed entries information
0 file(s) have been record as destroyed since backup of reference
<b>root@terre:/mnt/memdisk# touch pass.dcf</b>
<b>root@terre:/mnt/memdisk# chmod go-rwx pass.dcf</b>
<b>root@terre:/mnt/memdisk# cat >> pass.dcf</b>
-K "aes256:hello world!"
<b>root@terre:/mnt/memdisk# ls -l pass.dcf</b>
-rw------- 1 root root 25 Nov 9 11:37 pass.dcf
<b>root@terre:/mnt/memdisk# rm backup.1.dar</b>
rm: remove regular file 'backup.1.dar'? y
<b>root@terre:/mnt/memdisk# dar -c backup -R / -g usr/bin -B pass.dcf -q -z6</b>
<b>root@terre:/mnt/memdisk# dar -l backup -q -B pass.dcf</b>
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
Archive version format : 11
Compression algorithm used : gzip
Compression block size used : 0
Symmetric key encryption used : AES 256
Asymmetric key encryption used : none
Archive is signed : no
Sequential reading marks : present
User comment : N/A
KDF iteration count : 10000
KDF hash algorithm : argon2
Salt size : 32 bytes
Catalogue size in archive : 102310 bytes
Archive is composed of 1 file(s)
File size: 155132433 bytes
The global data compression ratio is: 64%
CATALOGUE CONTENTS :
total number of inode : 2589
fully saved : 2589
binay delta patch : 0
inode metadata only : 0
distribution of inode(s)
- directories : 2
- plain files : 2152
- symbolic links : 435
- named pipes : 0
- unix sockets : 0
- character devices : 0
- block devices : 0
- Door entries : 0
hard links information
- number of inode with hard link : 5
- number of reference to hard linked inodes: 10
destroyed entries information
0 file(s) have been record as destroyed since backup of reference
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
We can provide password either on command-line (not recommended), prompted by dar once launched
or from a protected configuration file. In the following we add slicing to encryption to see
whether or not <i>dar</i> deciphers the whole backup to recover a single file:
</p>
<code class=block>
<b>root@terre:/mnt/localdisk# rm -rf backup.*</b>
<b>root@terre:/mnt/localdisk# dar -c backup -R / -g usr/bin -K aes256: -s 1M -q -z6</b>
Archive backup requires a password:
Please confirm your password:
<b>root@terre:/mnt/localdisk# ls -l backup.* | wc -l</b>
<e>148</e>
<b>root@terre:/mnt/localdisk# dar -x backup -g usr/bin/emacs-gtk -E "echo openning slice %b.%N.%e" -q</b>
openning slice backup.148.dar
Archive backup requires a password:
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
<e>openning slice backup.1.dar</e>
<e>openning slice backup.80.dar</e>
<e>openning slice backup.81.dar</e>
<e>openning slice backup.82.dar</e>
<e>openning slice backup.83.dar</e>
<e>openning slice backup.84.dar</e>
<b>root@terre:/mnt/localdisk#</b>
</code>
<p>
As seen above, dar does not need to uncipher nor uncompress the whole backup to recover a single file, the use
of slicing let us see which slice it accessed to, but the behavior is the same without
slicing and can be measure by the execution time (see the performance tests logs).
</p>
<h5>Rsync</h5>
<p>
<i>rsync</i> cannot cipher data, it can rely on ssh to cipher the data over the network
but data is finally always stored in clear text.
</p>
<h5>Tar</h5>
<p>
There is no native support for ciphering with <i>tar</i>. You can however pipe <i>tar</i>'s output
to openssl to cipher the generated backup on fly as a whole.
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# tar -czf - /usr/bin | openssl enc -e -aes256 -out backup.tar.gz.crypted</b>
tar: Removing leading `/' from member names
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:
<e>*** WARNING : deprecated key derivation used.</e>
<e>Using -iter or -pbkdf2 would be better.</e>
tar: Removing leading `/' from hard link targets
<b>root@terre:/mnt/memdisk# openssl enc -d -aes256 -in backup.tar.gz.crypted | tar -xz</b>
enter aes-256-cbc decryption password:
<e>*** WARNING : deprecated key derivation used.</e>
<e>Using -iter or -pbkdf2 would be better.</e>
<b>root@terre:/mnt/memdisk# tar -czf - /usr/bin | openssl enc -e -aes256 -out backup.tar.gz.crypted -pass file:pass.txt</b>
tar: Removing leading `/' from member names
<e>*** WARNING : deprecated key derivation used.</e>
<e>Using -iter or -pbkdf2 would be better.</e>
tar: Removing leading `/' from hard link targets
<b>root@terre:/mnt/memdisk# openssl enc -d -aes256 -in backup.tar.gz.crypted -pass file:pass.txt | tar -xz</b>
<e>*** WARNING : deprecated key derivation used.</e>
<e>Using -iter or -pbkdf2 would be better.</e>
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
with openssl, <i>tar</i> has both the ability to provide the password/passphrase from an interactive prompt and from a protected file.
However you will have to remember which algorithm you used in adition to the passphrase. The ciphering being done
as a whole, you will have to decipher the whole backup even to just restore a single file.
If the backup is large, this may take a long time and may require to download a lot of stuff from a remote storage.
</p>
<p>
We see that ciphering with <i>tar</i> is possible at the cost of some complex command-line. But this is
error-prone as we see the shown warning that the key derivation function is deprecated and we should switch to
another one. Moreover you will have to remember which key derivation function and its parameters in addition to the
passphrase you provided and in addition to the ciphering algorithm used.
</p>
<p>
<u>Note:</u> you can also use <i>openssl</i> with <i>dar</i> as we did for <i>tar</i> but it brings all the drawbacks we saw with <i>tar</i>
</p>
<h4>Asymmetric encryption</h4>
<p>
The objective is to create a backup ciphered using GnuPG public/private key pair, restore the whole backup and
restore a single file from it. We will also use compression (gzip level 6) as it may make sense for the
corresponding use cases (data exchange over Internet for example).
</p>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup -K gnupg::root@terre.systeme-solaire.espace -R SRC -z6 -q</b>
<b>terre:/mnt/memdisk# dar -l backup -q</b>
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
Archive version format : 11
Compression algorithm used : <e>gzip</e>
Compression block size used : 0
Symmetric key encryption used : <e>AES 256</e>
Asymmetric key encryption used : <e>gnupg</e>
Archive is signed : no
Sequential reading marks : present
User comment : N/A
Catalogue size in archive : 68669 bytes
Archive is composed of 1 file(s)
File size: 158261425 bytes
The global data compression ratio is: 64%
CATALOGUE CONTENTS :
total number of inode : 2593
fully saved : 2593
binay delta patch : 0
inode metadata only : 0
distribution of inode(s)
- directories : 1
- plain files : 2157
- symbolic links : 435
- named pipes : 0
- unix sockets : 0
- character devices : 0
- block devices : 0
- Door entries : 0
hard links information
- number of inode with hard link : 0
- number of reference to hard linked inodes: 0
destroyed entries information
0 file(s) have been record as destroyed since backup of reference
<b>terre:/mnt/memdisk# ls -l backup.1.dar</b>
-rw-r--r-- 1 root root 158261425 Nov 9 16:04 backup.1.dar
<b>terre:/mnt/memdisk#</b>
</code>
<p>
As displayed in the backup header output above the underlying encryption is a symmetric encryption
(AES 256 by default), but the AES key is stored ciphered using the private key of the backup recipient
which email address is provided (or email adresses, if more than one
recipient is expected). This key is randomly chosen by dar and stored ciphered in the archive header.
Thus the overall behavior, performance and security of GnuPG withing dar is equivalent
to the one of the symmetrical algorithm chosen, with the ability to quickly restore some or all files
from an archive, and not waiting/downloading first the whole backup to unciphered it.
</p>
<p>
Seen above no password or passphrase is asked as the recipient email is ourselves
(root@terre.systeme-solaire.espace). Let's cipher for another recipient:
</p>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup -K <e class=blue>gnupg::dar.linux@free.fr</e> -R SRC -z6 -q -w</b>
<b>terre:/mnt/memdisk# ls -l backup.1.dar</b>
-rw-r--r-- 1 root root <e>158230913</e> Nov 9 16:22 backup.1.dar
<b>terre:/mnt/memdisk# dar -l backup -q</b>
FATAL error, aborting operation: Unexpected error reported by GPGME: <e>No secret key</e>
<b>terre:/mnt/memdisk# dar -c backup -K <e class=blue>gnupg::dar.linux@free.fr,root@terre.systeme-solaire.espace</e> -R SRC -z6 -q -w</b>
<b>terre:/mnt/memdisk# dar -l backup -q</b>
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
Archive version format : 11
Compression algorithm used : gzip
Compression block size used : 0
Symmetric key encryption used : AES 256
Asymmetric key encryption used : gnupg
Archive is signed : no
Sequential reading marks : present
User comment : N/A
Catalogue size in archive : 68624 bytes
Archive is composed of 1 file(s)
File size: 158252223 bytes
The global data compression ratio is: 64%
CATALOGUE CONTENTS :
total number of inode : 2593
fully saved : 2593
binay delta patch : 0
inode metadata only : 0
distribution of inode(s)
- directories : 1
- plain files : 2157
- symbolic links : 435
- named pipes : 0
- unix sockets : 0
- character devices : 0
- block devices : 0
- Door entries : 0
hard links information
- number of inode with hard link : 0
- number of reference to hard linked inodes: 0
destroyed entries information
0 file(s) have been record as destroyed since backup of reference
<b>terre:/mnt/memdisk#</b>
</code>
<p>
Here we saw that ciphering for a recipient different than ourself does not allow us to read the resulting backup,
however we can define several recipients and if we add ourself, we can read the backup as well as our primary
recipients.
</p>
<h5>Rsync</h5>
<i>rsync</i> is not able to perform asymmetric encryption of backed up files.
<h5>Tar</h5>
<p>
<i>Tar</i> cannot hold asymmetrical encryption alone, as for symmetrical encryption we must use an external tool
that performes the ciphering operation outside the backup.
</p>
<code class=block>
<b>terre:/mnt/memdisk# tar -czf - SRC | gpg --encrypt --recipient <e class=blue>root@terre.systeme-solaire.espace</e> --output backup.tar.gz.gpg</b>
<b>terre:/mnt/memdisk# ls -l backup.tar.gz.gpg</b>
-rw-r--r-- 1 root root <e>155337814</e> Nov 9 16:45 backup.tar.gz.gpg
<b>terre:/mnt/memdisk#</b>
<b>terre:/mnt/memdisk# gpg --decrypt backup.tar.gz.gpg | tar -xzf -</b>
gpg: encrypted with 3072-bit RSA key, ID 97E13D38B007DF30, created 2020-08-08
"root@terre <root@terre.systeme-solaire.espace>"
<b>terre:/mnt/memdisk#</b>
<b>terre:/mnt/memdisk# tar -czf - SRC | gpg --encrypt --recipient <e class=blue>dar.linux@free.fr</e> --output backup.tar.gz.gpg</b>
<b>terre:/mnt/memdisk# gpg --decrypt backup.tar.gz.gpg | tar -xzf -</b>
gpg: encrypted with 4096-bit RSA key, ID DB0A2141A4D96ECA, created 2012-09-13
"Denis Corbin (http://dar.linux.free.fr/) <dar.linux@free.fr>"
gpg: decryption failed: <e>No secret key</e>
gzip: stdin: unexpected end of file
tar: Child returned status 1
tar: Error is not recoverable: exiting now
<b>terre:/mnt/memdisk#terre:/mnt/memdisk# tar -czf - SRC | gpg --encrypt --recipient <e class=blue>dar.linux@free.fr</e> \</b>
--recipient <e class=blue>root@terre.systeme-solaire.espace</e> --output backup.tar.gz.gpg
<b>terre:/mnt/memdisk# gpg --decrypt backup.tar.gz.gpg | tar -xzf -</b>
gpg: encrypted with 4096-bit RSA key, ID DB0A2141A4D96ECA, created 2012-09-13
"Denis Corbin (http://dar.linux.free.fr/) <dar.linux@free.fr>"
gpg: encrypted with 3072-bit RSA key, ID 97E13D38B007DF30, created 2020-08-08
"root@terre <root@terre.systeme-solaire.espace>"
<b>terre:/mnt/memdisk#</b>
</code>
<p>
Same as for symmetric encryption, the fact that the whole backup is ciphered at once implies to download
back the whole backup even to recover just one file.
</p>
<h4>Protection against plain-text attack</h4>
<h5>Dar</h5>
<code class=block>
<b>devuan:/mnt/memdisk# time dar -c backup -K "aes256:hello world!" -at -1 0 -R SRC -q -w</b>
9.782u 3.413s <e>0:06.28</e> 210.0% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# la backup.1.dar</b>
-rw-r--r-- 1 root root 1572<e>706497</e> Nov 9 14:50 backup.1.dar
<b>devuan:/mnt/memdisk# time dar -c backup -K "aes256:hello world!" -at -1 0 -R SRC -q -w</b>
9.173u 2.845s <e>0:05.50</e> 218.3% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# la backup.1.dar</b>
-rw-r--r-- 1 root root 1572<e>655217</e> Nov 9 14:50 backup.1.dar
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
When ciphering the same data several times (with symmetric or asymmetric encryption),
the resulting backup size changes each time. This is due to the garbage (the elastic
buffer) dar adds at the beginnning and at the end of the data to cipher. This way,
even if a dar backup has well known structure it is not easy to know precisely where
they are positionned in the backup file, which makes plain-text attack much more difficult
to succeed if even possible in a reasonable time.
</p>
<h5>Rsync</h5>
<p>
<i>rsync</i> does not provide any way to cipher the backup, it is thus not concerned by
protecting against plain-text attack.
</p>
<h5>Tar</h5>
<code class=block>
<b>devuan:/mnt/memdisk/SRC# time ../tar.backup ../backup.tar.crypted usr</b>
4.112u 2.343s 0:04.72 136.6% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/SRC# ls -l ../bac</b>
backup.1.dar backup.tar.crypted
<b>devuan:/mnt/memdisk/SRC# ls -l ../backup.tar.crypted</b>
-rw-r--r-- 1 root root <e>1603594272</e> Nov 9 14:56 ../backup.tar.crypted
<b>devuan:/mnt/memdisk/SRC# time ../tar.backup ../backup.tar.crypted usr</b>
3.952u 2.564s 0:04.79 135.9% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/SRC# ls -l ../backup.tar.crypted</b>
-rw-r--r-- 1 root root <e>1603594272</e> Nov 9 14:56 ../backup.tar.crypted
<b>devuan:/mnt/memdisk/SRC#</b>
</code>
<p>
<i>tar</i> by itself does not provide any ciphering mechanism, however you can
cipher the <i>tar</i> generated backups with external tool (for example <i>openssl</i>
for symmetric encryption or <i>gpg</i> for asymmetric encryption). However none
of these mechanism protect against plain-text attack: tar backup have somehow
predictable header contents.
</p>
<h4>Key Derivation Function</h4>
<h5>Dar</h5>
<p>
<i>dar</i> uses <code>argon2</code> by default, with 10,000 iterations. It can
also use pkcs5 v2 (pbkdf2) with md5, sha1 or sha512 algorithm. The user
is able to set the KDF function and iteration count, so we are able to measure
the execution time variation added by the iteration count (taking into account that the data to cipher also
changes depending on the amount of random garbage <i>dar</i> wraps it with):
</p>
<code class=block>
<b>terre:/mnt/memdisk# time dar -c backup -R SRC -K aes:hello --kdf-param <e>100k</e>:<e class=blue>sha1</e> -w -q</b>
4.904u 0.572s <e>0:05.49</e> 99.6% 0+0k 0+0io 0pf+0w
<b>terre:/mnt/memdisk# time dar -c backup -R SRC -K aes:hello --kdf-param <e>500k</e>:sha1 -w -q</b>
5.805u 0.272s <e>0:06.08</e> 99.8% 0+0k 0+0io 0pf+0w
<b>terre:/mnt/memdisk# time dar -c backup -R SRC -K aes:hello --kdf-param <e>1M</e>:sha1 -w -q</b>
6.852u 0.308s <e>0:07.18</e> 99.5% 0+0k 0+0io 0pf+0w
time dar -c backup -R SRC -K aes:hello --kdf-param 10k:argon2 -w -q
5.092u 0.870s 0:03.50 170.2% 0+0k 0+0io 0pf+0w
<b>terre:/mnt/memdisk# time dar -c backup -R SRC -K aes:hello --kdf-param <e>10k</e>:<e class=blue>argon2</e> -w -q</b>
5.232u 0.760s <e>0:03.54</e> 169.2% 0+0k 0+0io 0pf+0w
<b>terre:/mnt/memdisk# time dar -c backup -R SRC -K aes:hello --kdf-param <e>20k</e>:argon2 -w -q</b>
5.778u 0.822s <e>0:04.14</e> 159.1% 0+0k 0+0io 0pf+0w
<b>terre:/mnt/memdisk# time dar -c backup -R SRC -K aes:hello --kdf-param <e>100k</e>:argon2 -w -q</b>
10.613u 0.831s <e>0:09.00</e> 127.1% 0+0k 0+0io 0pf+0w
<b>terre:/mnt/memdisk# time dar -c backup -R SRC -K aes:hello --kdf-param <e>1M:</e>argon2 -w -q</b>
66.862u 0.666s <e>1:05.14</e> 103.6% 0+0k 0+0io 0pf+0w
<b>terre:/mnt/memdisk#</b>
</code>
<h5>Rsync</h5>
<p>
<i>rsync</i> does not provide any way to cipher the backup, it is not concerned by KDF.
</p>
<h5>Tar</h5>
<p>
As of today (year 2020) <i>openssl</i> only supports PBKDF2: no support for argon2 is available.
<a href="https://en.wikipedia.org/wiki/Argon2">Argon2</a> was the winner of the Password Hashing
Competition in July 2015. <a href="https://en.wikipedia.org/wiki/PBKDF2">PBKDF2</a> has been
published by the IETF in September 2000 with the
<a href="https://tools.ietf.org/html/rfc2898">RCF 2898</a>
</p>
<h4>File change detection</h4>
<p>
In order stress each backup software on that aspect, we will use an ugly
script <a href="#always_change">always_change</a> that loops forever permanently
invoking <code>touch</code> on a given file. For the test, we create a source
tree to backup, containing a file of 1 MiB on which we will
apply this script:
</p>
<code class=block>
<b>terre:/mnt/memdisk# mkdir SRC</b>
<b>terre:/mnt/memdisk# dd if=/dev/zero of=SRC/hello_world bs=10240 count=1024</b>
1024+0 records in
1024+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.0107294 s, 977 MB/s
<b>terre:/mnt/memdisk# ./always_change SRC/hello_world &</b>
[1] 7433
<b>terre:/mnt/memdisk# stat SRC/hello_world</b>
File: SRC/hello_world
Size: 10485760 Blocks: 20480 IO Block: 4096 regular file
Device: 1bh/27d Inode: 375588 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-11-10 16:34:13.806106695 +0100
<e>Modify: 2020-11-10 16:34:13.806106695 +0100</e>
Change: 2020-11-10 16:34:13.806106695 +0100
Birth: -
<b>terre:/mnt/memdisk# stat SRC/hello_world</b>
File: SRC/hello_world
Size: 10485760 Blocks: 20480 IO Block: 4096 regular file
Device: 1bh/27d Inode: 375588 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-11-10 16:34:14.838104981 +0100
<e>Modify: 2020-11-10 16:34:14.838104981 +0100</e>
Change: 2020-11-10 16:34:14.838104981 +0100
Birth: -
<b>terre:/mnt/memdisk# jobs</b>
[1] + Running ./always_change SRC/hello_world
<b>terre:/mnt/memdisk# ls -l SRC</b>
total 10240
-rw-r--r-- 1 root root 10485760 Nov 10 16:34 hello_world
<b>terre:/mnt/memdisk#</b>
</code>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup -R SRC -q</b>
<e>WARNING! File modified while reading it for backup, but no more retry allowed: /mnt/memdisk/SRC/hello_world</e>
<b>terre:/mnt/memdisk# dar -l backup</b>
[Data ][D][ EA ][FSA][Compr][S]| Permission | User | Group | Size | Date | filename
--------------------------------+------------+-------+-------+---------+-------------------------------+------------
[<e>DIRTY</e>][ ] [---][ 99%][X] -rw-r--r-- 0 0 10 Mio Tue Nov 10 16:34:55 2020 hello_world
<b>terre:/mnt/memdisk# dar -x backup -R DST</b>
<e>File /mnt/memdisk/DST/hello_world has changed during backup and is probably not saved in a valid state ("dirty file"),</e>
<e>do you want to consider it for restoration anyway? [return = YES | Esc = NO]</e>
Continuing...
--------------------------------------------
1 inode(s) restored
including 0 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
0 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 1
--------------------------------------------
EA restored for 0 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk#</b>
</code>
<p>
<ul>
<li>
<i>dar</i> detects properly the file change and issues a warning during the backup.
</li>
<li>
It even retries to save the file several times (3 times by default).
</li>
<li>
the resulting backup keeps trace of this context by flagging the file as <code>DIRTY</code>
</li>
<li>
When restoring the data, a warning shows (default behavior) and the user is requested for confirmation.
</li>
</ul>
</p>
<h5>Rsync</h5>
<code class=block>
<b>terre:/mnt/memdisk# rsync -arvHAXqz --delete SRC DST</b>
<b>terre:/mnt/memdisk#</b>
</code>
<p>
<i>rsync</i> does not shows anything nor behaves differently (no retry, no change notification).
</p>
<h5>Tar</h5>
<code class=block>
<b>terre:/mnt/memdisk# tar -cf backup.tar SRC</b>
<e>tar: SRC/hello_world: file changed as we read it</e>
<b>terre:/mnt/memdisk# tar -tvf backup.tar</b>
drwxr-xr-x root/root 0 2020-11-10 16:33 SRC/
-rw-r--r-- root/root 10485760 2020-11-10 16:41 SRC/hello_world
<b>terre:/mnt/memdisk# rm -rf DST</b>
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# cd DST</b>
<b>terre:/mnt/memdisk/DST# tar -xf ../backup.tar</b>
<b>terre:/mnt/memdisk/DST# ls -l SRC</b>
total 10240
-rw-r--r-- 1 root root 10485760 Nov 10 16:41 hello_world
<b>terre:/mnt/memdisk/DST#</b>
</code>
<p>
<ul>
<li><i>tar</i> detects properly the file change and issues a warning during the backup.
</li>
<li>
it does not tries to save the file
</li>
<li>
the resulting backup keeps no visible trace of this possible data corruption
</li>
<li>
When restoring the data, no warning is issued and the restoration proceed as if the file was saved properly
</li>
</ul>
<h4>Multi-level backup</h4>
<p>
For this test we make a full backup of a Linux source tree, then
rename the <i>Documentation</i> directory as <i>doc</i> and make a
differential backup of the whole. Renaming files is expected to do at worse
the same as removing some and adding new ones, whe should not see all data
saved again:
</p>
<h5>Dar</h5>
<code class=block>
<b>devuan:/mnt/memdisk# du -B1 -s SRC</b>
<e>1121144832</e> SRC
<b>devuan:/mnt/memdisk# dar -c full -R SRC -z6 -q</b>
<b>devuan:/mnt/memdisk# cd SRC/linux-5.9.2/</b>
<b>devuan:/mnt/memdisk/SRC/linux-5.9.2# mv Documentation/ doc</b>
<b>devuan:/mnt/memdisk/SRC/linux-5.9.2# cd ../..</b>
<b>devuan:/mnt/memdisk# dar -c diff -A full -R SRC -z6 -q</b>
<b>devuan:/mnt/memdisk# ls -l *.dar</b>
-rw-r--r-- 1 root root <e>17858927</e> Nov 1 18:18 diff.1.dar
-rw-r--r-- 1 root root <e>219047658</e> Nov 1 18:14 full.1.dar
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# dar -x full -R DST -q</b>
<b>devuan:/mnt/memdisk# dar -x diff -R DST -q -w</b>
<b>devuan:/mnt/memdisk# diff -r SRC DST && echo "same data" || echo "different data"</b>
same data
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
We can see that the restoration of the full and differential backup over it
lead to the exact same directory tree as the source saved files.
</p>
<h5>Rsync</h5>
<code class=block>
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# rsync -arHAXz --delete --info=stats SRC/* BACKUP</b>
<e>sent 214,380,105 bytes received 1,359,591 bytes 9,180,412.60 bytes/sec</e>
total size is 954,869,250 speedup is 4.43
<b>devuan:/mnt/memdisk# cd SRC/linux-5.9.2/</b>
<b>devuan:/mnt/memdisk/SRC/linux-5.9.2# mv Documentation/ doc</b>
<b>devuan:/mnt/memdisk/SRC/linux-5.9.2# cd ../..</b>
<b>devuan:/mnt/memdisk# rsync -arHAXz --delete --info=stats SRC/* BACKUP</b>
<e>sent 12,923,292 bytes received 680,190 bytes 3,886,709.14 bytes/sec</e>
total size is 954,869,250 speedup is 70.19
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# rsync -arHAXz --delete --info=stats BACKUP/* DST</b>
<e class=blue>sent 214,371,610 bytes received 1,359,603 bytes 9,180,051.62 bytes/sec</e>
total size is 954,869,250 speedup is 4.43
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
We see that after the modification the amount of data pushed to the backup by <i>rsync</i>
passes from 214 MiB to only 12 MiB we can consider this as a differential backup, thus this
part of the multi-level backup aspect is addressed, but we have lost the access to the first
backup: it has been overwritten by the new one, so we lose history but that's a different feature.
</p>
<h5>Tar</h5>
<code class=block>
<b>devuan:/mnt/memdisk# tar --listed-incremental=snapshot.file -czf full.tar.gz SRC</b>
<b>devuan:/mnt/memdisk# cd SRC/linux-5.9.2/</b>
<b>devuan:/mnt/memdisk/SRC/linux-5.9.2# mv Documentation/ doc</b>
<b>devuan:/mnt/memdisk/SRC/linux-5.9.2# cd ../..</b>
<b>devuan:/mnt/memdisk# tar --listed-incremental=snapshot.file -czf diff.tar.gz SRC</b>
<b>devuan:/mnt/memdisk# ls -l</b>
total 190488
drwxr-xr-x 3 root root 60 Oct 31 19:37 SRC
-rw-r--r-- 1 root root <e>9654445</e> Oct 31 19:49 diff.tar.gz
-rw-r--r-- 1 root root <e>184036391</e> Oct 31 19:49 full.tar.gz
-rw-r--r-- 1 root root <e>1361962</e> Oct 31 19:49 snapshot.file
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# cd DST</b>
<b>devuan:/mnt/memdisk/DST# tar --listed-incremental=/dev/null -xf ../full.tar.gz</b>
<b>devuan:/mnt/memdisk/DST# tar --listed-incremental=/dev/null -xf ../diff.tar.gz</b>
<b>devuan:/mnt/memdisk/DST# cd ..</b>
<b>devuan:/mnt/memdisk# diff -r SRC DST/SRC && echo "same data" || echo "different data"</b>
same data
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
Here too, we got the exact same directory as original and modified data
</p>
<h4>Binary Delta</h4>
<p>
To evaluate the ability the support for binary delta, we will make a first
backup of a Debian ISO image, of which we will modify one bit using the
<a href="#bitflip">bitflip</a> script, then
make a differential backup of it. We expect to see the differential backup not
resaving the whole file, and though the restoration of the full and differential
backup matching the modified file.
</p>
<h5>Dar</h5>
<code class=block>
<b>devuan:/mnt/memdisk# dar -c full -z6 -R SRC --delta sig -q</b>
<b>devuan:/mnt/memdisk# ./bitflip 100000 SRC/debian-10.6.0-amd64-DVD-2.iso</b>
<b>devuan:/mnt/memdisk# dar -c diff -A full -z6 -R SRC -q</b>
<b>devuan:/mnt/memdisk# ls -l *.dar</b>
-rw-r--r-- 1 root root <e>643</e> Nov 1 19:45 diff.1.dar
-rw-r--r-- 1 root root <e>4704429776</e> Nov 1 19:05 full.1.dar
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# dar -x full -R DST -q</b>
<b>devuan:/mnt/memdisk# dar -x diff -R DST -q</b>
<b>devuan:/mnt/memdisk# diff -s SRC/debian-10.6.0-amd64-DVD-2.iso DST/debian-10.6.0-amd64-DVD-2.iso</b>
Files SRC/debian-10.6.0-amd64-DVD-2.iso and DST/debian-10.6.0-amd64-DVD-2.iso are identical
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
For <i>dar</i> the backup we used:
</p>
<ul>
<li>4.3 GiB for the full backup (compression ratio of 0,21 %)</li>
<li>614 bytes for the differential backup (compression ratio of 99,99998%)</li>
</ul>
<h5>Rsync</h5>
<code class=block>
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# rsync -arHAX --info=stats SRC/* DST</b>
<e>sent 4,688,066,109 bytes received 35 bytes 284,125,220.85 bytes/sec</e>
total size is 4,686,921,728 speedup is 1.00
<b>devuan:/mnt/memdisk# ./bitflip 100000 SRC/debian-10.6.0-amd64-DVD-2.iso</b>
<b>devuan:/mnt/memdisk# rsync -arHAX --info=stats SRC/* DST</b>
<e>sent 4,688,066,109 bytes received 35 bytes 302,455,880.26 bytes/sec</e>
<e class=red>total size is 4,686,921,728 speedup is 1.00</e>
<b>devuan:/mnt/memdisk# rsync -arHAXt --info=stats <e class=blue>--no-whole-file</e> SRC/* DST</b>
<e>sent 342,469 bytes received 547,803 bytes 30,178.71 bytes/sec</e>
total size is 4,686,921,728 speedup is 5,264.60
<b>devuan:/mnt/memdisk# diff -s SRC/debian-10.6.0-amd64-DVD-2.iso DST/debian-10.6.0-amd64-DVD-2.iso</b>
Files SRC/debian-10.6.0-amd64-DVD-2.iso and DST/debian-10.6.0-amd64-DVD-2.iso are identical
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
We had to use <code>--no-whole-file</code> to see the binary delta in action with
<i>rsync</i>. This feature is not activated when copying on local disk as it
does not makes sense (for <i>rsync</i>) because the computation time needed for the
binary delta takes more time the the byte to byte copy and because <i>rsync</i> does
not store just the delta (no backup history) but modifies the existing backup.
Anyway, binary delta is supported (of course!) by <i>rsync</i>.
</p>
<h5>Tar</h5>
<code class=block>
<b>devuan:/mnt/memdisk# tar --listed-incremental=snapshot.file -czf full.tar.gz SRC</b>
<b>devuan:/mnt/memdisk# ./bitflip 100000 SRC/debian-10.6.0-amd64-DVD-2.iso</b>
<b>devuan:/mnt/memdisk# tar --listed-incremental=snapshot.file -czf diff.tar.gz SRC</b>
<b>devuan:/mnt/memdisk# ls -l</b>
total 9133304
drwxr-xr-x 2 root root 40 Oct 31 17:31 SRC
-rwxr--r-- 1 root root 460 Oct 31 16:34 bitflip
-rw-r--r-- 1 root root <e class=red>4676243904</e> Oct 31 17:28 diff.tar.gz
-rw-r--r-- 1 root root <e>4676244172</e> Oct 31 17:24 full.tar.gz
-rw-r--r-- 1 root root 107 Oct 31 17:28 snapshot.file
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# cd DST</b>
<b>devuan:/mnt/memdisk/DST# tar --listed-incremental=/dev/null -xf ../full.tar.gz</b>
<b>devuan:/mnt/memdisk/DST# tar --listed-incremental=/dev/null -xf ../diff.tar.gz</b>
<b>devuan:/mnt/memdisk/DST# diff -s ../SRC/debian-10.6.0-amd64-DVD-2.iso SRC/debian-10.6.0-amd64-DVD-2.iso</b>
Files ../SRC/debian-10.6.0-amd64-DVD-2.iso and SRC/debian-10.6.0-amd64-DVD-2.iso are identical
<b>devuan:/mnt/memdisk/DST#</b>
</code>
<p>
For <i>tar</i> the backup used:
</p>
<ul>
<li>4.3 GiB for full backup (compression ratio of 0,22 %)</li>
<li>4.3 GiB for the differential backup (compression ratio of 0,22 %)</li>
</ul>
<p>
Binary delta is not supported by <i>tar</i>
</p>
<h4>Detection suspicious modifications</h4>
<p>For this test we will use the <a href="#hide_change">hide_change</a> script that rely
on the <a href="#bitflip">bitflip</a> script
seen above and try to hide the modifications performed, as a virus, keylogger or rootkit would
tend to do. We will make a full backup before
the modification and a differential backup after, then observe the behavior.
<p>
Here follows the script in action, we see no change using <code>ls -l</code>
while <code>stat</code> shows the exact same information:
<ul>
<li>file size</li>
<li>block used</li>
<li>Inode number</li>
<li>permissions</li>
<li>user and group ownership</li>
<li>last access time</li>
<li>last modification time</li>
</ul>
The only change concerns the inode change time (ctime) that cannot be set manually
and signals that some inode properties (but no file content) has changed. This
condition occurs, when changing the file permission, ownership, extended
attributes and so on, but should not occur when only file's data has changed.
</p>
</p>
<code class=block>
<b>terre:/mnt/memdisk# mkdir SRC</b>
<b>terre:/mnt/memdisk# echo "Hello World!" > SRC/file.txt</b>
<b>terre:/mnt/memdisk# cat SRC/file.txt</b>
Hello World!
<b>terre:/mnt/memdisk# ls -l SRC/file.txt</b>
-rw-r--r-- 1 root root 13 Nov 12 13:13 SRC/file.txt
<b>terre:/mnt/memdisk# stat SRC/file.txt</b>
File: SRC/file.txt
Size: 13 Blocks: 8 IO Block: 4096 regular file
Device: 1bh/27d Inode: 424690 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-11-12 13:13:19.021978762 +0100
Modify: 2020-11-12 13:13:09.213998852 +0100
Change: 2020-11-12 13:13:<e>09.213998852</e> +0100
Birth: -
<b>terre:/mnt/memdisk# ./hide_change SRC/file.txt</b>
<b>terre:/mnt/memdisk# ls -l SRC/file.txt</b>
-rw-r--r-- 1 root root 13 Nov 12 13:13 SRC/file.txt
<b>terre:/mnt/memdisk# stat SRC/file.txt</b>
File: SRC/file.txt
Size: 13 Blocks: 8 IO Block: 4096 regular file
Device: 1bh/27d Inode: 424690 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-11-12 13:13:19.021978762 +0100
Modify: 2020-11-12 13:13:09.213998852 +0100
Change: 2020-11-12 13:13:<e>39.549936636</e> +0100
Birth: -
<b>terre:/mnt/memdisk# cat SRC/file.txt</b>
<e class=red>L</e>ello World!
<b>terre:/mnt/memdisk#</b>
</code>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# mkdir SRC</b>
<b>terre:/mnt/memdisk# echo "Hello World!" > SRC/file.txt</b>
<b>terre:/mnt/memdisk# dar -c full -R SRC -N</b>
--------------------------------------------
1 inode(s) saved
including 0 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
0 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 1
--------------------------------------------
EA saved for 0 inode(s)
FSA saved for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# ./hide_change SRC/file.txt</b>
<b>terre:/mnt/memdisk# dar -c diff -A full -R SRC -N -q</b>
<e>SECURITY WARNING! SUSPICIOUS FILE /mnt/memdisk/SRC/file.txt: ctime changed since archive of reference was done, while no other inode information changed</e>
<b>terre:/mnt/memdisk#</b>
</code>
<p>
<i>dar</i> issues a warning because of this suspicious condition. Note that we still have the sane file in the full backup, in case of doubt,
we can compare it with this modified version:
</p>
<code class=block>
<b>terre:/mnt/memdisk# dar -d full -R SRC -q</b>
DIFF /mnt/memdisk/SRC/file.txt: <e>different file data, offset of first difference is: 0</e>
Some file comparisons failed
<b>terre:/mnt/memdisk#</b>
</code>
<p>
The previous test reports that the first byte to have changed is at offset 0, thus this is not just a metadata change
that lead to this warning. We can if necessary restore the sane data from the full backup.
</p>
<h5>Rsync</h5>
<code class=block>
<b>terre:/mnt/memdisk# rm -rf SRC</b>
<b>terre:/mnt/memdisk# mkdir SRC</b>
<b>terre:/mnt/memdisk# echo "Hello World!" > SRC/file.txt</b>
<b>terre:/mnt/memdisk# rsync -arvHAX SRC DST</b>
sending incremental file list
created directory DST
SRC/
SRC/file.txt
sent 146 bytes received 65 bytes 422.00 bytes/sec
total size is 13 speedup is 0.06
<b>terre:/mnt/memdisk# ./hide_change SRC/file.txt</b>
<b>terre:/mnt/memdisk# rsync -arvHAX SRC DST</b>
sending incremental file list
sent 83 bytes received 13 bytes 192.00 bytes/sec
total size is 13 speedup is 0.14
<b>terre:/mnt/memdisk# cat SRC/file.txt</b>
<e>Lello World!</e>
<b>terre:/mnt/memdisk# cat DST/SRC/file.txt</b>
<e class=red>Hello World!</e>
<b>terre:/mnt/memdisk#</b>
</code>
<p>
rsync has not reported the problem, but hopefully it has not synchronized the backup,
thus we end in a sane version in the DST backup directory though, as user is not aware
of this potential risk, the virus/ransomware can spread silently.
</p>
<h5>Tar</h5>
<code class=block>
<b>terre:/mnt/memdisk# rm -rf SRC</b>
<b>terre:/mnt/memdisk# rm -rf DST</b>
<b>terre:/mnt/memdisk# mkdir SRC</b>
<b>terre:/mnt/memdisk# echo "Hello World!" > SRC/file.txt</b>
<b>terre:/mnt/memdisk# tar --listed-incremental=snapshot.file -cf full.tar SRC</b>
<b>terre:/mnt/memdisk# ./hide_change SRC/file.txt</b>
<b>terre:/mnt/memdisk# tar --listed-incremental=snapshot.file -cvf diff.tar SRC</b>
SRC/
SRC/file.txt
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# cd DST</b>
<b>terre:/mnt/memdisk/DST# tar -xf ../full.tar</b>
<b>terre:/mnt/memdisk/DST# cat SRC/file.txt</b>
<e>Hello World!</e>
<b>terre:/mnt/memdisk/DST# tar -xf ../diff.tar</b>
<b>terre:/mnt/memdisk/DST# cat SRC/file.txt</b>
<e class=red>Lello World!</e>
<b>terre:/mnt/memdisk/DST#</b>
</code>
<p>
As seen above <i>tar</i> does not see any problem, but the file has been resaved
as a whole (while its last modification time was unchanged) which lead to corrupt the
new backup with potential harmful data. The good point is that you have still the
full backup with the sane data. But at a next backup cycle, as you were not notified of the
risk, you will lose it and keep only the corrupted version of this file.
</p>
<h4>Snapshot</h4>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c full -z6 -R /usr <e>--on-fly-isolate snapshot</e></b>
--------------------------------------------
267245 inode(s) saved
including 23 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
0 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 267245
--------------------------------------------
EA saved for 5 inode(s)
FSA saved for 237962 inode(s)
--------------------------------------------
Now performing on-fly isolation...
<b>terre:/mnt/memdisk# ls -l *.dar</b>
-rw-r--r-- 1 root root 4006060941 Nov 12 15:34 full.1.dar
-rw-r--r-- 1 root root 6662595 Nov 12 15:34 <e class=blue>snapshot.1.dar</e>
<b>terre:/mnt/memdisk# dar <e>-C recreated_snapshot</e> -A full -z6 -q</b>
<b>terre:/mnt/memdisk# ls -al *.dar</b>
-rw-r--r-- 1 root root 4006060941 Nov 12 15:34 full.1.dar
-rw-r--r-- 1 root root 7907094 Nov 12 16:33 <e class=blue>recreated_snapshot.1.dar</e>
-rw-r--r-- 1 root root 6662595 Nov 12 15:34 snapshot.1.dar
<b>terre:/mnt/memdisk# dar -c diff -A snapshot -R /usr -z</b>
--------------------------------------------
23 inode(s) saved
including 23 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
<e>267222 inode(s) not saved (no inode/file change)</e>
0 inode(s) failed to be saved (filesystem error)
0 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 267245
--------------------------------------------
EA saved for 0 inode(s)
FSA saved for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk#</b>
<b>terre:/mnt/memdisk# ls -lh *.dar</b>
-rw-r--r-- 1 root root 25M Nov 12 16:37 diff.1.dar
-rw-r--r-- 1 root root 3.8G Nov 12 15:34 full.1.dar
-rw-r--r-- 1 root root 7.6M Nov 12 16:33 recreated_snapshot.1.dar
-rw-r--r-- 1 root root 6.4M Nov 12 15:34 snapshot.1.dar
<b>terre:/mnt/memdisk# dar -c diff2 -A recreated_snapshot -R /usr -z</b>
--------------------------------------------
23 inode(s) saved
including 23 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
<e>267222 inode(s) not saved (no inode/file change)</e>
0 inode(s) failed to be saved (filesystem error)
0 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 267245
--------------------------------------------
EA saved for 0 inode(s)
FSA saved for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# dar -c snapshot_alone <e>-A +</e> -R /usr -z</b>
--------------------------------------------
23 inode(s) saved
including 23 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
267222 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
0 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 267245
--------------------------------------------
EA saved for 0 inode(s)
FSA saved for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# <e>touch /usr/local/src</e></b>
<b>terre:/mnt/memdisk# dar -c faked_diff -A snapshot -R /usr <e class=blue>--dry-run</e> -q -vt</b>
<e>Adding folder to archive: /usr/local/src</e>
Saving Filesystem Specific Attributes for /usr/local/src
<b>terre:/mnt/memdisk# ls -l *.dar</b>
-rw-r--r-- 1 root root 25537139 Nov 12 16:37 diff.1.dar
-rw-r--r-- 1 root root 25537139 Nov 12 16:39 diff2.1.dar
-rw-r--r-- 1 root root 4006060941 Nov 12 15:34 full.1.dar
-rw-r--r-- 1 root root 7907094 Nov 12 16:33 recreated_snapshot.1.dar
-rw-r--r-- 1 root root 6662595 Nov 12 15:34 snapshot.1.dar
-rw-r--r-- 1 root root 25537142 Nov 12 16:44 <e class=blue>snapshot_alone.1.dar</e>
<b>terre:/mnt/memdisk#</b>
</code>
<p>As seen above,a snapshot can be created:
<ul>
<li>as part of a backup process (full, differential, incremental or even decremental backup) (<code>--on-fly-isolate</code>)</li>
<li>from a existing backup (<code>-C</code>)</li>
<li>alone by a dedicated operation (<code>-A +</code>)</li>
</ul>
</p>
<code class=block>
<b>root@terre:/mnt/memdisk# ls -l full.1.dar</b>
-rw-r--r-- 1 root root <e>3895581703</e> Nov 29 21:53 full.1.dar
<b>root@terre:/mnt/memdisk# dar -l full -q</b>
FATAL error, aborting operation: Cannot open catalogue: unknown compression
<b>root@terre:/mnt/memdisk# !bitflip</b>
bitflip 31124653000 full.1.dar
<b>root@terre:/mnt/memdisk# dar -l full -q</b>
Archive version format : 11
Compression algorithm used : gzip
Compression block size used : 0
Symmetric key encryption used : none
Asymmetric key encryption used : none
Archive is signed : no
Sequential reading marks : present
User comment : N/A
<e>Catalogue size in archive : 7799028 bytes</e>
Archive is composed of 1 file(s)
File size: 3895581703 bytes
The global data compression ratio is: 51%
CATALOGUE CONTENTS :
total number of inode : 263480
fully saved : 263480
binay delta patch : 0
inode metadata only : 0
distribution of inode(s)
- directories : 18080
- plain files : 216142
- symbolic links : 29258
- named pipes : 0
- unix sockets : 0
- character devices : 0
- block devices : 0
- Door entries : 0
hard links information
- number of inode with hard link : 11
- number of reference to hard linked inodes: 34
destroyed entries information
0 file(s) have been record as destroyed since backup of reference
<b>root@terre:/mnt/memdisk# <e>bitflip 31124653000 full.1.dar</e></b>
<b>root@terre:/mnt/memdisk# dar -t full</b>
Final memory cleanup...
<e class=red>FATAL error, aborting operation: Cannot open catalogue: unknown compression</e>
<b>root@terre:/mnt/memdisk# dar -t full <e>-A snapshot</e></b>
--------------------------------------------
263503 item(s) treated
0 item(s) with error
0 item(s) ignored (excluded by filters)
--------------------------------------------
Total number of items considered: 263503
--------------------------------------------
<b>root@terre:/mnt/memdisk#</b>
<b>root@terre:/mnt/memdisk# dar -t full <e>--sequential-read</e></b>
A problem occurred while reading this archive contents: <e>Cannot open catalogue: unknown compression</e>
--------------------------------------------
263503 item(s) treated
0 item(s) with error
0 item(s) ignored (excluded by filters)
--------------------------------------------
Total number of items considered: 263503
--------------------------------------------
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
Once created a snapshot can be used:
<ul>
<li>to create a differential or incremental backup</li>
<li>to list the files that would be saved (thus which have changed,
were added or have been removed) thus all changes since the time the snapshot was made (using the <code>--dry-run</code> option)</li>
<li>
rescue a corrupted backup when the corruption falled into the
backup table of content located at the end of the <i>dar</i>
backup (only if it has been created based on the backup to rescue
either using <code>-C option</code> maybe long after the backup was made
or using <code>--on-fly-isolate</code> at the same time the backup was created.
</li>
</ul>
Note, as shown above, a table of content (aka "catalogue") corruption, can also partially be recovered
using the <code>--sequential-read</code> mode, it will just not let <i>dar</i> remove files that
were removed since the reference backup was made (this does thus not concern full backups, as here).
</p>
<h5>Rsync</h5>
<p>
This feature is not supported by <i>rsync</i>.
</p>
<h5>Tar</h5>
<p>
<i>tar</i> can generate snapshot:
<ul>
<li>alone redirecting the backup output to /dev/null</li>
<li>as part of a backup process (in fact <i>tar</i> cannot do else)</li>
</ul>
</p>
<code class=block>
<b>terre:/mnt/memdisk# tar --listed-incremental=snapshot.file -czf full.tar.gz /usr</b>
tar: Removing leading `/' from member names
tar: Removing leading `/' from hard link targets
<b>terre:/mnt/memdisk# ls -l snapshot.file</b>
-rw-r--r-- 1 root root 6288644 Nov 12 15:12 snapshot.file
<b>terre:/mnt/memdisk# cp snapshot.file snapshot.file.ref</b>
tar --listed-incremental=snapshot.file -cvf /dev/null /usr
/usr/
/usr/bin/
/usr/games/
/usr/include/
/usr/include/X11/
/usr/include/X11/bitmaps/
/usr/include/arpa/
/usr/include/asm-generic/
/usr/include/attr/
/usr/include/c++/
/usr/include/c++/
<e>[...]</e>
/usr/share/zoneinfo/right/Canada/
/usr/share/zoneinfo/right/Chile/
/usr/share/zoneinfo/right/Etc/
/usr/share/zoneinfo/right/Europe/
/usr/share/zoneinfo/right/Indian/
/usr/share/zoneinfo/right/Mexico/
/usr/share/zoneinfo/right/Pacific/
/usr/share/zoneinfo/right/SystemV/
/usr/share/zoneinfo/right/US/
/usr/share/zsh/
/usr/share/zsh/site-functions/
/usr/share/zsh/vendor-completions/
/usr/src/
<b>terre:/mnt/memdisk# ls -l sna</b>
snapshot.file snapshot.file.ref
<b>terre:/mnt/memdisk# ls -l snapshot.file*</b>
-rw-r--r-- 1 root root 6288644 Nov 12 15:20 snapshot.file
-rw-r--r-- 1 root root 6288644 Nov 12 15:18 snapshot.file.ref
<b>terre:/mnt/memdisk#</b>
</code>
<p>
If a snapshot can be used (and is in fact required) to make a differential backup, it
cannot really be used to see the difference a current living filesystem has with a given
snapshot. Worse, doing so modifies the snapshot, so you have first to make a copy
to not screw up your backup process. Worse, if incremental backup fails and you have
not created a copy of the backup, your snapshot being modified you will mostly have to
remake the whole backup process from the full backup to be sure to not miss backing up
some modified files. Same thing if you lose by mistake the snapshot file.
</p>
<h4>On-fly hashing</h4>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup -R /usr -g usr/bin -z6 <e>--hash sha1</e></b>
--------------------------------------------
0 inode(s) saved
including 0 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
8 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 8
--------------------------------------------
EA saved for 0 inode(s)
FSA saved for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# ls -l *.dar*</b>
-rw-r--r-- 1 root root 171 Nov 12 17:22 backup.1.dar
-rw-r--r-- 1 root root 55 Nov 12 17:22 <e>backup.1.dar.sha1</e>
<b>terre:/mnt/memdisk# sha1sum -c backup.1.dar.sha1</b>
<e>backup.1.dar: OK</e>
<b>terre:/mnt/memdisk#</b>
</code>
<h5>Rsync</h5>
<p>
not supported by <i>rsync</i>
</p>
<h5>Tar</h5>
<p>
not supported by <i>tar</i>
</p>
<h4>Custom command during operation</h4>
<p>
As an example (but there is much more thing that can be done), we take the case
of a automounted directory. Such type of volume is mounted only when used, if not
used no mount point directory shows and unless you know it exists, no backup of
its content is performed. The idea, is when entering the parent directory at backup
process to trigger the mount point for the backup to include them.
<p>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# cat /etc/auto.mnt</b>
Espace -defaults,relatime,acl,bg,rsize=8192,wsize=8192 nfs.systeme-solaire.espace:/mnt/Externe/Espace
Commun -defaults,relatime,acl,bg,rsize=8192,wsize=8192,ro nfs.systeme-solaire.espace:/mnt/Externe/Commun
Backup -defaults,relatime,acl,bg,rsize=8192,wsize=8192,ro nfs.systeme-solaire.espace:/mnt/Backup
<b>terre:/mnt/memdisk# ls -l /mnt/Externe/</b>
total 4
drwxr-xr-x 7 root root 4096 Jul 14 17:58 Espace
<b>terre:/mnt/memdisk# dar -c backup -R / -g /mnt -q</b>
<b>terre:/mnt/memdisk# dar -l backup</b>
[Data ][D][ EA ][FSA][Compr][S]| Permission | User | Group | Size | Date | filename
--------------------------------+------------+-------+-------+---------+-------------------------------+------------
[Saved][-] [-L-][ ][ ] drwxr-xr-x 0 0 0 Wed Oct 21 18:17:07 2020 mnt
[Saved][-] [-L-][ ][ ] drwxr-xr-x 1000 1002 0 Mon Nov 9 11:56:54 2020 mnt/localdisk
[Saved][-] [---][-----][ ] lrwxrwxrwx 0 0 0 Thu Aug 15 23:29:46 2019 mnt/Backup
[Saved][-] [---][ ][ ] drwxr-xr-x 0 0 0 Thu Nov 12 17:42:11 2020 mnt/Externe
[Saved][-][Saved][---][ ][ ] drwxr-xr-x 0 0 0 Tue Jul 14 17:58:57 2020 <e class=blue>mnt/Externe/Espace</e>
<b>terre:/mnt/memdisk#</b>
<b>terre:/mnt/memdisk# rm backup.1.dar</b>
<b>terre:/mnt/memdisk# dar -c backup -R / -g mnt -q '-<' mnt '-=' 'file %p/Externe/Backup %p/Externe/Commun'</b>
/mnt/Externe/Backup: directory
/mnt/Externe/Commun: directory
<b>terre:/mnt/memdisk# dar -l backup</b>
[Data ][D][ EA ][FSA][Compr][S]| Permission | User | Group | Size | Date | filename
--------------------------------+------------+-------+-------+---------+-------------------------------+------------
[Saved][-] [-L-][ ][ ] drwxr-xr-x 0 0 0 Wed Oct 21 18:17:07 2020 mnt
[Saved][-] [-L-][ ][ ] drwxr-xr-x 1000 1002 0 Mon Nov 9 11:56:54 2020 mnt/localdisk
[Saved][-] [---][-----][ ] lrwxrwxrwx 0 0 0 Thu Aug 15 23:29:46 2019 mnt/Backup
[Saved][-] [---][ ][ ] drwxr-xr-x 0 0 0 Thu Nov 12 18:01:41 2020 mnt/Externe
[Saved][-][Saved][---][ ][ ] drwxr-x--- 993 1002 0 Wed Nov 11 10:21:55 2015 <e>mnt/Externe/Commun</e>
[Saved][-][Saved][---][ ][ ] drwxr-xr-x 0 0 0 Sun Sep 13 12:22:24 2020 <e>mnt/Externe/Backup</e>
[Saved][-][Saved][---][ ][ ] drwxr-xr-x 0 0 0 Tue Jul 14 17:58:57 2020 <e class=blue>mnt/Externe/Espace</e>
<b>terre:/mnt/memdisk# ls -l /mnt/Externe/</b>
total 12
drwxr-xr-x 9 root root 4096 Sep 13 12:22 Backup
drwxr-x--- 4 commun maison 4096 Nov 11 2015 Commun
drwxr-xr-x 7 root root 4096 Jul 14 17:58 Espace
<b>terre:/mnt/memdisk#</b>
</code>
<p>
In the previous example we see that the /mnt/Externe directory is a mount point containing three auto-mounted
volumes: <code>Espace</code>, <code>Commun</code> and <code>Backup</code>. At first only <code>Espace</code>
was mounted. Performing a backup without care will skip the two other directories.
</p>
<p>
In a second time, thanks to the <code>-<</code> and <code>-=</code> options, we instructed <i>dar</i> to
run the <code>file</code> command on the two missing directories when entering <code>/mnt</code>.
As a result, we now see both of them in the backup. We could do that before executing the backup, but as
the backup may include many other
directories the time between such operation done before starting the backup and the time the backup finally
saves the automount point at <code>/mnt/Externe</code> may exceed the automount timeout leading them to be
unmounted and disappear before the backup process reaches them.
</p>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup -R / -g usr/bin --hash sha512 -s 100M -q</b>
<b>terre:/mnt/memdisk# ls -l backup.*</b>
-rw-r--r-- 1 root root 104857600 Nov 12 18:30 backup.1.dar
-rw-r--r-- 1 root root 143 Nov 12 18:30 backup.1.dar.sha512
-rw-r--r-- 1 root root 104857600 Nov 12 18:30 backup.2.dar
-rw-r--r-- 1 root root 143 Nov 12 18:30 backup.2.dar.sha512
-rw-r--r-- 1 root root 104857600 Nov 12 18:30 backup.3.dar
-rw-r--r-- 1 root root 143 Nov 12 18:30 backup.3.dar.sha512
-rw-r--r-- 1 root root 63577207 Nov 12 18:30 backup.4.dar
-rw-r--r-- 1 root root 143 Nov 12 18:30 backup.4.dar.sha512
<b>terre:/mnt/memdisk# dar -t backup <e>-E 'sha512sum -c %p/%b.%N.%e.sha512'</e></b>
backup.4.dar: OK
backup.1.dar: OK
backup.2.dar: OK
backup.3.dar: OK
backup.4.dar: OK
--------------------------------------------
2594 item(s) treated
0 item(s) with error
0 item(s) ignored (excluded by filters)
--------------------------------------------
Total number of items considered: 2594
--------------------------------------------
<b>terre:/mnt/memdisk#</b>
</code>
<p>
In this example, this we used slicing with on-fly hashing which generated for each slice
the corresponding sha512 hash file. Then we tested the archive content and at the same time the hash
files thanks to the <code>-E</code> option. Of course any user command or shell or python script,
can be used instead, and for backup, restoration, testing, snashotting,...
</p>
<h5>Rsync</h5>
<p>
not supported by <i>rsync</i>
</p>
<h5>Tar</h5>
<p>
<i>tar</i> has the <code>-F option</code> to launch a command after each tape,
but it is only available with multi-volume tar archive, which in turn
cannot be used with compression. Thus we won't test it, as it is quite
restrictive and does not match any common use cases.
</p>
<h4>Dry-run execution</h4>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk/A# ls -l</b>
<e>total 0</e>
<b>terre:/mnt/memdisk/A# dar -c backup -R / -g usr/bin --dry-run</b>
--------------------------------------------
2594 inode(s) saved
including 5 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
34 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 2628
--------------------------------------------
EA saved for 3 inode(s)
FSA saved for 2154 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk/A# ls -l</b>
<e>total 0</e>
<b>terre:/mnt/memdisk/A#</b>
</code>
<h5>Rsync</h5>
<code class=block>
<b>terre:/mnt/memdisk# rsync -arHAX --dry-run /usr/bin DST</b>
<b>terre:/mnt/memdisk# ls -l DST</b>
<e>ls: cannot access 'DST': No such file or directory</e>
<b>terre:/mnt/memdisk#</b>
</code>
<h5>Tar</h5>
<p>
does not seem supported by <i>tar</i>
</p>
<h4>User message within backup</h4>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup <e>--user-comment "passphrase is the usual one. Archive was made on %d on host %h"</e> -R / -g usr/bin -K camellia: -zxz -s 100M</b>
Archive backup requires a password:
Please confirm your password:
--------------------------------------------
2594 inode(s) saved
including 5 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
34 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 2628
--------------------------------------------
EA saved for 3 inode(s)
FSA saved for 2154 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# dar -l backup <e>-aheader</e></b>
Archive version format : 11
Compression algorithm used : xz
Compression block size used : 0
Symmetric key encryption used : camellia 256
Asymmetric key encryption used : none
Archive is signed : no
Sequential reading marks : present
User comment : <e>passphrase is the usual one. Archive was made on Thu Nov 12 18:57:35 2020 on host terre</e>
KDF iteration count : 10000
KDF hash algorithm : argon2
Salt size : 32 bytes
Final memory cleanup...
FATAL error, aborting operation: header only mode asked
<b>terre:/mnt/memdisk#</b>
</code>
<p>
The use of the <code>-aheader</code> let one see the archive header that is always in clear-text. The usual listing
operation provides some additional informations from the ciphered table of content and thus in that context requires the passphrase:
</p>
<code class=block>
<b>terre:/mnt/memdisk# dar <e>-l</e> backup <e>-q</e></b>
<e>Archive backup requires a password:</e>
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
Archive version format : 11
Compression algorithm used : xz
Compression block size used : 0
Symmetric key encryption used : camellia 256
Asymmetric key encryption used : none
Archive is signed : no
Sequential reading marks : present
User comment : <e>passphrase is the usual one. Archive was made on Thu Nov 12 18:57:35 2020 on host terre</e>
KDF iteration count : 10000
KDF hash algorithm : argon2
Salt size : 32 bytes
Catalogue size in archive : 78268 bytes
Archive is composed of 2 file(s)
File size : 104857600 bytes
Last file size : 17168696 bytes
Archive total size is : 122026296 bytes
<e>The global data compression ratio is: 72%</e>
<e>CATALOGUE CONTENTS :</e>
total number of inode : 2589
fully saved : 2589
binay delta patch : 0
inode metadata only : 0
distribution of inode(s)
- directories : 2
- plain files : 2152
- symbolic links : 435
- named pipes : 0
- unix sockets : 0
- character devices : 0
- block devices : 0
- Door entries : 0
hard links information
- number of inode with hard link : 5
- number of reference to hard linked inodes: 10
destroyed entries information
0 file(s) have been record as destroyed since backup of reference
<b>terre:/mnt/memdisk#</b>
</code>
<h5>Rsync</h5>
<p>
not supported by <i>rsync</i>
</p>
<h5>Tar</h5>
<p>
not supported by <i>tar</i>
</p>
<h4>backup sanity test</h4>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup -R / -g usr/bin -zlz4</b>
--------------------------------------------
2594 inode(s) saved
including 5 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
34 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 2628
--------------------------------------------
EA saved for 3 inode(s)
FSA saved for 2154 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# dar -t backup</b>
--------------------------------------------
2594 item(s) treated
0 item(s) with error
0 item(s) ignored (excluded by filters)
--------------------------------------------
Total number of items considered: 2594
--------------------------------------------
<b>terre:/mnt/memdisk#</b>
</code>
<h5>Rsync</h5>
<p>
It does not seems possible to let <i>rsync</i> check that the target or destination
directory is sane and usuable. All operation modify the destination file or save
modified files in either the destination directory (the backup) or an alternate directory
(<code>--compare-dest</code> option).
</p>
<h5>Tar</h5>
<code class=block>
<b>terre:/mnt/memdisk# rm -rf backup.tar.gz</b>
<b>terre:/mnt/memdisk# tar -czf backup.tar.gz /usr/bin</b>
tar: Removing leading `/' from member names
tar: Removing leading `/' from hard link targets
<b>terre:/mnt/memdisk# tar -tzf backup.tar.gz</b>
usr/bin/
usr/bin/bitmap
usr/bin/dot
usr/bin/indi_usbdewpoint
usr/bin/ruby2.5
usr/bin/pod2man
usr/bin/iptables-xml
usr/bin/knotify4
usr/bin/fakeroot
usr/bin/xclock
<e>[...]</e>
/bin/traceproto
usr/bin/ofm2opl
usr/bin/akonadi_archivemail_agent
usr/bin/resizecons
usr/bin/rletopnm
usr/bin/dh_install
usr/bin/updvitomp
usr/bin/h2xs
usr/bin/xmessage
<b>terre:/mnt/memdisk# echo $?</b>
0
<b>terre:/mnt/memdisk#</b>
</code>
<h4>Comparing with original data</h4>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup -R SRC -q</b>
<b>terre:/mnt/memdisk# dar -d backup -R SRC</b>
--------------------------------------------
2594 item(s) treated
0 item(s) do not match those on filesystem
0 item(s) ignored (excluded by filters)
--------------------------------------------
Total number of items considered: 2594
--------------------------------------------
<b>terre:/mnt/memdisk# echo $?</b>
0
<b>terre:/mnt/memdisk#</b>
</code>
<h5>Rsync</h5>
<p>
Does not seems supported by <i>rsync</i>
</p>
<h5>Tar</h5>
<code class=block>
<b>terre:/mnt/memdisk/SRC# tar -czf ../backup.tar.gz .</b>
<b>terre:/mnt/memdisk/SRC# tar -dzf ../backup.tar.gz</b>
<b>terre:/mnt/memdisk/SRC# echo $?</b>
0
<b>terre:/mnt/memdisk/SRC#</b>
</code>
<h4>Tunable verbosity</h4>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup -R / -g usr/bin <e>-q</e></b>
<b>terre:/mnt/memdisk# rm backup.1.dar</b>
<b>terre:/mnt/memdisk# dar -c backup -R / -g usr/bin</b>
--------------------------------------------
2594 inode(s) saved
including 5 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
34 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 2628
--------------------------------------------
EA saved for 3 inode(s)
FSA saved for 2154 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# dar -c backup -R / -g usr/bin <e>-vm</e></b>
Arguments read from /usr/local/etc/darrc :
Creating low layer: Writing archive into a plain file object...
Adding a new layer on top: Caching layer for better performances...
Writing down the archive header...
Adding a new layer on top: Escape layer to allow sequential reading...
All layers have been created successfully
Building the catalog object...
Processing files for backup...
Writing down archive contents...
Closing the escape layer...
Writing down the first archive terminator...
Writing down archive trailer...
Writing down the second archive terminator...
Closing archive low layer...
Archive is closed.
--------------------------------------------
2594 inode(s) saved
including 5 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
34 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 2628
--------------------------------------------
EA saved for 3 inode(s)
FSA saved for 2154 inode(s)
--------------------------------------------
Making room in memory (releasing memory used by archive of reference)...
Final memory cleanup...
<b>terre:/mnt/memdisk# rm -f backup*</b>
<b>terre:/mnt/memdisk# dar -c backup -R / -g usr/bin <e>-vt</e> -q</b>
Adding folder to archive: /usr
Saving Filesystem Specific Attributes for /usr
Adding folder to archive: /usr/bin
Saving Filesystem Specific Attributes for /usr/bin
Adding file to archive: /usr/bin/bitmap
Saving Filesystem Specific Attributes for /usr/bin/bitmap
<e>[...]</e>
Saving Filesystem Specific Attributes for /usr/bin/dh_install
Adding symlink to archive: /usr/bin/updvitomp
Adding file to archive: /usr/bin/h2xs
Saving Filesystem Specific Attributes for /usr/bin/h2xs
Adding file to archive: /usr/bin/xmessage
Saving Filesystem Specific Attributes for /usr/bin/xmessage
<b>terre:/mnt/memdisk# rm -f backup*</b>
<b>terre:/mnt/memdisk# dar -c backup -R / -g usr/bin -vd</b>
Inspecting directory /root
Inspecting directory /bin
Inspecting directory /sbin
Inspecting directory /tmp
Inspecting directory /sys
Inspecting directory /lib
<e>[...]</e>
Inspecting directory /var
Inspecting directory /proc
Inspecting directory /dev
Inspecting directory /etc
Inspecting directory /media
Inspecting directory /run
<b>terre:/mnt/memdisk#</b>
<b>terre:/mnt/memdisk# rm -f backup.*</b>
<b>terre:/mnt/memdisk# dar -c backup -R / -g usr/bin <e>-vf</e> -q</b>
Finished Inspecting directory /usr/bin , saved 408 Mio, compression ratio 13%
Finished Inspecting directory /usr , saved 408 Mio, compression ratio 13%
<b>terre:/mnt/memdisk#</b>
<b>terre:/mnt/memdisk# dar -c backup -R / -g usr/bin <e>-vmasks</e> -q</b>
directory tree filter:
AND
| OR
| | Is subdir of: /usr/bin [case sensitive]
| +--
+--
filename filter:
AND
| TRUE
+--
EA filter:
AND
| TRUE
+--
Compression filter:
TRUE
<b>terre:/mnt/memdisk#</b>
</code>
<p>
<i>dar</i> has several options to define which type of message to show or not to show:
<code> -v, -vs, -vt, -vd, -vf, -vm, -vmasks, -q</code>. They can be combined.
</p>
<h5>Rsync</h5>
<code class=block>
<b>terre:/mnt/memdisk# rsync -arHAX /usr/bin DST</b>
<b>terre:/mnt/memdisk# rm -rf DST</b>
<b>terre:/mnt/memdisk# rsync -arHAX <e>-v</e> /usr/bin DST</b>
sending incremental file list
created directory DST
bin/
bin/2to3-2.7
bin/411toppm
bin/7z
bin/7za
bin/7zr
bin/FvwmCommand
<e>[...]</e>
bin/zstdmt -> zstd
bin/perl => bin/perl5.28.1
bin/perlbug => bin/perlthanks
bin/python3.7 => bin/python3.7m
bin/pkg-config => bin/x86_64-pc-linux-gnu-pkg-config
bin/unzip => bin/zipinfo
sent 437,298,617 bytes received 42,381 bytes 174,936,399.20 bytes/sec
total size is 445,394,557 speedup is 1.02
<b>root@terre:/mnt/memdisk# rsync -arHAX <e>--info=progress2</e> /usr/bin DST</b>
437,083,500 98% 128.42MB/s 0:00:03 (xfr#2152, to-chk=0/2593)
<b>root@terre:/mnt/memdisk#</b>
</code>
<p>
<code>-v option</code> leads to a more verbose output, while <code>-q</code>
remove the non error messages. Using both at the same time seems not to
be different than using <code>-q</code> alone. However <i>rsync</i> has a very rich
set of additional options like <code>--info</code>, <code>--debug</code>
that can be added on top.
</p>
<h5>Tar</h5>
<code class=block>
<b>terre:/mnt/memdisk# tar -czf backup.tar.gz /usr/bin</b>
tar: Removing leading `/' from member names
tar: Removing leading `/' from hard link targets
<b>terre:/mnt/memdisk# rm backup.tar.gz</b>
<b>terre:/mnt/memdisk# tar <e>-v</e> -czf backup.tar.gz /usr/bin</b>
tar: Removing leading `/' from member names
/usr/bin/
/usr/bin/bitmap
/usr/bin/dot
/usr/bin/indi_usbdewpoint
/usr/bin/ruby2.5
/usr/bin/pod2man
/usr/bin/iptables-xml
/usr/bin/knotify4
<e>[...]</e>
/usr/bin/traceproto
/usr/bin/ofm2opl
/usr/bin/akonadi_archivemail_agent
/usr/bin/resizecons
/usr/bin/rletopnm
/usr/bin/dh_install
/usr/bin/updvitomp
/usr/bin/h2xs
/usr/bin/xmessage
<b>terre:/mnt/memdisk#</b>
</code>
<p>
<i>tar</i> only provides the <code>-v</code> option to increase
verbosity.
</p>
<h4>Modify Backup content</h4>
<p>
We will perform two types of tests:
<ul>
<li>remove one or several files from an existing backup without having to make a new backup process</li>
<li>add some forgotten files to an existing backup without performing a new full backup process</li>
</ul>
</p>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup -R / -g usr/bin -z6 -q</b>
<b>terre:/mnt/memdisk# dar -l backup -g usr/bin/emacs-gtk</b>
[Data ][D][ EA ][FSA][Compr][S]| Permission | User | Group | Size | Date | filename
--------------------------------+------------+-------+-------+---------+-------------------------------+------------
[Saved][-] [-L-][ 64%][ ] drwxr-xr-x root root 408 Mio Sun Jun 2 23:25:09 2019 usr
[Saved][-] [-L-][ 64%][ ] drwxr-xr-x root root 408 Mio Sun Nov 8 13:43:58 2020 usr/bin
[Saved][ ] [-L-][ 90%][X] -rwxr-xr-x root root 38 Mio Thu Sep 5 04:35:24 2019 <e>usr/bin/emacs-gtk</e>
<b>terre:/mnt/memdisk# dar -A backup <e>-+ without-emacs</e> <e class=blue>-ak</e> <e>-P usr/bin/emacs-gtk</e> -vs -q</b>
Skipping file: <ROOT>/usr/bin/emacs-gtk
<b>terre:/mnt/memdisk# dar -l without-emacs -g usr/bin/emacs-gtk</b>
[Data ][D][ EA ][FSA][Compr][S]| Permission | User | Group | Size | Date | filename
--------------------------------+------------+-------+-------+---------+-------------------------------+------------
[Saved][-] [-L-][ 62%][ ] drwxr-xr-x root root 370 Mio Sun Jun 2 23:25:09 2019 usr
[Saved][-] [-L-][ 62%][ ] drwxr-xr-x root root 370 Mio Sun Nov 8 13:43:58 2020 usr/bin
<b>terre:/mnt/memdisk#rm backup.*</b>
<b>terre:/mnt/memdisk#mv without-emacs.1.dar backup.1.dar</b>
<b>terre:/mnt/memdisk#</b>
</code>
<p>
<i>dar</i> does not modify a existing backup but creates a copy of it with the requested files or
directory removed. The process can be quick even with compression thanks to the <code>-ak</code>
option that avoid uncompressing and recompressing
file that are kept. Before removing the old backup you can test the sanity of the new generated one.
</p>
<code class=block>
<b>terre:/mnt/memdisk# dar -c emacs -R / -g usr/bin/emacs-gtk -z6 -q</b>
<b>terre:/mnt/memdisk# dar -l emacs</b>
[Data ][D][ EA ][FSA][Compr][S]| Permission | User | Group | Size | Date | filename
--------------------------------+------------+-------+-------+---------+-------------------------------+------------
[Saved][-] [-L-][ 90%][ ] drwxr-xr-x root root 38 Mio Sun Jun 2 23:25:09 2019 usr
[Saved][-] [-L-][ 90%][ ] drwxr-xr-x root root 38 Mio Sun Nov 8 13:43:58 2020 usr/bin
[Saved][ ] [-L-][ 90%][X] -rwxr-xr-x root root 38 Mio Thu Sep 5 04:35:24 2019 usr/bin/emacs-gtk
<b>terre:/mnt/memdisk# <e>dar -A backup -@ emacs -+ with-emacs</e> <e class=blue>-ak</e></b>
--------------------------------------------
2594 inode(s) added to archive
with 10 hard link(s) recorded
0 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted
--------------------------------------------
EA saved for 3 inode(s)
FSA saved for 2159 inode(s)
--------------------------------------------
Total number of inode(s) considered: 2594
--------------------------------------------
<b>terre:/mnt/memdisk# dar -l with-emacs -g usr/bin/emacs-gtk</b>
[Data ][D][ EA ][FSA][Compr][S]| Permission | User | Group | Size | Date | filename
--------------------------------+------------+-------+-------+---------+-------------------------------+------------
[Saved][-] [-L-][ 64%][ ] drwxr-xr-x root root 408 Mio Sun Jun 2 23:25:09 2019 usr
[Saved][-] [-L-][ 64%][ ] drwxr-xr-x root root 408 Mio Sun Nov 8 13:43:58 2020 usr/bin
[Saved][ ] [-L-][ 90%][X] -rwxr-xr-x root root 38 Mio Thu Sep 5 04:35:24 2019 usr/bin/emacs-gtk
<b>terre:/mnt/memdisk# rm emacs.* backup.*</b>
<b>terre:/mnt/memdisk# mv with-emacs.1.dar backup.1.dar</b>
<b>terre:/mnt/memdisk#</b>
</code>
<p>
Here to add files to a existing backup we must make a small backup of these files only, then merge
this backup with the backup we want to modify. Nothing of the source data is touched in this operation,
is something goes wrong or if you made an error, you can fix and restart without taking the risk
to lose data.
</p>
<h5>Rsync</h5>
<p>
The backup made by <i>rsync</i> is just a copy of the save files, removing a file from the backup
is as simple as calling <code>rm</code> on that file in the repository that is considered the backup.
</p>
<p>
While adding a new file in the backup can be done by using <i>rsync</i> as usual including the directory
tree where this file resides.
</p>
<h5>Tar</h5>
<code class=block>
<b>terre:/mnt/memdisk# tar -czf backup.tar.gz /usr/bin</b>
tar: Removing leading `/' from member names
tar: Removing leading `/' from hard link targets
<b>terre:/mnt/memdisk# tar -tvf backup.tar.gz | grep emacs-gtk</b>
-rwxr-xr-x root/root 39926024 2019-09-05 04:35 usr/bin/emacs-gtk
<b>terre:/mnt/memdisk# tar -tvf backup.tar.gz | grep emacs-gtk</b>
-rwxr-xr-x root/root 39926024 2019-09-05 04:35 usr/bin/emacs-gtk
<b>terre:/mnt/memdisk# tar --delete usr/bin/emacs-gtk -f backup.tar.gz</b>
<e class=red>tar: Cannot update compressed archives</e>
tar: Error is not recoverable: exiting now
<b>terre:/mnt/memdisk#</b>
</code>
<p>
Well, <i>tar</i> cannot manipulate compressed archives. What the point then to remove a
file from a backup if storage space is not an issue, else, would compression be used?
</p>
<h4>stdin/stdout backup read/write</h4>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c - -z6 -R SRC > backup.file</b>
--------------------------------------------
2594 inode(s) saved
including 5 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
0 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 2594
--------------------------------------------
EA saved for 3 inode(s)
FSA saved for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# rm -rf DST</b>
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# dar -x - --sequential-read -R DST < backup.file</b>
--------------------------------------------
2594 inode(s) restored
including 5 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
0 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 2594
--------------------------------------------
EA restored for 3 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk#</b>
</code>
<p>
<i>dar</i> can read a backup from stdin and write a backup to stdout.
</p>
<h5>Rsync</h5>
<p>
Using stdin/stdout to send to or read from backed up data does not seems possible with <i>rsync</i>
</p>
<h5>Tar</h5>
<code class=block>
<b>terre:/mnt/memdisk# tar -czf - SRC > backup.file</b>
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# cd DST</b>
<b>terre:/mnt/memdisk/DST# tar -xzf - < ../backup.file</b>
<b>terre:/mnt/memdisk/DST#</b>
</code>
<p>
<i>tar</i> can read a backup from stdin and write a backup to stdout.
</p>
<h4>Remote network storage</h4>
<p>
For Remote Network storage, if you use a personal NAS you may avoid generating
ciphered backup, though you still should transfer
it using a secured protocol if the underlaying network is not your own from end to end
(for example a part of the path goes over Internet without IPSec or equivalent).
</p>
<p>
Why ciphering backup if using secure transfer protocol?
<ul>
<li>
Secure transfer avoids one to
read your data in transit in particular your credentials to the remote site, but at the
end the transferred data is stored in clear at the other end.
</li>
<li>
ciphered data avoids the owner of the remote storage to access to your data
without your consent, though it does not protect one to intercept your transfer and
read the credentials you used to connected to the remote storage. This one could
then connect later and delete all your backup... which is surely not what you want.
</li>
</ul>
</p>
<p>
In the following we will use both: <b>secure protocol</b> and <b>ciphered backup</b>, without using
local storage. We will also need <b>compression</b> to save precious space (usually you pay for the
cloud storage you use) and <b>maybe slicing</b> depending on the constraints
imposed by the remote storage (some provider ask you to pay an extra amount to store larger files,
having slicing avoids you paying extra cost in such context). Another use case of slicing is when
the file transfer protocol is not able to continue an interrupted transfer,
you will then only need to restart it for the last slice, not the whole backup.
</p>
<code class=block>
<b>terre:/mnt/memdisk# sftp denis@dar</b>
The authenticity of host 'dar (192.168.6.32)' can't be established.
RSA key fingerprint is SHA256:KN3o/psWC512grcZ5/J5dTSg9PzIXbZAHiig/hqfkc8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'dar,192.168.6.32' (RSA) to the list of known hosts.
denis@dar's password:
Connected to denis@dar.
sftp> bye
<b>terre:/mnt/memdisk#</b>
</code>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c sftp://denis@dar/home/denis/backup -R / -g etc -K aes: -zlz4 -s 1M</b>
<e class=blue>Please provide the password for login denis at host dar:</e>
<e>Archive backup requires a password:</e>
<e>Please confirm your password:</e>
--------------------------------------------
2360 inode(s) saved
including 0 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
27 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 2387
--------------------------------------------
EA saved for 0 inode(s)
FSA saved for 1523 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# sftp denis@dar</b>
denis@dar's password:
Connected to denis@dar.
sftp> ls -l
-rw-r--r-- 1 denis denis 1048576 Nov 26 17:15 backup.1.dar
-rw-r--r-- 1 denis denis 1048576 Nov 26 17:15 backup.2.dar
-rw-r--r-- 1 denis denis 1048576 Nov 26 17:15 backup.3.dar
-rw-r--r-- 1 denis denis 474982 Nov 26 17:15 backup.4.dar
sftp> bye
<b>terre:/mnt/memdisk#</b>
</code>
<p>
The backup results in four ciphered slices located on the remote sftp server. Let's add
a <code>-E option</code> to see which slice are being read while testing the archive.
</p>
<code class=block>
<b>terre:/mnt/memdisk# dar -t sftp://denis@dar/home/denis/backup <e class=blue>-E "echo 'openning slice %p/%b.%N.%e'"</e></b>
<e class=blue>Please provide the password for login denis at host dar:</e>
openning slice /home/denis/backup.4.dar
<e>Archive backup requires a password:</e>
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
openning slice /home/denis/backup.1.dar
openning slice /home/denis/backup.2.dar
openning slice /home/denis/backup.3.dar
openning slice /home/denis/backup.4.dar
--------------------------------------------
2360 item(s) treated
0 item(s) with error
0 item(s) ignored (excluded by filters)
--------------------------------------------
Total number of items considered: 2360
--------------------------------------------
<b>terre:/mnt/memdisk#</b>
</code>
<p>
We see that all slices have been read as expected, now let's restore /etc/fstab in the current directory
and compare the restored files with the real /etc/fstab
</p>
<code class=block>
<b>terre:/mnt/memdisk# dar -x sftp://denis@dar/home/denis/backup -E "echo 'openning slice %p/%b.%N.%e'" -g etc/fstab --flat</b>
Please provide the password for login denis at host dar:
<e>openning slice /home/denis/backup.4.dar</e>
Archive backup requires a password:
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
<e>1 inode(s) restored</e>
including 0 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
269 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 270
--------------------------------------------
EA restored for 0 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# <e>diff fstab /etc/fstab</e></b>
<b>terre:/mnt/memdisk# echo $?</b>
<e>0</e>
<b>terre:/mnt/memdisk#</b>
</code>
<p>
As seen above only one slice (slice #4) has been necessary to restore /etc/fstab. But let's save two files,
a huge one and a small one into a single sliced backup and measure the transfer time of backup
and restoration of this ciphered an compressed backup through sftp. We have added public key authentification
for precise time measurement:
</p>
<code class=block>
<b>terre:/mnt/memdisk# sftp denis@dar</b>
Connected to denis@dar.
sftp> bye
<b>terre:/mnt/memdisk# ls -l SRC</b>
total 315396
-rw------- 1 root root 322961408 Nov 26 17:28 devuan_beowulf_3.0.0_amd64-netinstall.iso
-rw-r--r-- 1 root root 994 Nov 26 17:29 fstab
<b>terre:/mnt/memdisk#</b>
<b>terre:/mnt/memdisk# time dar -c sftp://denis@dar/home/denis/backup -R SRC -z6 -K aes:hello -afile-auth -q</b>
20.769u 2.445s <e>0:22.77</e> 101.8% 0+0k 0+0io 0pf+0w
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# time dar -x sftp://denis@dar/home/denis/backup -R DST -K hello -afile-auth -q</b>
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
11.826u 4.211s <e>0:15.88</e> 100.9% 0+0k 0+0io 0pf+0w
<b>terre:/mnt/memdisk# diff -rs SRC DST</b>
<e>Files SRC/devuan_beowulf_3.0.0_amd64-netinstall.iso and DST/devuan_beowulf_3.0.0_amd64-netinstall.iso are identical</e>
<e>Files SRC/fstab and DST/fstab are identical</e>
<b>terre:/mnt/memdisk# <e class=blue>rm DST/fstab</e></b>
<b>terre:/mnt/memdisk# time dar -x sftp://denis@dar/home/denis/backup -R DST -K hello -afile-auth -q -g fstab</b>
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
0.680u 0.012s <e>0:00.87</e> 79.3% 0+0k 0+0io 0pf+0w
<b>terre:/mnt/memdisk#</b>
</code>
<p>
While restoring the whole backup needs 15 seconds of transfer time, restoring <code>fstab</code> alone requires only 0.87 second,
as there is only one slice, this shows that <i>dar</i> is reading only the necessary part of the archive even within a slice to
perform the operation.
</p>
<h5>Rsync</h5>
<code class=block>
<b>terre:/mnt/memdisk# rsync -arHAXSzq /etc denis@dar:/home/denis</b>
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# rsync -arHAXSzq denis@dar:/home/denis/etc/fstab .</b>
<b>terre:/mnt/memdisk# diff fstab /etc/fstab</b>
<b>terre:/mnt/memdisk# echo $?</b>
0
<b>terre:/mnt/memdisk#</b>
</code>
<p>
We can backup to a remote sftp server, we can compress the data on-fly but it is not stored compressed nor ciphered.
Restoration operation is possible per file or for the whole backup
</p>
<h5>Tar</h5>
<p>
tar has no way to perform sftp or other secured transfer protocol, nor encryption by itself. When time comes to
restore a particular file, the whole backup has to be retrieved, unciphered and uncompressed to restore even
just a sigle file</p>
<h3>Backup <a name="robustness">Robustness</a></h3>
<p>
The objective of this test is to measure the way the backup tools under test behave when the backup has been corrupted.
We will here just flip one byte of the backup, at the beginning, in the middle or at the end of the backup and
observe the consequences in term of ability to restore the backup.
</p>
<h5>Dar</h5>
<code class=block>
<b>terre:/mnt/memdisk# dar -c backup -R SRC -z6</b>
--------------------------------------------
74725 inode(s) saved
including 0 hard link(s) treated
0 inode(s) changed at the moment of the backup and could not be saved properly
0 byte(s) have been wasted in the archive to resave changing files
0 inode(s) with only metadata changed
0 inode(s) not saved (no inode/file change)
0 inode(s) failed to be saved (filesystem error)
0 inode(s) ignored (excluded by filters)
0 inode(s) recorded as deleted from reference backup
--------------------------------------------
Total number of inode(s) considered: 74725
--------------------------------------------
EA saved for 0 inode(s)
FSA saved for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# ls -al backup*</b>
-rw-r--r-- 1 root root 219088536 Nov 17 17:45 backup.1.dar
<b>terre:/mnt/memdisk# ./hide_change backup.1.dar 1</b>
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# dar -x backup -R DST</b>
<e>backup.1.dar is not a valid file (wrong magic number), please provide the good file. [return = YES | Esc = NO]</e>
Escaping...
Final memory cleanup...
Aborting program. User refused to continue while asking: backup.1.dar is not a valid file (wrong magic number), please provide the good file.
<b>terre:/mnt/memdisk# dar -x backup -R DST <e>-alax</e></b>
LAX MODE: In spite of its name, backup.1.dar does not appear to be a dar slice, assuming a data corruption took place and continuing
LAX MODE: Archive is flagged as having escape sequence (which is normal in recent archive versions). However if this is not expected, shall I assume a data corruption occurred in this field and that this flag should be ignored? (If unsure, refuse) [return = YES | Esc = NO]
Escaping...
--------------------------------------------
<e>74725 inode(s) restored</e>
including 0 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
0 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
<e>Total number of inode(s) considered: 74725</e>
--------------------------------------------
EA restored for 0 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk# diff -r SRC DST</b>
<b>terre:/mnt/memdisk# echo $?</b>
0
<b>terre:/mnt/memdisk#</b>
</code>
<p>
Modifying the first bit <i>dar</i> has seen the corruption. We can use the lax mode (<code>-alax</code> option) to bypass this
corruption and then the restoration proceeds normally. We can try a bit further for example somewhere in the middle of the archive,
thus at offset 876354144 (half of the size expressed in bit, not byte):
</p>
<code class=block>
<b>terre:/mnt/memdisk# ls -l backup*</b>
-rw-r--r-- 1 root root 219088536 Nov 17 17:45 backup.1.dar
<b>terre:/mnt/memdisk# hide_change backup.1.dar 876354144</b>
<b>terre:/mnt/memdisk# rm -rf DST</b>
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# dar -x backup -R DST</b>
<e>Error while restoring /mnt/memdisk/DST/linux-5.9.8/drivers/mtd/spi-nor/core.c : compressed data CRC error</e>
--------------------------------------------
74724 inode(s) restored
including 0 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
0 inode(s) ignored (excluded by filters)
<e class=red>1 inode(s) failed to restore (filesystem error)</e>
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 74725
--------------------------------------------
EA restored for 0 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
Final memory cleanup...
All files asked could not be restored
<b>terre:/mnt/memdisk# diff -rq SRC DST</b>
<e>Files SRC/linux-5.9.8/drivers/mtd/spi-nor/core.c and DST/linux-5.9.8/drivers/mtd/spi-nor/core.c differ</e>
<b>terre:/mnt/memdisk#</b>
</code>
<p>
One file could not be restored properly as reported by <i>dar</i>,
but all other files could be and are identical to their respective
originals. Let's modifying the last bit for completness:
</p>
<code class=block>
<b>terre:/mnt/memdisk# ls -al *.dar</b>
-rw-r--r-- 1 root root 219088537 Nov 17 17:45 backup.1.dar
<b>terre:/mnt/memdisk# cp backup.1.dar backop.1.dar</b>
<b>terre:/mnt/memdisk# hide_change backup.1.dar 1752708287</b>
<b>terre:/mnt/memdisk# ls -al *.dar</b>
-rw-r--r-- 1 root root 219088536 Nov 17 17:58 backop.1.dar
-rw-r--r-- 1 root root 219088536 Nov 17 17:58 backup.1.dar
<b>terre:/mnt/memdisk# diff backup.1.dar backop.1.dar</b>
Binary files backup.1.dar and backop.1.dar differ
<b>terre:/mnt/memdisk# rm -rf DST</b>
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# dar -x backup -R DST</b>
--------------------------------------------
74725 inode(s) restored
including 0 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
0 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 74725
--------------------------------------------
EA restored for 0 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
<b>terre:/mnt/memdisk#</b>
<b>terre:/mnt/memdisk# diff -rq SRC DST</b>
<b>terre:/mnt/memdisk# echo $?</b>
0
<b>terre:/mnt/memdisk#</b>
</code>
<p>
By chance it did not affected the ability to restore the backup. However if it ever had,
we have several fallbacks: the <code>--sequential-read</code> mode, the use a already created
snapshot (aka isolated catalogue) as seen about the snapshot feature to backup the internal
table of content, or as last resort
the <code>-alax option</code> eventually combined with the <code>--sequential-read</code>
mode and a backup snapshot.
</p>
<h5>Rsync</h5>
<code class=block>
<b>terre:/mnt/memdisk# rm -rf DST</b>
<b>terre:/mnt/memdisk# rsync -arHAXS SRC/* DST</b>
<b>terre:/mnt/memdisk# ls -al DST</b>
total 0
drwxr-xr-x 3 root root 60 Nov 17 18:07 .
drwxrwxrwt 4 root root 140 Nov 17 18:07 ..
drwxrwxr-x 24 root root 740 Nov 10 21:16 linux-5.9.8
<b>terre:/mnt/memdisk# diff -rq SRC DST</b>
<b>terre:/mnt/memdisk# ./hide_change DST/linux-5.9.8/README 10</b>
<b>terre:/mnt/memdisk# diff -rq SRC DST</b>
Files SRC/linux-5.9.8/README and DST/linux-5.9.8/README differ
<b>terre:/mnt/memdisk# rsync -arvHAXS SRC/* DST</b>
sending incremental file list
sent 1,254,054 bytes received 5,215 bytes 839,512.67 bytes/sec
total size is 954,980,692 speedup is 758.36
<b>terre:/mnt/memdisk# diff -rq SRC DST</b>
<e>Files SRC/linux-5.9.8/README and DST/linux-5.9.8/README differ</e>
<b>terre:/mnt/memdisk#</b>
</code>
<p>
modifying the backup (the directory we sync with), <i>rsync</i> does not
report any difference and the backup stay corrupted.
</p>
<h5>Tar</h5>
<code class=block>
<b>terre:/mnt/memdisk# rm -rf DST</b>
<b>terre:/mnt/memdisk# tar -czf backup.tar.gz SRC</b>
<b>terre:/mnt/memdisk# ls -l backup*</b>
-rw-r--r-- 1 root root 183659664 Nov 17 18:11 backup.tar.gz
<b>terre:/mnt/memdisk# ./hide_change backup.tar.gz 1</b>
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# cd DST</b>
<b>terre:/mnt/memdisk/DST# tar -xzf ../backup.tar.gz</b>
gzip: stdin: not in gzip format
tar: Child returned status 1
<e class=red>tar: Error is not recoverable: exiting now</e>
<b>terre:/mnt/memdisk/DST#</b>
<b>terre:/mnt/memdisk/DST# find . -ls</b>
1720964 0 drwxr-xr-x 2 root root 40 Nov 17 18:56 .
<b>terre:/mnt/memdisk/DST#</b>
</code>
<p>
Modifying the first byte leads to a completely unusable backup. Nothing got restored at all.
Let's see what going on when modifying a single bit in the middle of the backup:
</p>
<code class=block>
<b>terre:/mnt/memdisk# ls -l backup*</b>
-rw-r--r-- 1 root root 183659664 Nov 17 18:11 backup.tar.gz
<b>terre:/mnt/memdisk# ./hide_change backup.tar.gz 734638656</b>
<b>terre:/mnt/memdisk# cd DST</b>
<b>terre:/mnt/memdisk/DST# tar -xf ../backup.tar.gz</b>
tar: Skipping to next header
<e class=red>gzip: stdin: invalid compressed data--crc error</e>
gzip: stdin: invalid compressed data--length error
tar: Child returned status 1
<e>tar: Error is not recoverable: exiting now</e>
<b>terre:/mnt/memdisk/DST#</b>
<b>terre:/mnt/memdisk/DST# diff -rq ../SRC SRC | wc -l</b>
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/arc: No such file or directory
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/arm: No such file or directory
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/arm64: No such file or directory
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/c6x: No such file or directory
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/h8300: No such file or directory
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/microblaze: No such file or directory
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/mips: No such file or directory
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/nios2: No such file or directory
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/openrisc: No such file or directory
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/powerpc: No such file or directory
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/sh: No such file or directory
diff: SRC/linux-5.9.8/scripts/dtc/include-prefixes/xtensa: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/copyloops/copy_mc_64.S: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/copyloops/copyuser_64.S: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/copyloops/memcpy_64.S: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/nx-gzip/include/vas-api.h: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/primitives/asm/asm-compat.h: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/primitives/asm/asm-const.h: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/primitives/asm/feature-fixups.h: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/primitives/asm/ppc_asm.h: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/primitives/word-at-a-time.h: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/stringloops/memcmp_32.S: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/stringloops/memcmp_64.S: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/stringloops/strlen_32.S: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/vphn/asm/lppaca.h: No such file or directory
diff: SRC/linux-5.9.8/tools/testing/selftests/powerpc/vphn/vphn.c: No such file or directory
<e>150</e>
<b>terre:/mnt/memdisk/DST# find ../SRC | wc -l</b>
<e class=blue>74726</e>
<b>terre:/mnt/memdisk/DST# find SRC | wc -l</b>
<e class=red>32615</e>
<b>terre:/mnt/memdisk/DST#</b>
</code>
<p>
Only 32615 files on the 74726 that were saved could be restored. Assuming the problem is due to
the fact the backup is compressed, let's see tar without compression:
</p>
<code class=block>
<b>terre:/mnt/memdisk# tar -cf backup.tar SRC</b>
<b>terre:/mnt/memdisk# ls -l backup*</b>
-rw-r--r-- 1 root root 1011312640 Nov 17 19:28 backup.tar
<b>terre:/mnt/memdisk# ./hide_change backup.tar 1</b>
<b>terre:/mnt/memdisk# rm -rf DST</b>
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# cd DST</b>
<b>terre:/mnt/memdisk/DST# tar -xf ../backup.tar</b>
tar: This does not look like a tar archive
<e>tar: Skipping to next header</e>
tar: Exiting with failure status due to previous errors
<b>terre:/mnt/memdisk/DST# diff -rq ../SRC SRC</b>
<b>terre:/mnt/memdisk/DST# echo $?</b>
0
<b>terre:/mnt/memdisk/DST#</b>
</code>
<p>
Without compression, a <i>tar</i> backup is much more reliable, however we now need more than 5 times
storage space to hold the backup. Let's see what happens when we modify a single bit in the midle of the backup:
</p>
<code class=block>
<b>terre:/mnt/memdisk# ./hide_change backup.tar 4045250560</b>
<b>terre:/mnt/memdisk# rm -rf DST</b>
<b>terre:/mnt/memdisk# mkdir DST</b>
<b>terre:/mnt/memdisk# cd DST</b>
<b>terre:/mnt/memdisk/DST# tar -xf ../backup.tar</b>
<b>terre:/mnt/memdisk/DST#</b>
<b>terre:/mnt/memdisk/DST# diff -rq ../SRC SRC</b>
<e class=red>Files ../SRC/linux-5.9.8/drivers/media/pci/bt8xx/bttv-cards.c and SRC/linux-5.9.8/drivers/media/pci/bt8xx/bttv-cards.c differ</e>
<b>terre:/mnt/memdisk/DST#</b>
</code>
<p>
the backup restoration suceeded according to <i>tar</i> but the corruption has been completely ignored!!!
The result is both a corrupted backup and a corrupted restored data, with no notification at all...
</p>
<h5>Parchive</h5>
<p>
We can increase the robustness of any file or set of files by mean of <i>Parchive</i> software. If its use
is adapted to <i>tar</i> and <i>dar</i> it is not adapted to <i>rsync</i> due to the directory tree structure it uses for its backup.
We will thus here measure the par2create (<i>Parchive</i>) execution time compared to backup time of <i>tar</i> and <i>dar</i>.
</p>
<code class=block>
<b>devuan:/mnt/memdisk# mkdir SRC</b>
<b>devuan:/mnt/memdisk# cp --preserve -r /usr SRC</b>
<b>devuan:/mnt/memdisk# time <e class=blue>tar</e> -czf backup.tar.gz SRC</b>
62.550u 3.148s <e>1:01.75</e> 106.3% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# time <e class=blue>dar</e> -c backup -z6 -1 0 -at -R SRC -q</b>
60.287u 1.152s <e>1:01.45</e> 99.9% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# ls -l backup.*</b>
-rw-r--r-- 1 root root <e>601976990</e> Dec 1 10:48 backup.1.dar
-rw-r--r-- 1 root root <e>588260243</e> Dec 1 10:47 backup.tar.gz
<b>devuan:/mnt/memdisk# time <e class=blue>par2create</e> -r5 -n1 -q backup.tar.gz</b>
Opening: backup.tar.gz
Done
94.465u 0.535s <e>0:05.74</e> 1654.8% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# time <e class=blue>par2create</e> -r5 -n1 -q backup.1.dar</b>
Opening: backup.1.dar
Done
110.048u 0.364s <e>0:06.19</e> 1783.5% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
We see that the redundancy process is not negligible: for 5% of data redundancy,
we need around 10% of extra CPU time. Things get worse when the size of the
data to process by <i>Parchive</i> increases and when the disk I/O comes to play
(here the /mnt/memdisk was an in-memory tmpfs filesystem). This is the
case when the amount of data to backup is larger than the available RAM space, which
is a quite frequent situation:
</p>
<code class=block>
<b>devuan:~/tmp# du -sh SRC</b>
<e>27G</e> SRC
<b>devuan:~/tmp# free -m</b>
. total used free shared buff/cache available
Mem: <e>15776</e> 560 433 1 14782 14823
Swap: 0 0 0
<b>devuan:~/tmp#</b>
</code>
<p>
We are now placed in this context, having a 27 GiB data to backup on a machine having only around 16 GiB of
RAM.
</p>
<code class=block>
<b>devuan:~/tmp# time dar -c backup -z6 -at -1 0 -R SRC -q <e class=blue>-E 'par2create -r5 -n1 -q %b.%N.%e'</e></b>
Opening: backup.1.dar
Done
15237.777u 105.379s <e>36:48.53</e> 694.7% 0+0k 158854544+57572120io 158pf+0w
<b>devuan:~/tmp#</b>
</code>
<p>
This execution time of around 36 mn above can be improved by using multiple slices. Choosing a slice size smaller than the available RAM
let <i>Parchive</i> compute parity data right after each slice has been generated, while it is still in the disk cache (RAM),
bypassing the corresponding disks I/O we had previously in a second time:
</p>
<code class=block>
<b>devuan:~/tmp# time dar -c backup_splitted -z6 -at -1 0 -R SRC -q <e class=blue>-E 'par2create -r5 -n1 -q %b.%N.%e'</e> <e>-s 1G</e></b>
Opening: backup_splitted.1.dar
Done
Opening: backup_splitted.2.dar
Done
<i>[...]</i>
Opening: backup_splitted.26.dar
Done
Opening: backup_splitted.27.dar
Done
6040.106u 49.201s <e>21:58.73</e> 461.7% 0+0k 61862640+57567104io 123pf+0w
<b>devuan:~/tmp#</b>
</code>
<p>
The total execution time dropped to around 22 mn! Which makes a 40% time reduction.
By the way, having here 27 files of 1 GiB is also easier to manipulate (file transfer,
copy to removable media,...) than a huge equivalent file of 27 GiB.
</p>
<code class=block>
<b>devuan:~/tmp# time tar -czf backup.tar.gz SRC</b>
<e class=blue>837.662u</e> 80.776s <e>18:26.08</e> 83.0% 0+0k 54926128+54799696io 6pf+0w
<b>devuan:~/tmp# time par2create -r5 -n1 -q backup.tar.gz</b>
Opening: backup.tar.gz
Done
<e class=blue>13352.393u</e> 71.390s <e>18:24.34</e> 1215.5% 0+0k 95000064+2772144io 9pf+0w
<b>devuan:~/tmp#</b>
</code>
<p>
We get the same execution time (18 mn) for both <i>tar</i> and <i>par2</i> for thus a total of 36 mn.
This same time for both software while the real CPU usage is much more important for <i>par2</i>,
clearly shows that the slowest operation was the disk I/O. Else the overall time of the operation
is similar to what we say with <i>dar</i> above, except that we cannot use multi-volume
to speed up the operation as we did with <i>dar</i>: <i>tar</i> is not able to compress
*and* produce multi-volume backup: What we would gain on one side would be lost on the
other side...
</p>
<h3>Execution <a name="performance">Performance</a></h3>
</p>
<p>
In order to compare performance in a fair manner, we have to take into
consideration that some CPU intensive features are not implement by all softwares or have
different default values:
</p>
<ul>
<li>
The default compression level differs: <i>dar</i> uses level 9 by default while <i>rsync</i>
and <i>tar</i> use level 6 which is faster. Only <i>dar</i> and <i>rsync</i> seems able
let the user set this value, so we will have to manually set <i>dar</i> to use level 6 too:
<code>-z6 option</code>
</li>
<li>
the disk usage optimization is not supported by <i>tar</i> so we will not activate
sparse file detection and optimization (for <i>rsync</i> no <code>-S option</code>)
and disable it for <i>dar</i>
(activated by default): <code>-1 0 option</code>
</li>
<li>
<i>dar</i> spends non negligible CPU cycle to duplicate metadata along the backup, this
is one of the root of exclusive robusness brought by <i>dar</i> backups, but this is an
optional feature. We will disable it using the
<code>-at option</code>
</li>
<li>
<i>rsync</i> and <i>dar</i> calculate checksum on the saved data, while tar completely skips
this data protection. Unfortunately this is not possible to disable for both,
thus <i>tar</i> will have a speed advantage thanks to this difference.
</li>
</ul>
</p>
For the data reduction, we will first compare with the same feature set, then activate all specific
features each software can leverage to improve data reduction, and will measure the execution
time impact.
</p>
<p>
All performance aspects are not interesting in all <b>use cases</b>. We can distinguish two main
types of use cases:
</p>
<ul>
<li>
A first set of tests will cover the <b>copy operations</b>, they will not use any compression, focusing
only on execution time.
</li>
<li>
A second set of tests will cover the <b>backup operations</b>, use compression and focus on the data
reduction mainly but also on the execution time.
</li>
</ul>
<p>
When using <i>rsync</i> as a backup tool (at the opposite of a copy operation), we assume the remote
(or local) copy <i>is</i> the backup, and thus restoring implies syncing back this remote (or local)
copy to the place the original data was located and has been lost.
</p>
<p>
To prepare the data under test we used:
</p>
<ul>
<li>a big ISO file</li>
<li>a full linux system</li>
</ul>
<p>
All data to backup or to copy has been stored in a tmpfs, which is also the destination of the created backups and
restored data. The swap has been disabled to avoid any disk I/O penalty, in the intention to provide a fair
comparison environment (avoiding disk cache variable performance).
</p>
<code class=block>
<b>devuan:/mnt/memdisk# free</b>
total used free shared buff/cache available
Mem: 16155172 691764 151608 8780152 15311800 6299316
<e>Swap: 0 0 0</e>
<b>devuan:/mnt/memdisk# df -h .</b>
Filesystem Size Used Avail Use% Mounted on
<e>tmpfs</e> 14G 4.0K 14G 1% /mnt/memdisk
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
To prepare the Linux system under backup we installed the <i>Devuan</i> system a few days before in a VM. On day D,
a full backup has been executed, we updated/upgraded the system using the disto package manager and we made a differential
backup based on the first one, both backup being wrote to the testing machine (bare-metal server) that was used for the performance tests:
</p>
<code class=block>
<b>root@Georges:~# dar -c sftp://denis@10.13.30.163/home/denis/tmp/full -zlz4 -R / -M -D --hash sha1 -afile-auth -C cat_full</b>
<b>root@Georges:~# apt-get update</b>
<i>[...]</i>
<b>root@Georges:~# apt-get upgrade</b>
<i>[...]</i>
<b>root@Georges:~# dar -c sftp://denis@10.13.30.163/home/denis/tmp/diff -A cat_full -zlz4 -R / -M -D --hash sha1 -afile-auth</b>
<b>root@Georges:~#</b>
</code>
<p>
Back on the testing host (the bare-metal server at 10.13.30.163) we restored the data
for the performance test, the following way: excluding FSA and EA to avoid a tone of warning as those are not
supported on tmpfs filesystem:
</p>
<code class=block>
<b>devuan:/mnt/memdisk# mkdir state-1</b>
<b>devuan:/mnt/memdisk# mkdir state-2</b>
<b>devuan:/mnt/memdisk# dar -x ~denis/tmp/full -R state-1 --fsa-scope none -u "*"</b>
--------------------------------------------
136836 inode(s) restored
including 27 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
0 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 136836
--------------------------------------------
EA restored for 3 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
<b>devuan:/mnt/memdisk# dar -x ~denis/tmp/full -R state-2 --fsa-scope none -u "*"</b>
--------------------------------------------
136836 inode(s) restored
including 27 hard link(s)
0 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
0 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 136836
--------------------------------------------
EA restored for 3 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
<b>devuan:/mnt/memdisk# dar -x ~denis/tmp/diff -R state-2 --fsa-scope none -u "*" -w</b>
--------------------------------------------
568 inode(s) restored
including 0 hard link(s)
136670 inode(s) not restored (not saved in archive)
0 inode(s) not restored (overwriting policy decision)
0 inode(s) ignored (excluded by filters)
0 inode(s) failed to restore (filesystem error)
0 inode(s) deleted
--------------------------------------------
Total number of inode(s) considered: 137238
--------------------------------------------
EA restored for 0 inode(s)
FSA restored for 0 inode(s)
--------------------------------------------
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
This leads us to have two directories <code>state-1</code> and <code>state-2</code> corresponding to the state of the <i>Devuan</i> machine has two days ago and today respectively.
</p>
<h4>Performance of <a name="copy_perf">copy</a> operations</h4>
<p>
To perform the copy operation, we have decomposed the operations to precisely measure the execution time. We could have decided to pipe the backup to a second instance of the
backup tool restoring the data (<i>tar</i> and <i>dar</i> only would benefit from this). But the time measurement was less easy to obtain and doing that way does not seem to
provide any noticable speed improvement. The data used here in <code>SRC1</code> is a single big ISO file (a <i>Devuan</i> installation DVD image).
</p>
<h5>Dar</h5>
<code class=block>
<b>devuan:/mnt/memdisk# time dar -c copy -1 0 -at -R SRC1 -q</b>
1.834u 2.909s <e>0:04.87</e> 97.1% 0+0k 744+0io 12pf+0w
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# time dar -x copy -R DST -q</b>
1.563u 2.836s <e>0:04.41</e> 99.5% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# du -sh SRC1 DST</b>
4.4G SRC1
4.4G DST
<b>devuan:/mnt/memdisk# diff -r SRC1 DST</b>
<b>devuan:/mnt/memdisk# echo $?</b>
0
<b>devuan:/mnt/memdisk# rm -rf DST copy.1.dar</b>
<b>devuan:/mnt/memdisk# time dar -c copy -1 0 -at -R SRC2 -q</b>
4.739u 3.683s <e>0:08.44</e> 99.6% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# time dar -x copy -R DST -q</b>
4.449u 3.872s <e>0:08.34</e> 99.6% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# du -sh SRC2 DST</b>
4.1G SRC2
4.1G DST
<b>devuan:/mnt/memdisk# find DST | wc -l</b>
136837
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
The overall copy time for <i>dar</i> is:
</p>
<ul>
<li>9.18 seconds for the big file in <code>SRC1</code></li>
<li>16.78 seconds for the full linux system in <code>SRC2</code></li>
</ul>
<h5>Rsync</h5>
<code class=block>
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# time rsync -arH SRC1 DST</b>
23.088u 5.420s <e>0:15.28</e> 186.5% 0+0k 168+0io 4pf+0w
<b>devuan:/mnt/memdisk# diff -r SRC1/ DST/SRC1/</b>
<b>devuan:/mnt/memdisk# echo $?</b>
0
<b>devuan:/mnt/memdisk# rm -rf DST</b>
<b>devuan:/mnt/memdisk# time rsync -arH SRC2 DST</b>
22.408u 8.560s <e>0:16.59</e> 186.6% 0+0k 1224+0io 6pf+0w
<b>devuan:/mnt/memdisk# du -sh SRC2 DST</b>
4.1G SRC2
4.1G DST
<b>devuan:/mnt/memdisk# find DST | wc -l</b>
136838
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
The overall copy time for <i>rsync</i> is:
</p>
<ul>
<li>15.28 seconds for the big file in <code>SRC1</code></li>
<li>16.59 seconds for the full linux system in <code>SRC2</code></li>
</ul>
<h5>Tar</h5>
<code class=block>
<b>devuan:/mnt/memdisk# cd SRC1</b>
<b>devuan:/mnt/memdisk/SRC1# time tar -cf ../copy.tar *</b>
0.343u 2.756s <e>0:03.10</e> 99.6% 0+0k 104+0io 1pf+0w
<b>devuan:/mnt/memdisk/SRC1# cd ../</b>
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# cd DST</b>
<b>devuan:/mnt/memdisk/DST# time tar -xf ../copy.tar</b>
0.339u 3.071s <e>0:03.41</e> 99.7% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST# cd ..</b>
<b>devuan:/mnt/memdisk# diff -r SRC1/ DST/</b>
<b>devuan:/mnt/memdisk# echo $?</b>
0
<b>devuan:/mnt/memdisk# rm -rf DST copy.tar</b>
<b>devuan:/mnt/memdisk# cd SRC2</b>
<b>devuan:/mnt/memdisk/SRC2# time tar -cf ../copy.tar *</b>
<e class=red>tar: tmp/.ICE-unix/19789: socket ignored</e>
<e class=red>tar: tmp/.X11-unix/X0: socket ignored</e>
0.760u 2.887s <e>0:03.66</e> 99.4% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/SRC2# cd ..</b>
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# cd DST</b>
<b>devuan:/mnt/memdisk/DST# time tar -xf ../copy.tar</b>
0.814u 3.556s <e>0:04.38</e> 99.5% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST# cd ..</b>
<b>devuan:/mnt/memdisk# du -sh SRC2 DST</b>
4.1G SRC2
4.1G DST
<b>devuan:/mnt/memdisk# find DST | wc -l</b>
136834
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
the overall copy time for <i>tar</i> is:
</p>
<ul>
<li>6.51 seconds for the big file in <code>SRC1</code></li>
<li>8.04 seconds for the full Linux system in <code>SRC2</code></li>
</ul>
<h5>Cp</h5>
<code class=block>
<b>devuan:/mnt/memdisk# time cp --preserve -r SRC1 DST</b>
0.051u 2.514s <e>0:02.58</e> 99.2% 0+0k 8+0io 1pf+0w
<b>devuan:/mnt/memdisk# diff -r SRC1 DST</b>
<b>devuan:/mnt/memdisk# echo $?</b>
0
<b>devuan:/mnt/memdisk# rm -rf DST</b>
<b>devuan:/mnt/memdisk# time cp --preserve -r SRC2 DST</b>
0.910u 4.194s <e>0:05.15</e> 99.0% 0+0k 288+0io 1pf+0w
<b>devuan:/mnt/memdisk# du -sh SRC2 DST</b>
<e>4.1G</e> SRC2
<e class=red>4.2G</e> DST
<b>devuan:/mnt/memdisk# find DST | wc -l</b>
136838
<b>devuan:/mnt/memdisk# find DST/SRC2/tmp/ -ls</b>
2315983 0 drwxrwxrwt 4 root root 100 Dec 3 10:32 DST/SRC2/tmp/
2315987 0 drwxrwxrwt 2 root root 60 Dec 3 10:27 DST/SRC2/tmp/.ICE-unix
2315988 0 srwxrwxrwx 1 denis denis 0 Dec 3 10:27 DST/SRC2/tmp/.ICE-unix/19789
2315985 0 drwxrwxrwt 2 root root 60 Dec 3 10:32 DST/SRC2/tmp/.X11-unix
2315986 0 srwxrwxrwx 1 root root 0 Dec 3 10:32 DST/SRC2/tmp/.X11-unix/X0
2315984 4 -r--r--r-- 1 root root 11 Dec 3 10:32 DST/SRC2/tmp/.X0-lock
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
The overall copy time for <i>cp</i> is:
</p>
<ul>
<li>2.58 seconds for the big file in <code>SRC1</code></li>
<li>5.15 seconds for the full Linux system in <code>SRC2</code></li>
</ul>
<p>
<i>cp</i> is always the fastest and does reject the unix sockets as <i>tar</i> does.
However it requires slightly more storage than all other softwares tested here. And if
metadata (ACL, Extended Attributes, filesystem specific attributes, ...) need to be copied
with data, it does not match the need.
</p>
<h4>Performance of <a name="backup_perf">Backup</a> operations</h4>
<p>
For reference:
</p>
<code class=block>
<b>devuan:/mnt/memdisk# du -sb state-*</b>
<e>4095931349</e> state-1
<e>4136318367</e> state-2
<b>devuan:/mnt/memdisk# find state-1 | wc -l</b>
136837
<b>devuan:/mnt/memdisk# find state-2 | wc -l</b>
137239
<b>devuan:/mnt/memdisk#</b>
</code>
<h5>Dar</h5>
<h6>Minimal features</h6>
<code class=block>
<b>devuan:/mnt/memdisk# time dar -c dar-full -R state-1 -at -1 0 -z6 -q</b>
145.970u 3.263s <e>2:29.73</e> 99.6% 0+0k 12344+0io 71pf+0w
<b>devuan:/mnt/memdisk# time dar -c dar-diff -R state-2 -A dar-full -at -1 0 -z6 -q -asecu</b>
8.957u 0.959s <e>0:09.93</e> 99.6% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# ls -l *.dar</b>
-rw-r--r-- 1 root root <e>49498524</e> Dec 3 16:17 dar-diff.1.dar
-rw-r--r-- 1 root root <e>1580562224</e> Dec 3 16:16 dar-full.1.dar
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# time dar -x dar-full -R DST -q</b>
18.677u 4.244s <e>0:22.94</e> 99.8% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# time dar -x dar-diff -R DST -q -w</b>
2.585u 0.780s <e>0:03.48</e> 96.5% 0+0k 1856+0io 20pf+0w
<b>devuan:/mnt/memdisk#</b>
<b>devuan:/mnt/memdisk# time dar -x dar-full -R DST -q -w -g etc/fstab</b>
0.934u 0.036s <e>0:00.98</e> 97.9% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
for <i>dar</i> with minimal features (metadata no redundancy <code>-at</code>, no sparse file consideration <code>-1 0</code>):
</p>
<ul>
<li>data reduction on storage for the full backup is: 61.41%</li>
<li>data reduction on storage for the diff backup is: 98.80%</li>
<li>data reduction over the network is the same as on storage</li>
<li>execution time to restore a single file is: 0.98 s</li>
<li>execution time to restore the full backup: 22.94 s</li>
<li>execution time ot restore the diff backup: 3.48 s </li>
<li>full backup time: 149.73 s</li>
<li>diff backup time: 9.93 s</li>
</ul>
<h6>sparse file</h6>
<code class=block>
<b>devuan:/mnt/memdisk# rm -rf DST *.dar</b>
<b>devuan:/mnt/memdisk# time dar -c dar-full -R state-1 -at -z6 -q</b>
154.971u 3.000s <e>2:37.99</e> 99.9% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# time dar -c dar-diff -R state-2 -A dar-full -at -z6 -q -asecu</b>
9.488u 0.871s <e>0:10.37</e> 99.8% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# ls -l *.dar</b>
-rw-r--r-- 1 root root <e>49505251</e> Dec 3 16:27 dar-diff.1.dar
-rw-r--r-- 1 root root <e>1578428790</e> Dec 3 16:25 dar-full.1.dar
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# time dar -x dar-full -R DST -q</b>
24.231u 6.110s <e>0:30.36</e> 99.9% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# time dar -x dar-diff -R DST -q -w</b>
2.677u 0.793s <e>0:03.48</e> 99.4% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# time dar -x dar-full -R DST -q -w -g etc/fstab</b>
1.067u 0.053s <e>0:01.13</e> 98.2% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
for <i>dar</i> with default features (metadata no redundancy <code>-at</code>, with sparse file consideration (activated by default))
</p>
<ul>
<li>data reduction on storage for the full backup is: 61.46%</li>
<li>data reduction on storage for the diff backup is: 98.80%</li>
<li>data reduction over the network is the same as on storage</li>
<li>execution time to restore a single file is: 1.13 s</li>
<li>execution time to restore the full backup: 30.36 s</li>
<li>execution time ot restore the diff backup: 3.48 s </li>
<li>full backup time: 157.99 s</li>
<li>diff backup time: 10.37 s</li>
</ul>
<h6>Sparse file and binary delta</h6>
<code class=block>
<b>devuan:/mnt/memdisk# rm -rf DST *.dar</b>
<b>devuan:/mnt/memdisk# time dar -c dar-full -R state-1 -at -z6 --delta sig -q</b>
159.262u 3.332s <e>2:42.62</e> 99.9% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# time dar -c dar-diff -R state-2 -A dar-full -at -z6 -q -asecu</b>
6.149u 0.950s <e>0:07.11</e> 99.7% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# ls -l *.dar</b>
-rw-r--r-- 1 root root <e>23883368</e> Dec 3 16:39 dar-diff.1.dar
-rw-r--r-- 1 root root <e>1602481058</e> Dec 3 16:38 dar-full.1.dar
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# time dar -x dar-full -R DST -q</b>
24.169u 6.163s <e>0:30.35</e> 99.9% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# time dar -x dar-diff -R DST -q -w</b>
2.481u 0.942s <e>0:03.44</e> 99.4% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# time dar -x dar-full -R DST -q -w -g etc/fstab</b>
1.205u 0.059s <e>0:01.27</e> 98.4% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
for <i>dar</i> with advanced features (metadata no redundancy <code>-at</code>, with binary delta computation <code>--delta sig</code>):
</p>
<ul>
<li>data reduction on storage for the full backup is: 60,87%</li>
<li>data reduction on storage for the diff backup is: 99.42%</li>
<li>data reduction over the network is the same as on storage</li>
<li>execution time to restore a single file is: 1.27 s</li>
<li>execution time to restore the full backup: 30.35 s</li>
<li>execution time ot restore the diff backup: 1.27 s </li>
<li>full backup time: 162.62 s</li>
<li>diff backup time: 7.11 s</li>
</ul>
<h5>Rsync</h5>
<h6>minimal features</h6>
<code class=block>
<b>devuan:/mnt/memdisk# mkdir rsync-backup</b>
<b>devuan:/mnt/memdisk# time rsync -arHz --info=stats state-1/* rsync-backup</b>
sent <e>1,585,540,014 bytes received 2,174,472 bytes</e> 10,080,726.90 bytes/sec
total size is 4,260,538,564 speedup is 2.68
202.640u 8.503s <e>2:36.98</e> 134.5% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk#</b>
<b>devuan:/mnt/memdisk# time rsync -arHz --info=stats <e class=blue>--no-whole-file</e> state-2/* rsync-backup</b>
<e>sent 29,077,377 bytes received 216,581 bytes</e> 3,446,348.00 bytes/sec
total size is 4,300,916,222 speedup is 146.82
7.555u 1.115s <e>0:07.33</e> 118.1% 0+0k 1784+0io 7pf+0w
<b>devuan:/mnt/memdisk# du -sb rsync-backup</b>
<e>4136318307</e> rsync-backup
<b>devuan:/mnt/memdisk#</b>
<b>devuan:/mnt/memdisk# rm -rf state-1</b>
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# time rsync -arHz --info=stats <e class=blue>--no-whole-file</e> rsync-backup/* DST</b>
<e>sent 1,599,585,756 bytes received 2,181,147 bytes</e> 10,105,784.88 bytes/sec
total size is 4,300,916,222 speedup is 2.69
204.192u 8.306s <e>2:37.81</e> 134.6% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# time rsync -arHz --info=stats rsync-backup/etc/fstab DST/etc</b>
sent 44 bytes received 12 bytes 112.00 bytes/sec
total size is 664 speedup is 11.86
<e>0.001u 0.002s</e> 0:00.00 0.0% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
for <i>rsync</i> with minimal features (no sparse file consideration):
</p>
<ul>
<li>data reduction on storage for the full backup is: 0%</li>
<li>data reduction on storage for the diff backup is: 0%</li>
<li>data reduction over the network for the full backup is: 61.23%</li>
<li>data reduction over the network for the diff backup is: 99.29%</li>
<li>execution time to restore a single file is: 0.003 s</li>
<li>execution time ot restore the full+diff backup: 157.81 s (this is not due to the <code>--no-whole-file</code> see next text)</li>
<li>full backup time: 156.98 s</li>
<li>diff backup time: 7.33 s</li>
</ul>
<h6>sparse file + binary delta</h6>
<code class=block>
<b>devuan:/mnt/memdisk# mkdir rsync-backup</b>
<b>devuan:/mnt/memdisk# time rsync -arHSz --info=stats state-1/* rsync-backup</b>
<e>sent 1,585,540,014 bytes received 2,174,460 bytes</e> 8,605,498.50 bytes/sec
total size is 4,260,538,564 speedup is 2.68
232.038u 13.137s <e>3:03.44</e> 133.6% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# time rsync -arHSz --info=stats <e class=blue>--no-whole-file</e> state-2/* rsync-backup</b>
<e>sent 29,077,381 bytes received 216,577 bytes</e> 3,446,348.00 bytes/sec
total size is 4,300,916,222 speedup is 146.82
7.305u 1.275s <e>0:07.04</e> 121.7% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# du -sb rsync-backup</b>
<e>4136318307</e> rsync-backup
<b>devuan:/mnt/memdisk# rm -rf state-1</b>
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# time rsync -arHSz --info=stats rsync-backup/* DST</b>
sent 1,599,585,756 bytes received 2,181,219 bytes 10,042,426.18 bytes/sec
total size is 4,300,916,222 speedup is 2.69
205.089u 12.354s <e>2:38.39</e> 137.2% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk#</b>
<b>devuan:/mnt/memdisk# time rsync -arHSz --info=stats rsync-backup/etc/fstab DST/etc</b>
sent 44 bytes received 12 bytes 112.00 bytes/sec
total size is 664 speedup is 11.86
0.001u 0.002s 0:00.00 0.0% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
for <i>rsync</i> with advanced features (sparse file consideration <code>-S option</code>, binary delta <code>--no-whole-file</code>)
</p>
<ul>
<li>data reduction on storage for the full backup is: 0%</li>
<li>data reduction on storage for the diff backup is: 0%</li>
<li>data reduction over the network for the full backup is: 60.64%</li>
<li>data reduction over the network for the diff backup is: 99.28%</li>
<li>execution time to restore a single file is: 0.003 s</li>
<li>execution time to restore the full+diff backup: 158.39 s</li>
<li>full backup time: 183.44 s</li>
<li>diff backup time: 7.04 s</li>
</ul>
<h5>Tar</h5>
<h6>minimal features</h6>
<code class=block>
<b>devuan:/mnt/memdisk# cd state-1</b>
<b>devuan:/mnt/memdisk/state-1# time tar --listed-incremental=../snapshot.file -czf ../tar-full.tar.gz *</b>
<e class=red>tar: tmp/.ICE-unix/19789: socket ignored</e>
<e class=red>tar: tmp/.X11-unix/X0: socket ignored</e>
153.624u 8.676s 2:31.71 106.9% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/state-1# time tar --listed-incremental=../snapshot.file -czf ../tar-diff.tar.gz *</b>
0.809u 0.369s 0:00.98 118.3% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/state-1# cd ..</b>
<b>devuan:/mnt/memdisk# ls -l tar*</b>
-rw-r--r-- 1 root root 765425 Dec 3 16:49 tar-diff.tar.gz
-rw-r--r-- 1 root root 1546464033 Dec 3 16:48 tar-full.tar.gz
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# cd DST</b>
<b>devuan:/mnt/memdisk/DST# time tar -xzf ../tar-full.tar.gz</b>
27.106u 6.756s 0:26.72 126.6% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST# cd ..</b>
<b>devuan:/mnt/memdisk# diff --no-dereference -r state-1 DST</b>
Only in state-1: .cache
Only in state-1/tmp/.ICE-unix: 19789
Only in state-1/tmp/.X11-unix: X0
<b>devuan:/mnt/memdisk# cd DST</b>
<b>devuan:/mnt/memdisk/DST# time tar -xzf ../tar-diff.tar.gz</b>
0.183u 0.085s <e class=red>0:00.18</e> 144.4% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST#</b>
</code>
<p>
Doing that way, the <i>tar</i> differential backup is empty: it only contains empty directories, no file data.
We will apply the changes over <code>state-1</code> rather than already setup changes at <code>state-2</code>.
This seems to mean that if the system clock is wrong or was wrong at the time a file was modified
(like daylight saving? or before NTP synchronization at system startup), which is
the same as here, were the changes have been brought before full backup was done, <b><u>those changes will not be
backed up by <i>tar</i></u></b>, while the file's attributes (file size, last modification date,...) changed.
</p>
<code class=block>
<b>devuan:/mnt/memdisk# cd state-1</b>
<b>devuan:/mnt/memdisk/state-1# time tar --listed-incremental=../snapshot.file -czf ../tar-full.tar.gz *</b>
<e class=red>tar: tmp/.ICE-unix/19789: socket ignored</e>
<e class=red>tar: tmp/.X11-unix/X0: socket ignored</e>
150.751u 8.299s <e>2:28.59</e> 107.0% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/state-1# cd ..</b>
<b>devuan:/mnt/memdisk# dar -x ~denis/tmp/diff -R state-1 --fsa-scope none -u "*" -w -q</b>
<b>devuan:/mnt/memdisk# cd state-1</b>
<b>devuan:/mnt/memdisk/state-1# time tar --listed-incremental=../snapshot.file -czf ../tar-diff.tar.gz *</b>
6.147u 0.559s <e>0:06.40</e> 104.5% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/state-1# cd ..</b>
<b>devuan:/mnt/memdisk# ls -l tar* snapshot.file</b>
-rw-r--r-- 1 root root <e>3350869</e> Dec 3 17:08 snapshot.file
-rw-r--r-- 1 root root <e>44607904</e> Dec 3 17:08 tar-diff.tar.gz
-rw-r--r-- 1 root root <e>1546448179</e> Dec 3 17:04 tar-full.tar.gz
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# cd dst</b>
dst: No such file or directory.
<b>devuan:/mnt/memdisk# cd DST</b>
<b>devuan:/mnt/memdisk/DST# time tar -xzf ../tar-full.tar.gz</b>
26.807u 7.020s <e>0:26.72</e> 126.5% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST# time tar -xzf ../tar-diff.tar.gz</b>
1.492u 0.381s <e>0:01.48</e> 126.3% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST# time tar -xzf ../tar-full.tar.gz etc/fstab</b>
25.219u 2.581s <e>0:25.15</e> 110.4% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST#</b>
</code>
<p>
for <i>tar</i> with minimal features (no sparse file consideration):
</p>
<ul>
<li>data reduction on storage for the full backup is: 62.16%</li>
<li>data reduction on storage for the diff backup is: 98.92%</li>
<li>data reduction over the network is the same as on storage</li>
<li>execution time to restore a single file is: 25.15 s</li>
<li>execution time to restore the full backup: 26.72 s</li>
<li>execution time ot restore the diff backup: 1.48 s</li>
<li>full backup time: 148.59 s</li>
<li>diff backup time: 6.40 s</li>
</ul>
<h6>sparse file</h6>
<p>
Whe had to recreate <code>state-1</code> as we needed modifying it at previous test
</p>
<code class=block>
<b>devuan:/mnt/memdisk# rm tar* snapshot.file</b>
<b>devuan:/mnt/memdisk# cd state-1</b>
<b>devuan:/mnt/memdisk/state-1# time tar --listed-incremental=../snapshot.file -czSf ../tar-full.tar.gz *</b>
<e class=red>tar: tmp/.ICE-unix/19789: socket ignored</e>
<e class=red>tar: tmp/.X11-unix/X0: socket ignored</e>
152.878u 10.155s <e>2:29.38</e> 109.1% 0+0k 1520+0io 18pf+0w
<b>devuan:/mnt/memdisk/state-1# dar -x ~denis/tmp/diff --fsa-scope none -u "*" -w -q</b>
<b>devuan:/mnt/memdisk/state-1# time tar --listed-incremental=../snapshot.file -czSf ../tar-diff.tar.gz *</b>
6.369u 0.752s <e>0:06.55</e> 108.5% 0+0k 3992+0io 16pf+0w
<b>devuan:/mnt/memdisk/state-1# cd ..</b>
<b>devuan:/mnt/memdisk# ls -l tar* snap*</b>
-rw-r--r-- 1 root root <e>3350870</e> Dec 3 17:29 snapshot.file
-rw-r--r-- 1 root root <e>44604194</e> Dec 3 17:29 tar-diff.tar.gz
-rw-r--r-- 1 root root <e>1546226992</e> Dec 3 17:27 tar-full.tar.gz
<b>devuan:/mnt/memdisk# rm -rf DST</b>
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# cd DST</b>
<b>devuan:/mnt/memdisk/DST# time tar -xzSf ../tar-full.tar.gz</b>
27.331u 7.774s <e>0:26.27</e> 133.6% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST# time tar -xzSf ../tar-diff.tar.gz</b>
1.547u 0.487s <e>0:01.50</e> 134.6% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST# time tar -xzSf ../tar-full.tar.gz etc/fstab</b>
25.068u 2.565s <e>0:25.00</e> 110.4% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST#</b>
</code>
<p>
for <i>tar</i> with advanced features (sparse file consideration <code>-S option</code>):
</p>
<ul>
<li>data reduction on storage for the full backup is: 62.16%</li>
<li>data reduction on storage for the diff backup is: 98.92%</li>
<li>data reduction over the network is the same as on storage</li>
<li>execution time to restore a single file is: 25.0 s</li>
<li>execution time to restore the full backup: 26.27 s</li>
<li>execution time ot restore the diff backup: 1.50 s</li>
<li>full backup time: 149.38 s</li>
<li>diff backup time: 6.55 s</li>
</ul>
<h4>Ciphering performance</h4>
<p>
We evaluate here ciphering and deciphering performance. To compare on the same base we use the following
parameters:
<ul>
<li>AES-256 algorithm with CBC mode</li>
<li>pkcs5 v2 (pbkdf2) key derivation function (KDF) algorithm</li>
<li>KDF with 100,000 iterations</li>
<li>salt</li>
<li>password provided on command-line (insecure) to not depend on user or disk access</li>
<li>local system to backup and backup repository on a tmpfs filesystem</li>
<li>swap has been disabled to avoid tmpfs latency in case it would have been swapped out</li>
</ul>
To measure the ciphering time only, we will not use compression, though most of the time compression
should be used due to the use case encryption matches: relatively long time storage and/or costing
cloud space and network transfer time or limited removable media storage.
</p>
<p>
The content that will be backed up is a copy of <code> /usr</code> directory tree. We will measure:
<ul>
<li>the time to backup</li>
<li>the time to restore the whole backup</li>
<li>and the time to restore just the "diff" binary</li>
</ul>
</p>
<code class=block>
<b>devuan:/mnt/memdisk# mkdir SRC</b>
<b>devuan:/mnt/memdisk# cp --preserve -r /usr SRC</b>
<b>devuan:/mnt/memdisk# time dar -c backup -K "aes256:hello world!" --kdf-param 100000:sha1 -R SRC -q -at -1 0</b>
9.213u 3.245s <e>0:05.38</e> 231.4% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# time dar -x backup -K "hello world!" -R DST -q</b>
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
4.481u 2.628s <e>0:03.75</e> 189.3% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# rm -rf DST/usr</b>
<b>devuan:/mnt/memdisk# time dar -x backup -K "hello world!" -R DST -q -g usr/bin/diff</b>
Warning, the archive backup has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted
0.419u 0.025s <e>0:00.42</e> 102.3% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
For <i>dar</i> the operation took:
</p>
<ul>
<li>5.38 seconds to backup with encryption</li>
<li>3.75 seconds to restore the whole ciphered backup</li>
<li>0.42 seconds to restore a single file from the ciphered backup</li>
</ul>
<p>
<i>dar</i> is twice quicker to uncipher than to cipher the whole archive, but restoring a particular file is quite immediate.
By default, <i>dar</i> uses argon2 for KDF, which is the most secure algorithm as of year 2020 to derive a key, but we had to
adapt to openssl used with <i>tar</i> that does not (yet) support this algorithm.
</p>
<p>
To avoid plain-text attack a variable length elastic buffer containing random data is encrypted with the rest of the backed up files
at the beginning and at the end of the backup, this has some performance penalties (time to generate and time to cipher/decipher).
This explains why two identical invocations of <i>dar</i> produce backups of different sizes and execution times:
</p>
<code class=block>
<b>devuan:/mnt/memdisk# time dar -c backup -K "aes256:hello world!" -at -1 0 -R SRC -q -w</b>
9.782u 3.413s <e>0:06.28</e> 210.0% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# la backup.1.dar</b>
-rw-r--r-- 1 root root 1572<e>706497</e> Nov 9 14:50 backup.1.dar
<b>devuan:/mnt/memdisk# time dar -c backup -K "aes256:hello world!" -at -1 0 -R SRC -q -w</b>
9.173u 2.845s <e>0:05.50</e> 218.3% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk# la backup.1.dar</b>
-rw-r--r-- 1 root root 1572<e>655217</e> Nov 9 14:50 backup.1.dar
<b>devuan:/mnt/memdisk#</b>
</code>
<p>
<i>rsync</i> has no way to store the backup ciphered. Testing directly <i>tar</i> now:
</p>
<p>
<i>tar</i> has not support for ciphering. Though it seems the some use openssl workaround
this restriction. To measure the execution time we have to create as script that pipes <i>tar</i>
and <i>openssl</i> so we can measure the execution time of this script as a whole. There is thus one
script for backup and one for the restoration of <i>tar</i>+<i>openssl</i>.
</p>
<code class=block>
<b>devuan:/mnt/memdisk# cat > tar.backup</b>
#!/bin/bash
if [ -z "$1" ] ; then
echo "usage: $0 <backup name> [ <file or dir> ]"
exit 1
fi
tar -cf - "$2" | openssl enc -e -aes256 -out "$1" -pbkdf2 -iter 100000 -salt -pass pass:"hello world!"
<b>devuan:/mnt/memdisk#</b>
<b>devuan:/mnt/memdisk# chmod u+x tar.backup</b>
<b>devuan:/mnt/memdisk# cd SRC</b>
<b>devuan:/mnt/memdisk/SRC# time ../tar.backup ../backup.tar.crypted usr</b>
3.954u 2.498s <e>0:04.69</e> 137.3% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/SRC# cd ..</b>
<b>devuan:/mnt/memdisk# ls -l backup.tar.crypted</b>
-rw-r--r-- 1 root root 1603594272 Nov 9 13:33 backup.tar.crypted
<b>devuan:/mnt/memdisk#</b>
<b>devuan:/mnt/memdisk# cat > tar.restore</b>
#!/bin/bash
if [ -z "$1" ] ; then
echo "usage: $0 <tar.crypted file> [<file or dir>]"
exit 1
fi
openssl enc -d -aes256 -in "$1" -pbkdf2 -iter 100000 -salt -pass pass:"hello world!" | tar -x "$2"
<b>devuan:/mnt/memdisk# chmod u+x tar.restore</b>
<b>devuan:/mnt/memdisk# rm -rf DST</b>
<b>devuan:/mnt/memdisk# mkdir DST</b>
<b>devuan:/mnt/memdisk# cd DST</b>
<b>devuan:/mnt/memdisk/DST# time ../tar.restore ../backup.tar.crypted</b>
1.807u 2.821s <e>0:02.70</e> 171.1% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST#</b>
<b>devuan:/mnt/memdisk/DST# rm -rf usr</b>
<b>devuan:/mnt/memdisk/DST# time ../tar.restore ../backup.tar.crypted usr/bin/diff</b>
1.336u 1.428s <e>0:01.79</e> 153.6% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/DST# find</b>
.
./usr
./usr/bin
./usr/bin/diff
<b>devuan:/mnt/memdisk/DST#</b>
</code>
<p>
For <i>tar</i> the operation took:
</p>
<ul>
<li>4.69 seconds for backup</li>
<li>2.70 seconds to restore the whole backup</li>
<li>1.79 seconds to restore a single file</li>
</ul>
<p>
<i>tar</i> as <i>dar</i> is also twice longer to cipher than to decipher, this seems to be related to the algorithm itself.
Though <i>tar</i> is a bit faster than <i>dar</i> but lacks protection against clear-text: the generated encrypted backup
have the exact same sizes at one byte precision, this means the blocks boundaries and tar file internal structure always
lay at the same file offset for a given content:
</p>
<code class=block>
<b>devuan:/mnt/memdisk/SRC# time ../tar.backup ../backup.tar.crypted usr</b>
4.112u 2.343s 0:04.72 136.6% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/SRC# ls -l ../bac</b>
backup.1.dar backup.tar.crypted
<b>devuan:/mnt/memdisk/SRC# ls -l ../backup.tar.crypted</b>
-rw-r--r-- 1 root root <e>1603594272</e> Nov 9 14:56 ../backup.tar.crypted
<b>devuan:/mnt/memdisk/SRC# time ../tar.backup ../backup.tar.crypted usr</b>
3.952u 2.564s 0:04.79 135.9% 0+0k 0+0io 0pf+0w
<b>devuan:/mnt/memdisk/SRC# ls -l ../backup.tar.crypted</b>
-rw-r--r-- 1 root root <e>1603594272</e> Nov 9 14:56 ../backup.tar.crypted
<b>devuan:/mnt/memdisk/SRC#</b>
</code>
<h2><a name="scripts">Scripts</a> used in this benchmark</h2>
<p>
The following scripts are also available for download
from the <a href="Benchmark_tools"> directory</a>
</p>
<h3><a name="historization_feature"><i>historization_feature</i></a> script</h3>
<code class=block>
#!/bin/bash
if [ -z "$1" -o -z "$2" ] ; then
echo "usage: $0 <dir> {phase1 | phase2}"
exit 1
fi
dir="$1"
phase="$2"
case "$phase" in
phase1)
if [ -e "$dir" ] ; then
echo "$dir exists, remove it first"
exit 2
fi
mkdir "$dir"
echo "Hello World!" > "$dir/A.txt"
echo "Bonjour tout le monde !" > "$dir/B.txt"
;;
phase2)
if [ ! -d "$dir" ] ; then
echo "$dir does not exist or is not a directory, run phase1 first"
exit 2
fi
rm -f "$dir/A.txt"
echo "Buongiorno a tutti !" > "$dir/C.txt"
;;
*)
echo "unknown phase"
exit 2
;;
esac
</code>
<h3><a name="always_change"><i>always_change</i></a> script</h3>
<code class=block>
#!/bin/bash
if [ -z "$1" ] ; then
echo "usage: $0 <filename>"
exit 1
fi
while /bin/true ; do touch "$1" ; done
</code>
<h3><a name="bitflip"><i>bitflip</i></a> script</h3>
<code class=block>
#!/bin/bash
if [ -z "$1" -o -z "$2" ] ; then
echo "usage: $0 <offset in bit> <file>"
echo "flip the bit of the file located at the provided offset"
exit 1
fi
offbit=$1
file="$2"
offbyte=$(( $offbit / 8 ))
bitinbyte=$(( $offbit - ($offbyte * 8) ))
readbyte=`xxd -s $offbyte -p -l 1 "$file"`
mask=$(( 1 << $bitinbyte ))
newbyte=$(( 0x$readbyte ^ $mask ))
hexanewbyte=`printf "%.2x" $newbyte`
echo $hexanewbyte | xxd -p -l 1 -s $offbyte -r - "$file"
</code>
<h3><a name="build_test_tree.bash"><i>build_test_tree.bash</i></a> script</h3>
<code class=block>
#!/bin/bash
if [ -z "$1" ] ; then
echo "usage: $0 <directory>"
exit 1
fi
if [ -e "$1" ] ; then
echo "$1 already exists, remove it or use another directory name"
exit 1
fi
if ! dar -V > /dev/null ; then
echo "need dar to copy unix socket to the test tree"
exit 1
fi
mkdir "$1"
cd "$1"
# creating
mkdir "SUB"
dd if=/dev/zero of=plain_zeroed bs=1024 count=1024
dd if=/dev/urandom of=random bs=1024 count=1024
dd if=/dev/zero of=sparse_file bs=1 count=1 seek=10239999
ln -s random SUB/symlink-broken
ln -s ../random SUB/symlink-valid
mkfifo pipe
mknod null c 3 1
mknod fd1 b 2 1
dar -c - -R / -g dev/log -N -Q -q | dar -x - --sequential-read -N -q -Q
ln sparse_file SUB/hard_linked_sparse_file
ln dev/log SUB/hard_linked_socket
ln pipe SUB/hard_linked_pipe
# modifying dates and permissions
sleep 2
chown nobody random
chown -h bin SUB/symlink-valid
chgrp -h daemon SUB/symlink-valid
sleep 2
echo hello >> random
sleep 2
cat < random > /dev/null
# adding Extend Attributes, assuming the filesystem as user_xattr and acl option set
setfacl -m u:nobody:rwx plain_zeroed && setfattr -n "user.hello" -v "hello world!!!" plain_zeroed || (echo "FAILED TO CREATE EXTENDED ATTRIBUTES" && exit 1)
# adding filesystem specific attributes
chattr +dis plain_zeroed
</code>
<h3><a name="hide_change"><i>hide_change</i></a> script</h3>
<code class=block>
#!/bin/bash
if [ -z "$1" ] ; then
echo "usage: $0 <filename> [<bit offset>]"
echo "modify one bit and hide the change"
exit 1
fi
atime=`stat "$1" | sed -rn -s 's/^Access:\s+(.*)\+.*/\1/p'`
mtime=`stat "$1" | sed -rn -s 's/^Modify:\s+(.*)\+.*/\1/p'`
bitoffset="$2"
if [ -z "$bitoffset" ] ; then
bitoffset=2
fi
./bitflip "$bitoffset" "$1"
touch -d "$mtime" "$1"
touch -a -d "$atime" "$1"
</code>
</body>
</html>
|