ddr_lzo(1) LZO de/compression plugin for dd_rescue ddr_lzo(1)

ddr_lzo - افزونه فشرده‌سازی و بازگشایی داده برای dd_rescue

-L lzo[=option[:option[:...]]]
یا
-L /path/to/libddr_lzo.so[=option[:option[:...]]]

الگوریتم LZO داده‌ها را فشرده/بازگشایی می‌کند. این الگوریتم برای سرعت (به‌ویژه سرعت بازگشایی) بهینه‌سازی شده است و تا حدی اندازه فایل فشرده را فدای سرعت می‌کند. با این حال گونه‌هایی با فشرده‌سازی کند (اما همچنان بازگشایی بسیار سریع) نیز در دسترس هستند. پارامتر algorithm را در زیر ببینید.

این افزونه برای dd_rescue نوشته شده است و از رابط افزونه آن استفاده می‌کند. برای اطلاعات بیشتر درباره dd_rescue به صفحه راهنمای dd_rescue(1) مراجعه کنید.

گزینه‌ها با استفاده از نحو ارسال گزینه‌های dd_rescue ارسال می‌شوند: نام افزونه (lzo) می‌تواند به‌طور اختیاری با یک علامت مساوی (=) همراه شود و گزینه‌ها با علامت دونقطه (:) از یکدیگر جدا می‌شوند. همچنین افزونه lzo امکان خلاصه کردن اکثر گزینه‌ها به پنج یا شش حرف را می‌دهد. بخش «مثال‌ها» در زیر را ببینید.

افزونه lzo برای dd_rescue (که در ادامه صرفاً ddr_lzo نامیده می‌شود و نمایانگر بخش‌های متغیر نام فایل libddr_lzo.so است)، در صورتی که یکی از فایل‌های ورودی/خروجی دارای پسوند [lt]zo باشد، حالت فشرده‌سازی یا بازگشایی را به‌طور خودکار انتخاب می‌کند؛ در غیر این صورت می‌توانید پارامترهای compr[ess] یا decom[press] را در خط فرمان مشخص کنید.
پارامتر opt[imize] به ddr_lzo اعلام می‌کند که پس از فشرده‌سازی یک مرحله بهینه‌سازی انجام دهد. این عمل ممکن است هنگام ایجاد داده‌های فشرده با سطوح فشرده‌سازی بالا و اندازه‌های بلوک بزرگ، سرعت بازگشایی را چند درصد افزایش دهد.

این افزونه همچنین از پارامتر bench[mark] پشتیبانی می‌کند؛ در صورت تعیین شدن، اطلاعاتی را درباره میزان مصرف پردازنده (CPU) و پهنای باند فشرده‌سازی یا بازگشایی حاصل ارائه می‌دهد. (برای فایل‌های کوچک، این اعداد به دلیل نوسانات و وضوح زمانی محدود بی‌معنی می‌شوند -- در صورتی که اعداد بسیار کوچک باشند، ddr_lzo از نمایش خروجی صرف‌نظر می‌کند.)

افزونه lzo از تعدادی از الگوریتم‌های فشرده‌سازی/بازگشایی کتابخانه liblzo2 پشتیبانی می‌کند. می‌توانید با ارسال algo=XXX، که در آن XXX می‌تواند lzo1x_1،‏ lzo1x_1_15،‏ lzo1x_999،‏ lzo1x_1_11،‏ lzo1x_1_12،‏ lzo1y_1،‏ lzo1y_999،‏ lzo1f_1،‏ lzo1f_999،‏ lzo1b_1 ... lzo1b_9،‏ lzo1b_99،‏ lzo1b_999 یا lzo2a_999 باشد، مشخص کنید که از کدام‌یک می‌خواهید استفاده کنید. برای دریافت فهرستی از الگوریتم‌های موجود، algo=help را ارسال کنید. برای اطلاعات بیشتر درباره الگوریتم‌ها به مستندات liblzo مراجعه نمایید. توجه داشته باشید که تنها سه مورد اول توسط lzop پشتیبانی می‌شوند (البته می‌تواند پنج مورد اول را بازگشایی کند، زیرا همگی توسط یک روتین بازگشایی یکسان مدیریت می‌شوند).
مقدار پیش‌فرض (lzo1x_1) انتخابی مناسب برای فشرده‌سازی سریع و بازگشایی بسیار سریع است و سازگاری با lzop را تضمین می‌کند. برای فشرده‌سازی بالاتر شاید بخواهید lzo1x_999 را انتخاب کنید که بسیار کند است اما با lzop سازگاری دارد، یا lzo2a_999 که دو برابر سریع‌تر است، اما با lzop سازگار نیست. توجه داشته باشید که اگر به دنبال فشرده‌سازی مناسب هستید، بهتر است از سایر الگوریتم‌های فشرده‌سازی (مانند lzma با یک پیش‌تنظیم پایین) استفاده کنید؛ از این رو به‌ندرت دلیلی برای تغییر الگوریتم پیش‌فرض وجود دارد، زیرا با LZO تنها در ازای مصرف بسیار بیشتر پردازنده و حافظه، بهبودهای ناچیزی به دست خواهید آورد.

پرچم debug باعث می‌شود ddr_lzo اطلاعاتی درباره بلوک‌ها و سایر داده‌های داخلی چاپ کند. این پرچم برای مقاصد اشکال‌زدایی در نظر گرفته شده است.

در نهایت پارامتر flags=XXXX نیز وجود دارد. این پارامتر فیلد پرچم‌ها را در سرآیند تنظیم می‌کند (پیش‌فرض 0x03000403 است) و صرفاً برای آزمایش کاربرد دارد. این مقدار اعتبارسنجی نمی‌شود و شما می‌توانید به‌راحتی مقادیری تعیین کنید که بازگشایی را مختل کند یا سبب خروج غیرعادی ddr_lzo شود. واقعاً فقط در صورت اهداف توسعه و هنگامی که از مفهوم بیت‌های مختلف آگاهید از آن استفاده نمایید.

در زمان فشرده‌سازی، اگر بایت‌های ورودی قابل خواندن نباشند، ddr_lzo حفره‌ها را در فایل خروجی فشرده کدگذاری می‌کند -- در هنگام بازگشایی از روی این حفره‌ها پرش صورت خواهد گرفت.

در زمان بازگشایی، بلوک‌های دارای خطا را می‌توان توسط جمع‌های کنترلی (اغلب اوقات) یا توسط بازگشایی‌کننده تشخیص داد. در این صورت، اگر سرآیند بلوک که طول‌های فشرده/بازگشایی‌شده را مشخص می‌کند سالم باشد، افزونه lzo تلاش می‌کند به کار خود ادامه دهد. این امر موجب رد شدن از روی یک بلوک (ایجاد حفره) شده و بازگشایی با بلوک بعدی ادامه می‌یابد. این کار مانع از وارد شدن داده‌های خراب به فایل خروجی (یا بازنویسی داده‌های سالم قبلی که احتمالاً در آنجا وجود داشته‌اند) می‌شود.
این رفتار را می‌توان با مشخص کردن گزینه nodisc[ard] تغییر داد. با تعیین این گزینه، خروجی بازگشایی‌کننده (که در صورت کوتاه‌تر بودن از بلوک با صفر پر می‌شود) در فایل خروجی نوشته خواهد شد. حتی اگر بدانیم داده‌ها نادرست هستند، با کمی شانس ممکن است بخش‌هایی از بلوک واقعاً معتبر باشند.

هنگامی که سرآیندهای بلوک خراب شوند، وضعیت بحرانی خواهد بود چرا که باقیمانده فایل را از دست خواهید داد. برای بازیابی تکه‌ها پس از چنین خرابی در سرآیند بلوک، ddr_lzo از گزینه search پشتیبانی می‌کند. با این گزینه، افزونه فایل ورودی را (با شروع از موقعیت تعیین‌شده در dd_rescue با گزینه -s) برای یافتن داده‌هایی که شبیه سرآیند بلوک هستند جستجو می‌کند و اگر سرآیندی با ظاهر معتبر پیدا شود، بازگشایی را از آن موقعیت آغاز خواهد کرد. (اگر نتوانستید داده‌های مورد نظرتان را پیدا کنید، می‌توانید خروجی تولیدشده با پرچم debug را بررسی کنید.)

دستور dd_rescue با گزینه -x/--extend از الحاق داده‌ها به فایل‌ها پشتیبانی می‌کند. اگر ddr_lzo بارگذاری شده باشد و فایل خروجی یک فایل .lzo موجود باشد، داده‌های جدید با قالبی که توسط سرآیند LZOP موجود تعیین شده است الحاق می‌شوند. اگر سرآیند نشان‌دهنده یک فایل چندبخشی (آرشیو) نباشد، نشانگر EOF بازنویسی می‌شود تا یک فایل .lzo معتبر ساخته شود. در غیر این صورت بخش جدیدی الحاق خواهد شد.

هنگامی که dd_rescue نتواند داده‌ای را بخواند یا حجم قابل توجهی از داده‌های پر شده با صفر پیدا شود و گزینه -a/--sparse فعال باشد، dd_rescue فایل‌های تنک (sparse files؛ فایل‌های دارای حفره) ایجاد خواهد کرد. این بهینه‌سازی برای صرفه‌جویی در فضا است -- حفره‌ها هنگام خواندن عادی دوباره به صورت صفر تفسیر می‌شوند، بنابراین این فرایند شفاف است. همچنین وجود حفره‌ها می‌تواند برای اطمینان از این که در صورت عدم امکان خواندن داده‌ها، داده‌های سالم با صفر بازنویسی نمی‌شوند مفید باشد.
هنگامی که در حالت فشرده‌سازی حفره‌ها به پودمان lzo فرستاده می‌شوند، آن‌ها را به شیوه‌ای خاص در فایل خروجی فشرده کدگذاری می‌کند (با استفاده از ویژگی multipart در lzop، زیرا متأسفانه lzop هنگام برخورد با بلوک‌هایی با طول فشرده‌شده ۰ دچار اختلال می‌شود). در زمان بازگشایی، حفره‌ها دوباره باعث پرش از روی داده‌ها می‌شوند (در صورتی که هیچ داده‌ای از قبل در آن مکان وجود نداشته باشد، حفره‌ای در فایل خروجی ایجاد می‌شود).

این افزونه به‌طور پیش‌فرض از الگوریتم lzo1x_1 استفاده می‌کند (دقیقاً مانند رفتار پیش‌فرض lzop) و جمع‌های کنترلی adler32 ایجاد می‌کند تا امکان تشخیص خرابی داده‌ها فراهم شود. فایل‌های فشرده با lzop سازگار هستند و ddr_lzo باید بتواند فایل‌های ایجادشده توسط lzop را مدیریت کند.
فایل‌های چندبخشی (آرشیو) حاصل از lzop به همان ترتیبی که ذخیره شده‌اند، در یک (ONE) فایل خروجی بازگشایی می‌شوند.
فایل‌های چندبخشی ایجادشده توسط افزونه lzo جهت کدگذاری حفره‌ها، توسط lzop در چندین فایل استخراج خواهند شد. حفره‌ها در نام فایل‌ها کدگذاری می‌شوند (با شماره ترتیب و اندازه حفره تا 1TB؛ برای حفره‌های بسیار بزرگ از برچسب زمان استفاده می‌شود)، بنابراین سرهم‌بندی درست قطعات حتی بدون ddr_lzo نیز امکان‌پذیر است.

ابزار lzop تنها از خانواده الگوریتم‌های lzo1x_ پشتیبانی می‌کند. اگر الگوریتم دیگری را برای فشرده‌سازی داده‌ها با ddr_lzo برگزینید، فیلد needed_version_to_extract در فایل lzop حاصل را روی نسخه خودِ ddr_lzo (یعنی 1.789) تنظیم می‌کند تا ناسازگاری با lzop (تا نسخه 1.03) را نشان دهد.
ابزار lzop به‌طور پیش‌فرض از اندازه بلوک 256kiB (در سیستم‌های یونیکس) استفاده می‌کند، اما از فشرده‌سازی/بازگشایی با اندازه‌های بلوک کوچک‌تر نیز پشتیبانی می‌کند. برای پشتیبانی از اندازه‌های بلوک تا حداکثر مقدار ممکن 64MiB نیاز به کامپایل مجدد دارد. بنابراین ماندن در اندازه 256kiB یا کمتر توصیه می‌شود؛ حتی زمانی که سازگاری با lzop مد نظر نباشد، بلوک‌های بزرگ‌تر از 16MiB توصیه نمی‌شوند، به بخش زیر مراجعه کنید.

در زمان بازگشایی، اندازه بلوک (نرم‌افزاری) انتخاب‌شده در dd_rescue باید کافی باشد (حداقل نصف اندازه بلوک مورد استفاده در زمان فشرده‌سازی)؛ اگر بلوک‌های بیش از حد کوچک انتخاب کنید، ddr_lzo هشدار داده و خارج می‌شود.
برای فشرده‌سازی، اندازه بلوک (نرم‌افزاری) انتخاب‌شده در dd_rescue اندازه بلوک‌هایی را که باید به توابع ()lzo??_?_compress داده شوند مشخص می‌کند. اندازه‌های بلوک بزرگ‌تر معمولاً به نسبت‌های فشرده‌سازی کمی بهتر می‌انجامند، هرچند مزایای افزایش اندازه بلوک بعد از 64k به‌سرعت کاهش می‌یابد.
مقدار پیش‌فرض dd_rescue (یعنی 128kiB) انتخابی مناسب است. افزایش بیش از حد اندازه بلوک اصلاً توصیه نمی‌شود -- وقتی یک فایل lzo خراب شود، حداقل یک بلوک از دست می‌رود؛ بلوک‌های بزرگ‌تر خسارت بزرگ‌تری به بار می‌آورند. همچنین بلوک‌های بزرگ‌تر از 16MiB با قابلیت‌های تحمل خطای ddr_lzo به خوبی کار نخواهند کرد. به علاوه توجه داشته باشید که اگر می‌خواهید بتوانید از lzop برای پردازش فایل‌های .lzo استفاده کنید، بلوک‌های بزرگ‌تر از 256kiB نیاز به کامپایل مجدد lzop دارند؛ و بلوک‌های بزرگ‌تر از 64MiB حتی با lzop کامپایل مجدد شده نیز مانع از بازگشایی می‌شوند.

این افزونه از نگارش 1.43 در dd_rescue جدید است. هنوز به داده‌های ذخیره‌شده با ddr_lzo به عنوان تنها نسخه پشتیبان از داده‌های ارزشمند اتکا نکنید. همچنین در آینده‌ای نه چندان دور انتظار تغییراتی در ddr_lzo را داشته باشید. (این موضوع نباید قالب فایل را بشکند، چرا که ما از lzop پیروی می‌کنیم...).
داده‌های فشرده نسبت به داده‌های ساده به خرابی داده حساس‌تر هستند. توجه داشته باشید که جمع‌های کنترلی (adler32 یا crc32) در قالب فایل lzop امکان تصحیح خطاها را فراهم نمی‌کنند؛ آن‌ها صرفاً تشخیص نسبتاً مطمئنی از خرابی داده را امکان‌پذیر می‌سازند. (در حالت ایده‌آل، یک جمع کنترلی ۳۲ بیتی تنها ۱ مورد از ۲^۳۲ خرابی را از دست می‌دهد؛ در تغییرات کوچک، crc32 کمی بیشتر از adler32 به حالت ایده‌آل نزدیک می‌شود. می‌توانید گزینه crc32 را ارسال کنید تا به جای جمع‌های کنترلی adler32 از crc32 به بهای مقداری کاهش سرعت استفاده شود -- متأسفانه چندجمله‌ای crc32 برای .../lzop/gzip همان چندجمله‌ای crc32c نیست که امروزه روی بسیاری از پردازنده‌ها پشتیبانی سخت‌افزاری دارد.) همچنین توجه داشته باشید که جمع‌های کنترلی، هش‌های رمزنگاری نیستند؛ یک مهاجم مخرب به‌راحتی می‌تواند تغییراتی در داده‌ها بیابد که جمع‌های کنترلی را تغییر ندهند. برای اطمینان از یکپارچگی در برابر مهاجمان، از MD5 یا ترجیحاً SHA-256/SHA-512 استفاده کنید. اگر می‌خواهید در صورت خرابی قادر به بازیابی داده‌ها باشید، از par2 یا نرم‌افزارهای مشابه برای ایجاد کدهای تصحیح خطا (Reed-Solomon / Erasure Codes) بهره ببرید.

اگرچه برای بررسی نتیجه تخصیص‌های حافظه و موارد مشابه دقت لازم صورت گرفته است، اما کد بازگشایی‌کننده ممیزی نشده و تنها آزمون‌های فازی (fuzzing) محدودی برای اطمینان از آسیب‌پذیر نبودن آن در برابر داده‌های مخرب انجام شده است -- در هنگام پردازش داده‌ها از منابع غیرقابل اعتماد احتیاط کنید.

داده‌ها را از infile در outfile با استفاده از الگوریتم lzo1x_1_15 فشرده می‌کند و مقدار هش sha256 فایل outfile را محاسبه می‌نماید. برچسب زمان و حقوق دسترسی outfile از infile رونویسی می‌شوند و در صورت وجود، ابتدا خالی خواهد شد. فایل خروجی حفره‌های کدگذاری‌شده نخواهد داشت؛ خطاهای موجود در infile منجر به ایجاد صفر خواهند شد.
فایل infile را در infile2 رونویسی می‌کند و در حین کار، داده‌ها را فشرده کرده و دوباره بازگشایی می‌نماید. این دستور همچنین مقادیر هش MD5 را برای داده‌های فشرده (هرچند ذخیره نمی‌شوند) و برای دو فایل ورودی چاپ می‌کند -- طبیعتاً خروجی‌ها باید یکسان باشند. این دستور نسبتاً تصنعی بوده و برای آزمایش استفاده می‌شود. پرچم -a باعث می‌شود dd_rescue بلوک‌های صفر را تشخیص داده و حفره ایجاد کند، بنابراین در صورتی که infile دارای نواحی بزرگی پر از صفر باشد، کدگذاری حفره (فایل‌های تنک) و بازگشایی آن را نیز می‌آزماید.
در فایل infile.lzo با شروع از موقعیت 1MiB به بعد، به دنبال یک سرآیند بلوک lzop می‌گردد و باقیمانده فایل را بازگشایی می‌کند. در صورت یافتن بلوک‌های معیوب، همچنان خروجی حاصل از بازگشایی‌کننده را در outfile خواهد نوشت.

dd_rescue(1) liblzo2 documentation lzop(1)

Kurt Garloff <kurt@garloff.de>

کتابخانه و الگوریتم liblzo2 توسط Markus Oberhumer نوشته شده است.
http://www.oberhumer.com/opensource/lzo

این افزونه تحت همان مجوز dd_rescue ارائه شده است: مجوز عمومی همگانی گنو (GPL) نگارش ۲ یا ۳ - به انتخاب شما.

افزونه ddr_lzo نخستین بار همراه با dd_rescue 1.43 (مه ۲۰۱۴) معرفی شد.

اطلاعات تکمیلی را می‌توانید در نشانی زیر بیابید:
http://garloff.de/kurt/linux/ddrescue

2014-05-12 Kurt Garloff