SG_RAW(8) SG3_UTILS SG_RAW(8)

sg_raw - ارسال دستور دلخواه SCSI یا NVMe به یک دستگاه

sg_raw [--binary] [--cmdfile=CF] [--cmdset=CS] [--enumerate] [--help] [--infile=IFILE] [--nosense] [--nvm] [--outfile=OFILE] [--raw] [--readonly] [--request=RLEN] [--scan=FO,LO] [--send=SLEN] [--skip=KLEN] [--timeout=SECS] [--verbose] [--version] DEVICE [CDB0 CDB1 ...]

این ابزار یک دستور دلخواه SCSI (بین ۶ تا ۲۵۶ بایت) را به DEVICE ارسال می‌کند. ممکن است هیچ انتقال داده‌ای همراه آن نباشد؛ یا داده‌ها ممکن است از یک فایل خوانده شده و به DEVICE ارسال شوند؛ یا داده‌ها ممکن است از DEVICE دریافت شده و سپس نمایش داده شوند یا در یک فایل نوشته شوند. در صورت پشتیبانی رابط عبور مستقیم (pass through)، دستورات دوطرفه (bidirectional) نیز ممکن است ارسال شوند (یعنی شامل داده‌هایی که هم به DEVICE ارسال می‌شوند و هم از DEVICE دریافت می‌گردند).

طول دستور SCSI ممکن است بین ۶ تا ۲۵۶ بایت باشد. هر بایت دستور در قالب هگزادسیمال ساده (00..FF) بدون پیشوند یا پسوند مشخص می‌شود. دستور را می‌توان در خط فرمان یا از طریق گزینه --cmdfile=CF مشخص کرد. بخش «مثال‌ها» را در ادامه ببینید.

دستورات از طریق یک رابط عمومی SCSI (یا generic SCSI) عبور می‌کنند که برای چندین سیستم‌عامل از جمله لینوکس، FreeBSD و ویندوز پیاده‌سازی شده است.

پشتیبانی آزمایشی برای ارسال دستورات NVMe Admin و NVM به DEVICE اضافه شده است. از آنجا که تمام دستورات NVMe دارای طول ۶۴ بایت هستند، استفاده از گزینه --cmdfile=CF بسیار راحت‌تر از تایپ کردن ۶۴ بایت دستور NVMe در خط فرمان است. بخش «پشتیبانی از NVME» را در ادامه ببینید. از یک روش ابتکاری (heuristic) بر پایه طول دستور برای تشخیص SCSI یا NVMe بودن دستور داده‌شده استفاده می‌شود؛ برای نادیده گرفتن این روش ابتکاری از گزینه --cmdset=CS استفاده کنید.

آرگومان‌های گزینه‌های طولانی برای گزینه‌های کوتاه نیز الزامی هستند. گزینه‌ها بر اساس نام گزینه طولانی به ترتیب الفبایی مرتب شده‌اند.

داده‌ها را در قالب باینری تخلیه (dump) می‌کند، حتی هنگام نوشتن در خروجی استاندارد (stdout).
CF نام فایلی است که حاوی دستور مورد نظر برای اجرا می‌باشد. بدون این گزینه، دستور باید در خط فرمان، پس از گزینه‌ها و DEVICE داده شود.
CS عددی برای مشخص کردن مجموعه دستوری مورد استفاده است (یعنی SCSI یا NVMe). مقدار 0، که پیش‌فرض است، باعث استفاده از یک روش ابتکاری بر پایه طول دستور می‌شود. برای نادیده گرفتن این روش ابتکاری و انتخاب مجموعه دستوری SCSI از مقدار 1 برای CS استفاده کنید. برای نادیده گرفتن این روش ابتکاری و انتخاب مجموعه دستوری NVMe از مقدار 2 برای CS استفاده کنید.
نمایش اطلاعات نحوه استفاده و خروج.
خواندن داده‌های باینری از IFILE به جای stdin. این گزینه در صورتی که --send مشخص نشده باشد نادیده گرفته می‌شود. آن داده‌ها، در صورت استفاده، به بافر «داده‌های خروجی» ("data-out") دستور تبدیل خواهند شد.
اطلاعات Sense مربوط به SCSI نمایش داده نشود.
هنگام ارسال دستورات NVMe، مجموعه دستورات Admin پیش‌فرض فرض می‌شود. برای ارسال مجموعه دستورات NVM (مانند دستورات Read و Write (داده‌های کاربر)) این گزینه باید ارائه شود.
نوشتن داده‌های دریافت شده از DEVICE در OFILE. آن داده‌ها بافر «داده‌های ورودی» ("data-in") دستور هستند. داده‌ها به صورت باینری نوشته می‌شوند. به طور پیش‌فرض، داده‌ها با قالب هگزادسیمال در stdout ریخته می‌شوند. اگر OFILE برابر با '-' باشد، داده‌ها به صورت باینری در stdout ریخته می‌شوند. این گزینه در صورتی که --request مشخص نشده باشد نادیده گرفته می‌شود.
تفسیر CF (یعنی فایل دستور) به عنوان فایلی حاوی داده‌های باینری. حالت پیش‌فرض این است که فرض شود فایل حاوی مقادیر هگزادسیمال ASCII است.
باز کردن DEVICE به صورت فقط‌خواندنی. حالت پیش‌فرض (بدون این گزینه) باز کردن آن به صورت خواندنی-نوشتنی است.
انتظار دریافت تا سقف RLEN بایت داده از DEVICE. مقدار RLEN می‌تواند دارای پسوند 'k' باشد تا به جای بایت، از کیلوبایت (۱۰۲۴ بایت) استفاده شود. مقدار RLEN در مبنای ده‌دهی است مگر اینکه دارای پیشوند '0x' یا پسوند 'h' باشد.
اگر RLEN بیش از حد کوچک باشد (یعنی یا کوچک‌تر از مقدار مشخص‌شده توسط cdb (معمولاً فیلد "allocation length") و/یا کوچک‌تر از مقداری که DEVICE سعی در بازگرداندن آن دارد)، درایور HBA ممکن است خطایی گزارش کند. بزرگ‌تر تعیین کردن RLEN از مقدار مورد نیاز نباید مشکلی ایجاد کند. اکثر دستورات "data-in" مربوط به SCSI یک بلوک داده برمی‌گردانند که (در بایت‌های اولیه خود) شامل طولی است که DEVICE در صورت کافی بودن اندازه فیلد "allocation length" در cdb «مایل است» ارسال کند. در عمل، DEVICE بیش از تعداد بایت‌های مشخص‌شده در فیلد "allocation length" در cdb بازنخواهد گرداند.
پویش محدوده‌ای از آپ‌کدها (opcodes؛ یعنی بایت اول هر دستور). اولین آپ‌کد در این پویش FO است (که ده‌دهی است مگر اینکه دارای پیشوند '0x' یا پسوند 'h' باشد). آخرین آپ‌کد در پویش LO است. حداکثر مقدار LO برابر ۲۵۵ است. بایت‌های باقی‌مانده از دستور SCSI/NVMe همان مقادیری هستند که هنگام فراخوانی برنامه داده شده‌اند.
هشدار: این گزینه می‌تواند خطرناک باشد. ارسال دستورات تا حدی تصادفی به یک دستگاه می‌تواند نتایج غیرمنتظره‌ای به همراه داشته باشد. توصیه می‌شود از این گزینه به همراه گزینه --cmdset=CS که در آن CS برابر ۱ یا ۲ است استفاده شود تا از احتمال تغییر مجموعه دستوری در طول پویش جلوگیری به عمل آید.
خواندن SLEN بایت داده، چه از stdin یا از یک فایل، و ارسال آن‌ها به DEVICE. در لایه انتقال SCSI، مقدار SLEN طول (به بایت) بافر "data-out" خواهد شد. مقدار SLEN در مبنای ده‌دهی است مگر اینکه دارای پیشوند '0x' یا پسوند 'h' باشد.
مسئولیت اطمینان از این که طول "data-out" ضمنی یا تصریح‌شده در cdb با SLEN همخوانی دارد بر عهده کاربر است. توجه داشته باشید که برخی از دستورات رایج SCSI مانند WRITE(10) دارای یک فیلد "transfer length" هستند که واحد آن بلوک‌های منطقی است (که معمولاً دارای طول ۵۱۲ یا ۴۰۹۶ بایت هستند).
رد کردن KLEN بایت اول از فایل ورودی یا جریان ورودی. این گزینه در صورتی که --send مشخص نشده باشد نادیده گرفته می‌شود. اگر --send مشخص شده باشد و این گزینه داده نشود، صفر بایت رد می‌شود.
انتظار تا سقف SECS ثانیه برای اتمام دستور (پیش‌فرض: ۲۰). توجه داشته باشید که اگر زمان دستور به پایان برسد (timeout رخ دهد)، سیستم‌عامل ممکن است ابتدا با لغو (abort) دستور شروع کند و اگر ناموفق باشد ممکن است اقدام به ریست دستگاه نماید. شکل طولانیِ دیگر این گزینه --tmo=SECS است.
افزایش سطح پرگویی (verbosity). می‌تواند چندین بار استفاده شود.
نمایش اطلاعات نسخه و مجوز و خروج.

ابزار sg_inq می‌تواند برای ارسال دستور INQUIRY به یک دستگاه جهت تعیین نوع دستگاه جانبی آن (مانند '1' برای یک دستگاه استریم مانند درایو نوار) استفاده شود که تعیین می‌کند دستگاه چه مجموعه‌های دستوری SCSI را باید پشتیبانی کند (مانند SPC و SSC). ابزار sg_vpd صفحات داده‌های حیاتی محصول (VPD) دستگاه را خوانده و رمزگشایی می‌کند که ممکن است شامل اطلاعات مفیدی باشند.

امکان ارسال CDB بزرگ‌تر از ۱۶ بایت (و در برخی موارد بزرگ‌تر از ۱۲ بایت) ممکن است توسط رابط عبور مستقیم (pass-through)، درایور سطح پایین یا لایه انتقال محدود شود. در سری ۳ هسته‌های لینوکس، درایور bsg می‌تواند CDBهای طولانی‌تر را مدیریت کند؛ دستگاه‌های بلوکی (مانند /dev/sdc) که از طریق فراخوانی SG_IO ioctl مورد دسترسی قرار می‌گیرند نمی‌توانند CDBهای بیش از ۱۶ بایت را پردازش کنند؛ و درایور sg از هسته ۳.۱۷ لینوکس به بعد قادر به مدیریت CDBهای طولانی‌تر است.

نام دستور CDB تعریف‌شده توسط T10 برای CDB ارائه‌شده در صورت مشخص شدن گزینه '-vv' نمایش داده می‌شود. نحو خط فرمان همچنان باید صحیح باشد، بنابراین می‌توان از /dev/null برای DEVICE استفاده کرد زیرا رمزگشایی نام دستور CDB پیش از بررسی DEVICE انجام می‌شود.

هدف از گزینه --scan=FO,LO این است که فرایند یافتن دستورات پنهان یا مستندنه‌شده را تا حدودی ساده‌تر کند. این گزینه باید با احتیاط استفاده شود؛ به عنوان مثال هنگام بررسی دستورات SCSI خاصِ سازنده:

پشتیبانی از NVMe (یا همان NVM Express) در حال حاضر آزمایشی است. مفاهیم NVMe به طور منطقی بر معماری SCSI منطبق می‌شوند. یک واحد منطقی (LU) در SCSI مشابه با یک فضای نام (namespace) در NVMe است (اگرچه LUN 0 در SCSI بسیار رایج است در حالی که شناسه‌های فضای نام از ۱ شروع می‌شوند). یک دستگاه مقصد (target) در SCSI مشابه با یک کنترل‌کننده در NVMe است. دستورات SCSI از ۶ تا ۲۶۰ بایت متغیر هستند (اگرچه بلوک‌های توصیف‌کننده دستور SCSI یا همان cdb_ها که بیش از ۳۲ بایت طول داشته باشند رایج نیستند) در حالی که تمام دستورات NVMe در حال حاضر دارای طول ۶۴ بایت هستند. معماری SCSI تمایز آشکاری میان آغازگر (initiator - که اغلب HBA نامیده می‌شود) و مقصد (target - یا دستگاه) قائل می‌شود در حالی که (دست‌کم روی بستر ارتباطی PCIe) کنترل‌کننده NVMe هر دو نقش را ایفا می‌کند. این ابزار به طور پیش‌فرض فرض می‌کند که دستور ۶۴ بایتیِ ارائه‌شده توسط کاربر متعلق به مجموعه دستورات Admin مربوط به NVMe است. برای صدور دستورات از مجموعه دستورات "NVM"، گزینه --nvm باید ارائه شود. دستورات Admin و NVM به صف ارسال ۰ (submission queue 0) فرستاده می‌شوند.

یک تفاوت چشمگیر این است که SCSI از نمایش big endian برای اعداد صحیح بزرگ‌تر از ۸ بیت (یعنی بزرگ‌تر از ۱ بایت) استفاده می‌کند در حالی که NVMe از نمایش little endian استفاده می‌نماید (مانند بیشتر مواردی که از سازمان اینتل سرچشمه گرفته‌اند). مشخصات NVMe از کلمه‌ها یا Words (۱۶ بیت)، کلمه‌های دوگانه یا Double Words (۳۲ بیت) و گاهی کلمه‌های چهارگانه یا Quad Words (۶۴ بیت) صحبت می‌کنند و الزامات ترازسازی (alignment) سخت‌گیرانه‌تری نسبت به SCSI دارند.

تفاوتی که بر این ابزار تأثیر می‌گذارد این است که NVMe اشاره‌گرهایی به حافظه میزبان را در درون دستورات خود قرار می‌دهد در حالی که SCSI این جزئیات را به لایه انتقالی که استفاده می‌کند (مانند SAS، iSCSI، SRP) واگذار می‌نماید. از آنجا که این ابزار دستور را از کاربر دریافت می‌کند (چه در خط فرمان یا در فایلی با نام CF) اما خود ابزار بافر data-in یا data-out را بنا به نیاز تخصیص می‌دهد، کاربر از پیش نمی‌داند آدرس آن بافر چه خواهد بود. برخی آدرس‌های ویژه برای کمک به این مسئله معرفی شده‌اند: آدرس 0xfffffffffffffffe به عنوان «استفاده از آدرس بافر data-in» تفسیر می‌شود در حالی که 0xfffffffffffffffd به عنوان «استفاده از آدرس بافر data-out» تفسیر می‌گردد. از آنجا که NVMe از نمادگذاری little endian استفاده می‌کند، آن آدرس نخست در جریان بایت‌های دستور NVMe به صورت "fe" و به دنبال آن هفت "ff" ظاهر می‌شود. ترتیب مشابهی برای طول آن بافر (به بایت) در نظر گرفته شده است، اما از آنجا که آن یک مقدار ۳۲ بیتی (در متن اصلی: 32 byte) است، ۴ بایت نخست (همگی "ff") حذف می‌شوند.

چندین نمونه از فایل‌های دستور را می‌توان در دایرکتوری inhex از بسته سورس تاربال (tarball) این ابزار یافت: nvme_identify_ctl.hex، nvme_dev_self_test.hex، nvme_read_ctl.hex و nvme_write_ctl.hex .

توجه و احتیاط: استاندارد NVMe اغلب به برخی از فیلدهای خود با عنوان "0's based" (شروع از صفر) اشاره می‌کند. این‌ها معمولاً شمارش چیزی شبیه به تعداد بلوک‌های خوانده‌شدنی هستند. برای مثال در دستور NVMe Read، یک فیلد تعداد بلوک‌های "0's based" حاوی مقدار ۳ به معنای خواندن ۴ بلوک است! خیر، این یک شوخی نیست.

این مثال‌ها، به جز مورد آخر، از نام‌های دستگاه‌های لینوکس استفاده می‌کنند. برای نام‌های دستگاه‌های مناسب در سایر سیستم‌های عامل پشتیبانی‌شده، صفحه راهنمای sg3_utils(8) را ببینید.

خارج کردن رسانه (دیسک) از درایو سی‌دی /dev/scd0.
اجرای یک دستور INQUIRY روی /dev/sg0 و ریختن داده‌های پاسخ (حداکثر تا ۱۰۲۴ بایت) در stdout.
ارائه مثالی از نوشتن ۵۱۲ بایت روی یک سکتور از دیسک تا حدی خطرناک است. به جای آن، این مثال فایل i512.bin (با فرض داشتن طول ۵۱۲ بایت) را می‌خواند و از دستور SCSI WRITE BUFFER برای ارسال آن به بافر "data" (یعنی حالت ۲) استفاده می‌کند. این یک عملیات ایمن است.
این دستور از دستور SCSI READ BUFFER برای خواندن ۵۱۲ بایت از بافر "data" (یعنی حالت ۲) و سپس نوشتن آن در فایل o512.bin استفاده می‌کند. هنگامی که همراه با مثال قبلی استفاده شود، اگر هر دو دستور کار کنند، دستور 'cmp i512.bin o512.bin' باید تطابق آن‌ها را نشان دهد.
این یک دستور دوطرفه (bidirectional) به نام XDWRITEREAD(10) است که از طریق یک دستگاه bsg در لینوکس ارسال می‌شود. توجه داشته باشید که داده‌ها از "urandom.bin" خوانده شده و به دستگاه فرستاده می‌شوند (data-out)، در حالی که داده‌های حاصل (data-in) در فایل "out.bin" قرار می‌گیرند. همچنین توجه داشته باشید که طول هر دو ۵۱۲ بایت است که متناظر با طول انتقال ۱ (بلوک) در cdb می‌باشد (یعنی بایت ماقبل آخر). فایل urandom.bin را می‌توان به این صورت ایجاد کرد:
dd if=/dev/urandom bs=512 count=1 of=urandom.bin
این مثال از ویندوز است و ارسال دستور ATA STANDBY IMMEDIATE را به PhysicalDrive1 نشان می‌دهد. این دستور ATA درون دستور SCSI ATA PASS-THROUGH(12) گنجانده شده است (استاندارد SAT یا SAT-2 را در https://www.t10.org ببینید). توجه داشته باشید که دستور STANDBY IMMEDIATE هیچ داده اضافی ارسال یا دریافت نمی‌کند؛ با این حال اگر ناموفق باشد، داده‌های sense باید بازگردانده شده و نمایش داده شوند.
برای نمونه‌های NVMe فایل‌هایی را در پوشه inhex این بسته که با 'nvme_' شروع می‌شوند، مانند inhex/nvme_identify_ctl.hex ببینید.

وضعیت خروج sg_raw در صورت موفقیت 0 است. در غیر این صورت صفحه راهنمای sg3_utils(8) را ببینید.

نوشته‌شده توسط Ingo van Lil

گزارش باگ‌ها به <inguin at gmx dot de> یا به <dgilbert at interlog dot com>.

حق نشر © 2001-2023 Ingo van Lil
این نرم‌افزار تحت مجوز GPL نسخه ۲ توزیع شده است. هیچ تضمینی وجود ندارد؛ حتی برای قابلیت فروش یا تناسب با یک هدف خاص.

sg_inq, sg_vpd, sg3_utils (sg3_utils), plscsi

May 2023 sg3_utils-1.48