| SG_WRITE_SAME(8) | SG3_UTILS | SG_WRITE_SAME(8) |
نام (NAME)
sg_write_same - ارسال دستور SCSI WRITE SAME
خلاصه دستور (SYNOPSIS)
sg_write_same [--10] [--16] [--32] [--anchor] [--ff] [--grpnum=GN] [--help] [--in=IF] [--lba=LBA] [--lbdata] [--num=NUM] [--ndob] [--pbdata] [--timeout=TO] [--unmap] [--verbose] [--version] [--wrprotect=WPR] [--xferlen=LEN] DEVICE
توضیحات (DESCRIPTION)
دستور SCSI WRITE SAME (۱۰، ۱۶ یا ۳۲ بایتی) را به DEVICE ارسال میکند. این دستور بلوک داده مشخصشده را به تعداد NUM بار در بلوکهای متوالی روی DEVICE با شروع از آدرس بلوک منطقی LBA مینویسد.
طول بلوکی که قرار است چندین بار نوشته شود از آرگومان LEN، یا طول فایل ورودی دادهشده IF، یا با فراخوانی دستور READ CAPACITY(16) روی DEVICE به دست میآید. محتویات بلوکی که باید نوشته شود از فایل ورودی IF گرفته میشود یا از صفرها استفاده میشود. اگر READ CAPACITY(16) فراخوانی شود (که به معنی عدم ارائه IF است) و بیت PROT_EN تنظیم شده باشد، ۸ بایت اضافه (یعنی بیشتر از اندازه بلوک منطقی) از مقدار 0xff ارسال میشود. اگر READ CAPACITY(16) با شکست مواجه شود، از READ CAPACITY(10) برای تعیین اندازه بلوک استفاده خواهد شد.
اگر هیچیک از گزینههای --10، --16 یا --32 داده نشود، دستور WRITE SAME(10) ارسال میشود مگر اینکه یکی از شرایط زیر برقرار باشد: اگر LBA (به اضافه NUM) از ۳۲ بیت فراتر رود، NUM از ۶۵۵۳۵ بیشتر باشد، یا گزینه --unmap مشخص شده باشد، در این صورت WRITE SAME(16) ارسال میشود. گزینههای --10، --16 و --32 مانعةالجمع هستند.
در بازنگری 35d از استاندارد SBC-3، بیت «بدون بافر داده خروجی» (No Data-Out Buffer یا NDOB) معرفی شد که در صورت تنظیم، نیاز به ارسال یک بلوک داده تک به DEVICE همراه با دستور را برطرف میکند. تنها دستورات WRITE SAME (۱۶ و ۳۲ بایتی) از بیت NDOB پشتیبانی میکنند. در صورت تعیین این گزینه، یک بلوک کاربری پر از صفر فرض میشود؛ و در صورت نیاز، اطلاعات حفاظتی پر از 0xff فرض میگردد.
در بازنگری ۲۶ از SBC-3، بیتهای UNMAP و ANCHOR به دستور WRITE SAME (10) اضافه شدند. از آنجا که بیت UNMAP از زمان بازنگری ۱۸ از SBC-3 در دستورات WRITE SAME (16) و WRITE SAME (32) وجود داشته است، هنگام ارائه گزینه --unmap، نسخه کمتر از این دو (یعنی WRITE SAME (16)) به عنوان پیشفرض ارسال میشود. برای ارسال WRITE SAME (10) از گزینه --10 استفاده کنید.
دقت فرمایید: دستورات WRITE SAME(10, 16 and 32) ممکن است مقدار NUM برابر صفر را به عنوان نوشتن تا پایان DEVICE تفسیر کنند. این ابزار مقدار پیشفرض NUM را 1 قرار میدهد. دستورات WRITE SAME بیت IMMED ندارند، بنابراین اگر NUM بزرگ (یا صفر) باشد، اجرای این ابزار ممکن است زمان بسیار زیادی طول بکشد، احتمالاً به اندازه یک دستور FORMAT UNIT. در چنین شرایطی ممکن است لازم باشد مقدار زمانبندی دستور TO از مقدار پیشفرض ۶۰ ثانیه افزایش یابد. در بازنگری ۲۶ استاندارد SBC-3 بیت WSNZ (بیت write same no zero) به صفحه VPD حدود بلوک [0xB0] اضافه شد. در صورت تنظیم بودن این بیت، دستورات WRITE SAME مقدار NUM برابر صفر را نخواهند پذیرفت. همین بازنگری SBC-3 فیلد "Maximum Write Same Length" را نیز به صفحه VPD حدود بلوک اضافه کرد.
صفحه VPD تامین بلوک منطقی (Logical Block Provisioning با کد 0xB2) شامل بیتهای LBPWS و LBPWS10 است. اگر LBPWS تنظیم شده باشد، دستور WRITE SAME (16) از بیت UNMAP پشتیبانی میکند. اگر LBPWS10 تنظیم شده باشد، دستور WRITE SAME (10) از بیت UNMAP پشتیبانی میکند. اگر هر یک از LBPWS یا LBPWS10 تنظیم شده باشند و از WRITE SAME (32) پشتیبانی شود، آنگاه WRITE SAME (32) از بیت UNMAP پشتیبانی میکند.
به عنوان یک اقدام احتیاطی در برابر اجرای تصادفی مانند 'sg_write_same /dev/sda' که LBA 0 را روی /dev/sda با صفر بازنویسی میکند، دستکم یکی از گزینههای --in=IF، --lba=LBA یا --num=NUM باید مشخص شود. بدیهی است که این ابزار میتواند حجم زیادی از دادههای کاربر را نابود کند، بنابراین گزینهها را با دقت بررسی کنید.
گزینهها (OPTIONS)
آرگومانهای گزینههای طولانی برای گزینههای کوتاه نیز اجباری هستند. گزینهها بر اساس حروف الفبای نام گزینه طولانی مرتب شدهاند.
- -R, --10
- ارسال دستور SCSI WRITE SAME (10) به DEVICE. امکان تنظیم گزینههای --unmap (و --anchor) برای این دستور در بازنگری ۲۶ استاندارد SBC-3 افزوده شد.
- -S, --16
- ارسال دستور SCSI WRITE SAME (16) به DEVICE.
- -T, --32
- ارسال دستور SCSI WRITE SAME (32) به DEVICE.
- -a, --anchor
- تنظیم بیت ANCHOR در cdb. این قابلیت در بازنگری ۲۲ از SBC-3 معرفی شد. آن پیشنویس الزامی میکند که گزینه --unmap نیز مشخص شود.
- -f, --ff
- هنگام مشخص شدن این گزینه، بافر داده خروجی (data-out) ارسالی با این دستور با بایتهای 0xff مقداردهی اولیه میشود.
- -g, --grpnum=GN
- فیلد 'Group number' را روی GN تنظیم میکند. مقدار پیشفرض صفر است. GN باید مقداری بین 0 تا 63 باشد.
- -h, --help
- نمایش پیام راهنمای نحوه استفاده و سپس خروج.
- -i, --in=IF
- خواندن دادهها (باینری) از فایلی به نام IF و استفاده از آن به عنوان بافر data-out برای دستور SCSI WRITE SAME. طول بافر داده خروجی برابر با --xferlen=LEN است یا اگر آن گزینه داده نشده باشد، برابر با طول فایل IF خواهد بود. اگر IF برابر "-" باشد، دادهها از ورودی استاندارد (stdin) خوانده میشوند. اگر این گزینه و گزینه --ff داده نشده باشند، از بایتهای 0x00 به عنوان پرکننده استفاده میشود و طول بافر data-out از --xferlen=LEN یا با فراخوانی READ CAPACITY(16 or 10) به دست میآید. اگر پاسخ به READ CAPACITY(16) دارای بیت تنظیمشده PROT_EN باشد، اندازه بافر data-out متناسب با آن تغییر یافته و ۸ بایت آخر با 0xff تنظیم میشود.
- -l, --lba=LBA
- که در آن LBA آدرس بلوک منطقی برای شروع دستور WRITE SAME است. مقدار پیشفرض lba 0 است که بازنویسی آن روی دیسکی که در حال استفاده است بلوک خطرناکی محسوب میشود. فرض میشود مقدار در مبنای ده است مگر اینکه با '0x' شروع شود یا پسوند 'h' داشته باشد.
- -L, --lbdata
- بیت LBDATA را در cdb دستور WRITE SAME تنظیم میکند. این بیت در sbc3r32 در سپتامبر ۲۰۱۲ منسوخ شد.
- -N, --ndob
- بیت NDOB را در
دستورات WRITE SAME
(۱۶ و ۳۲
بایتی)
تنظیم
میکند. NDOB
مخفف No Data-Out Buffer
است. مقدار
پیشفرض
پاک بودن
این بیت
است. هنگامی
که این
گزینه مشخص
شود،
استفاده از
--in=IF مجاز
نیست و --xferlen=LEN
تنها در
صورتی مجاز
است که LEN
برابر 0
باشد.
بهطور پیشفرض در هر بلوک صفر نوشته میشود، اما بسته به سایر تنظیمات این احتمال وجود دارد که «الگوی مقداردهی اولیه تدارک» (provisioning initialization pattern) نوشته شود. - -n, --num=NUM
- که در آن NUM
تعداد
بلوکهایی
است که از LBA
شروع شده و
بافر data-out روی
آنها
نوشته
میشود.
مقدار
پیشفرض
برای NUM
برابر 1 است.
این مقدار
متناظر با
فیلد 'Number of logical blocks'
در cdb دستور WRITE SAME
است.
توجه داشته باشید که مقدار 0 در NUM ممکن است به صورت نوشتن بافر data-out روی تمام بلوکها از LBA تا انتهای DEVICE تفسیر شود. اگر بیت WSNZ (معرفیشده در sbc3r26، ژانویه ۲۰۱۱) در صفحه VPD حدود بلوک تنظیم شده باشد، مقدار 0 مجاز نبوده و کلید حسگر Invalid request برگردانده میشود. - -P, --pbdata
- بیت PBDATA را در cdb دستور WRITE SAME تنظیم میکند. این بیت در sbc3r32 در سپتامبر ۲۰۱۲ منسوخ شد.
- -t, --timeout=TO
- که در آن TO مقدار زمان انتظار (مهلت زمانی) دستور بر حسب ثانیه است. مقدار پیشفرض ۶۰ ثانیه است. اگر NUM بزرگ (یا صفر) باشد، تکمیل یک دستور WRITE SAME ممکن است به زمانی به مراتب بیشتر از ۶۰ ثانیه نیاز داشته باشد.
- -U, --unmap
- بیت UNMAP را در cdb دستورات WRITE SAME(10, 16 and 32) تنظیم میکند. بخش UNMAP را در ادامه ببینید.
- -v, --verbose
- افزایش سطح پرگویی (پیامهای اشکالزدایی).
- -V, --version
- نمایش رشته نسخه برنامه و سپس خروج.
- -w, --wrprotect=WPR
- فیلد "Write protect" را در cdb دستور WRITE SAME روی WPR تنظیم میکند. مقدار پیشفرض صفر است. WPR باید مقداری بین 0 تا 7 باشد. هنگامی که WPR برابر با 1 یا بیشتر باشد و نوع حفاظت دیسک 1 یا بیشتر باشد، ۸ بایت اضافه برای اطلاعات حفاظتی مورد انتظار است یا تولید میشود (تا در بافر data-out دستور قرار گیرد).
- -x, --xferlen=LEN
- که در آن LEN طول بافر data-out است. مقدار پیشفرض برابر با طول فایل IF است یا اگر آن گزینه داده نشده باشد، از دستور READ CAPACITY(16 or 10) برای یافتن 'طول بلوک منطقی بر حسب بایت' استفاده میشود. اگر نوع حفاظت DEVICE برابر 1 یا بیشتر باشد و فیلد WRPROTECT (به --wrprotect=WPR مراجعه کنید) برابر با 1 یا بیشتر باشد، این رقم ممکن است ۸ بایت افزایش یابد. اگر هم این گزینه و هم گزینه IF داده شوند و LEN از طول فایل IF بیشتر باشد، در این صورت LEN طول بافر data-out خواهد بود و از صفرها به عنوان بایتهای پرکننده (pad) استفاده میشود.
حذف نگاشت (UNMAP)
تدارک بلوک منطقی (Logical block provisioning) یک اصطلاح جدید است که در بازنگری ۲۵ استاندارد SBC-3 برای قابلیت نشانهگذاری بلوکها به عنوان استفادهنشده معرفی شده است. برای آرایههای ذخیرهسازی بزرگ، این روشی برای تدارک ذخیرهسازی فیزیکی کمتر از مقداری است که دستور READ CAPACITY گزارش میدهد در دسترس است، به طوری که هنگام نیاز دستورات WRITE، ذخیرهسازی فیزیکی بیشتری تخصیص داده شود. برای حافظههای فلش (مانند درایوهای SSD) این روشی برای صرفهجویی احتمالی در مصرف انرژی (و شاید زمان دسترسی) است، زمانی که مشخص شود بخشهای بزرگی (یا تقریباً تمام) از حافظه فلش استفاده نمیشوند. درایوهای SSD برای برخورداری از طول عمر قابل قبول به الگوریتمهای تراز ساییدگی (wear levelling) نیاز دارند و معمولاً برای سادهسازی این الگوریتمها بیشازحد ظرفیت تدارک میشوند (over provision)؛ بنابراین معمولاً حافظه فلش فیزیکی بیشتری نسبت به اندازه منطقی خود دارند.
پشتیبانی از تدارک بلوک منطقی با تنظیم بودن بیت LBPME در پاسخ دستور READ CAPACITY(16) مشخص میشود (به ابزار sg_readcap مراجعه کنید). این امر نشان میدهد که حداقل یکی از دستورات UNMAP یا WRITE SAME(16) پیادهسازی شده است. اگر دستور UNMAP پیادهسازی شده باشد، فیلدهای "Maximum unmap LBA count" و "Maximum unmap block descriptor count" در صفحه VPD حدود بلوک باید هر دو بزرگتر از صفر باشند. پاسخ دستور READ CAPACITY(16) همچنین شامل یک بیت LBPRZ است که در صورت تنظیم بودن بدین معناست که اگر بلوکهای لغونگاشتشده خوانده شوند، برای دادهها مقادیر صفر بازگردانده میشود (و اگر اطلاعات حفاظتی فعال باشد، بایتهای 0xff برای آن بازگردانده میشود). در بازنگری ۲۷ استاندارد SBC-3 همین بیت LBPRZ به صفحه VPD تامین بلوک منطقی نیز اضافه شد.
در بازنگری ۲۵ از SBC-3 بیتهای LBPU و ANC_SUP به صفحه VPD تامین بلوک منطقی اضافه شدند. هنگامی که LBPU تنظیم باشد نشان میدهد که دستگاه از دستور UNMAP پشتیبانی میکند (ابزار sg_unmap را ببینید). هنگامی که بیت ANC_SUP تنظیم باشد نشان میدهد دستگاه از LBAهای لنگرانداختهشده (anchored) پشتیبانی میکند.
هنگامی که بیت UNMAP در cdb تنظیم شود، بافر data-out نیز ارسال میشود. علاوه بر این، بخش دادههای آن بافر data-out باید پر از بایتهای 0x0 باشد در حالی که بلوک حفاظت داده (۸ بایت در انتها در صورت وجود) باید روی بایتهای 0xff تنظیم شود. اگر این شرایط برآورده نشوند و بیت LBPRZ تنظیم باشد، بیت UNMAP نادیده گرفته شده و بافر data-out روی DEVICE نوشته میشود همانگونه که گویی بیت UNMAP صفر بوده است. در صورت نبود گزینه --in=IF، این ابزار تلاش میکند یک بافر data-out ایجاد کند که الزامات مربوط به اثرگذاری بیت UNMAP در cdb توسط DEVICE را برآورده سازد.
بلوکهای منطقی همچنین ممکن است توسط دستورات SCSI UNMAP و FORMAT UNIT لغو نگاشت شوند (به ابزارهای sg_unmap و sg_format مراجعه کنید).
قابلیت unmap در SCSI ارتباط نزدیکی با دستور ATA DATA SET MANAGEMENT با بیت تنظیمشده "Trim" دارد. این قابلیت تریم ATA تعامل خوبی با صفبندی دستورات SATA موسوم به NCQ ندارد. کمیته T13 دستور جدیدی به نام SFQ DATA SET MANAGEMENT را همراه با یک بیت "Trim" برای حل این مشکل معرفی کرد. دستورات SCSI WRITE SAME با بیت تنظیمشده UNMAP و همچنین دستورات UNMAP هیچ مشکلی با صفبندی SCSI ندارند.
نکات (NOTES)
آرگومانهای عددی گوناگون (مانند LBA) ممکن است شامل پسوندهای ضریب باشند یا به صورت هگزادسیمال داده شوند. بخش "NUMERIC ARGUMENTS" را در صفحه راهنمای sg3_utils(8) ببینید.
در لینوکس، پیش از نسخه هسته 3.17، درایور sg از اندازههای cdb بزرگتر از ۱۶ بایت پشتیبانی نمیکرد. از این رو یک گره دستگاه مانند /dev/sg1 که با درایور sg مرتبط است، در صورت مشخص شدن گزینه --32 (یا استنباط آن از سایر گزینهها) با این ابزار با خطا مواجه میشد. درایور bsg با گرههای دستگاهی مانند /dev/bsg/6:0:0:1 از زمان معرفیاش در نسخه 2.6.28 هسته از اندازههای cdb بزرگتر از ۱۶ بایت پشتیبانی میکند.
وضعیت خروج (EXIT STATUS)
وضعیت خروج sg_write_same در صورت موفقیت 0 است. در غیر این صورت به صفحه راهنمای sg3_utils(8) مراجعه کنید.
مثالها (EXAMPLES)
هشدار: تمام این مثالها دادههای موجود در یک یا چند بلوک را بازنویسی میکنند و ممکن است تمام دیسک را پاک کنند!
یک کاربرد ساده، نوشتن بلوکهای صفر از یک LBA مشخص (شامل خود آن) به تعداد ۶۳ بلوک است:
sg_write_same --lba=0x1234 --num=63 /dev/sdc
از آنجا که
--xferlen=LEN داده
نشده است،
این ابزار
دستور READ CAPACITY را
روی /dev/sdc
فراخوانی
میکند تا
تعداد
بایتهای
موجود در یک
بلوک منطقی
را تعیین
کند. فرض
کنیم این
مقدار ۵۱۲
بایت باشد.
از آنجا که
--in=IF داده
نشده است،
یک بلوک پر
از صفر فرض
میشود.
بنابراین
۶۳ بلوک از
صفرها (هر
بلوک حاوی
۵۱۲ بایت) از
LBA با مقدار 0x1234
(شامل خود آن)
نوشته
خواهد شد.
توجه داشته
باشید که
تنها یک
بلوک از
صفرها در
بافر data-out به
دستور SCSI WRITE SAME
ارسال
میشود
(همانگونه
که توسط SBC-3
الزامی شده
است).
استفاده از
دستور SCSI WRITE SAME
برای نوشتن
یک یا چند
بلوک از
صفرها
معادل
دستور NVMe با
نام Write Zeroes است.
اکنون
بلوکهای
صفر را در کل
دیسک
مینویسیم.
[توجه داشته
باشید که
دستورات
نوع
پاکسازی (sanitize)
بلوکها و
متادادههایی
را نیز که
مستقیماً
قابل
مشاهده
نیستند پاک
میکنند]:
sg_write_same --lba=0x0 --num=0 /dev/sdc
بله، در این زمینه --num=0 به معنای باقیمانده دیسک است. اجرای فوق ممکن است به دلیل تنظیم بودن بیت WSNZ در صفحه VPD حدود بلوک با خطا مواجه شود. برای دور زدن این مشکل، دستور زیر را امتحان کنید:
sg_write_same --lba=0x0 --ndob /dev/sdc
این اجرا در صورت پشتیبانی شدن، این مزیت افزوده را دارد که بافر data-out پر از صفر را ارسال نمیکند. توجه داشته باشید که این احتمال وجود دارد که به جای صفر، «الگوی مقداردهی اولیه تدارک» در هر بلوک نوشته شود.
مثال مشابهی در ادامه آمده است اما در این حالت بلوکها به جای صفر شدن، «لغو نگاشت» میشوند (در ادبیات ATA اصطلاحاً «تریم» میشوند):
sg_write_same --unmap -L 0x1234 -n 63 /dev/sdc
توجه داشته باشید که اگر بیت LBPRZ در پاسخ READ CAPACITY(16) تنظیم شده باشد (یعنی مخفف logical block provisioning read zeros)، آنگاه این دو مثال دستکم از دیدگاه خواندنهای بعدی عملکرد یکسانی دارند.
این ابزار همچنین میتواند برای نوشتن اطلاعات حفاظتی (PI) روی دیسکهایی که با نوع حفاظتی بزرگتر از صفر فرمت شدهاند استفاده شود. PI مقدار ۸ بایت داده اضافی است که به دادههای کاربر در یک بلوک منطقی پیوست میشود: دو بایت اول یک CRC (موسوم به "guard")، دو بایت بعدی "application tag" و چهار بایت آخر "reference tag" است. در انواع حفاظتی ۱ و ۲ اگر application tag برابر 0xffff باشد، بررسی guard نباید (در برابر دادههای کاربر) انجام شود.
در این مثال فرض میکنیم اندازه بلوک منطقی (دادههای کاربر) ۵۱۲ بایت است و دیسک با نوع حفاظتی ۱ فرمت شده است. از آنجا که قصد داریم LBA 2468 را تغییر دهیم، ابتدا یک کپی از آن تهیه میکنیم:
dd if=/dev/sdb skip=2468 bs=512 of=2468.bin count=1
خط دستور زیر دادههای کاربر را روی صفر و PI را روی ۸ بایت 0xFF در LBA 2468 تنظیم میکند:
sg_write_same --lba=2468 /dev/sdb
خواندن مجدد آن بلوک باید موفقیتآمیز باشد زیرا application tag برابر 0xffff است که بررسی محافظ (CRC) را متوقف میکند (که در غیر این صورت نادرست میبود):
dd if=/dev/sdb skip=2468 bs=512 of=/dev/null count=1
اکنون تلاشی برای ایجاد یک فایل باینری با مقادیر صفر در دادههای کاربر، 0x0000 در application tag و بایتهای 0xff در دو فیلد دیگر PI انجام میشود. ایجاد بایتهای 0xff در یک فایل (در یونیکس) همانطور که دستور "tr" در زیر نشان میدهد کمی قلق دارد:
dd if=/dev/zero bs=1 count=512 of=ud.bin
tr "\000" "\377" < /dev/zero | dd bs=1 of=ff_s.bin
count=8
cat ud.bin ff_s.bin > lb.bin
dd if=/dev/zero bs=1 count=2 seek=514 conv=notrunc of=lb.bin
فایل حاصل را میتوان با 'hexdump -C lb.bin' مشاهده کرد و باید حاوی ۵۲۰ بایت باشد. اکنون میتوان آن فایل را به صورت زیر روی LBA 2468 نوشت:
sg_write_same --lba=2468 wrprotect=3 --in=lb.bin /dev/sdb
توجه داشته باشید که --wrprotect=3 به جای تنظیم روی 1 استفاده شده است، زیرا میخواهیم دستور WRITE SAME با موفقیت انجام شود حتی با اینکه دادههای PI اکنون نشان میدهند که دادههای کاربر خراب است. هنگامی که تلاشی برای خواندن LBA صورت گیرد، باید خطایی رخ دهد:
dd if=/dev/sdb skip=2468 bs=512 of=/dev/null count=1
خطاهای dd چندان رسا نیستند، اگر dmesg بررسی شود باید خطی شبیه به این وجود داشته باشد: "[sdb] Add. Sense: Logical block guard check failed". این بلوک را میتوان با اجرای دوباره دستور "sg_write_same --lba=1234 /dev/sdb" یا بازگرداندن محتویات اصلی آن LBA اصلاح کرد:
dd if=2468.bin bs=512 seek=2468 of=/dev/sdb conv=notrunc count=1
امید میرود که دستور dd هرگز سعی نکند فایل خروجی را در زمانی که یک دستگاه بلوکی است کوتاه (truncate) کند.
نویسندگان (AUTHORS)
نوشته شده توسط Douglas Gilbert.
گزارش باگها (REPORTING BUGS)
گزارش باگها به <dgilbert at interlog dot com>.
حق نشر (COPYRIGHT)
حق نشر © 2009-2020
Douglas Gilbert
این
نرمافزار
تحت مجوز BSD-2-Clause
توزیع
میشود. هیچ
ضمانتی
وجود
ندارد؛ حتی
برای
قابلیت
فروش یا
تناسب با یک
هدف خاص.
همچنین ببینید (SEE ALSO)
sg_format,sg_get_lba_status,sg_readcap,sg_vpd,sg_unmap, sg_write_x(sg3_utils)
| June 2020 | sg3_utils-1.45 |