ماژول نویسی برای هسته لینوکس (قسمت نهم)
در قسمت قبل با چگونگی خواندن از و نوشتن در فایل سیستم مجازی proc/ آشنا شدیم. در
این قسمت مدیریت این فایل سیستم را با استفاده از inode*ها و seq_file*ها از نظر می*گذرانیم.
در هسته لینوکس مکانیزم استانداردی برای ثبت فایل سیستم وجود دارد. از آن جاییکه هر فایل سیستم بایستی توابع مخصوص به خود برای به کار بردن inode و عملیات فایل داشته باشد ساختار ویژه*ای به نام struct inode_operations برای نگهداری اشاره*گر به تمام آن توابع وجود دارد که در خود اشاره*گری به ساختار struct file_operations دارد.
در فایل سیستمproc/ هنگامی*که یک فایل جدید ثبت می*شود ما اجازه خواهیم داشت که ساختار inode_operations ای که برای دسترسی به این فایل به کار می*رود را تعیین کنیم.
بـــه طـور خلاصه در ایـن مــکـانیزم یــک struct inode_operations وجـــود دارد کــه در خــود اشاره*گــری بــه یــک struct file_operations دارد کــه این ساختار نیز اشاره*گرهایی بــه تــوابـعـی مانند procfs_read و procfs_write دارد که وظیفه خواندن از و نوشتن در proc/ را بر عهده دارند.
نکته قابل توجه دیگر وجود توابعی مانند module_permission است. این تابع هنگامی* کــه یـک پروسه عملی در proc/ انجام می*دهد صدا زده شده و تعیین می*کند که آیا پروسه مذکور حق انجام عمل مورد نظر را دارد یا نه؟
در حال حاضر این قضاوت بر اساس عمل مذکور و uid کاربر حاضر (که در متغییر current که اشــاره*گری بــه ساختاری در مورد اطلاعات پروسه حاضر است , وجود دارد.) صورت می*پذیرد. اما باید توجه داشت که این قضاوت می*تواند به دلخواه ما که ماژول هسته را می*نویسیم صورت گیرد.
نکته دیگری که در اینجا بایستی ذکر گردد نقش توابع read و write برای هسته برعکس نقشی اســت کــه در مـورد یک پروسه وجود دارد. تابع read به عنوان تابع خروجی و تابع write به عنوان تابع ورودی در هسته استفاده می*شود. دلیل این موضوع آن است که هنگامی*که یک پروسه از هسته چیزی می*خــوانـد هسته بایستی آن را به عنوان خروجی بیرون دهد و هنگامیکه یک پروسه در هسته می*نویسد هسته بایستی آن را به عنوان ورودی دریافت دارد.
بــرای فــهم عمیق*تــر و چگــونــگی کاربرد ساختارهای inode_operations و module_permission به مثال procfs3.c که توضیحات کاملی در کــد برای آن وجود دارد مراجعه کنید. مـاژول را کامپایل نموده و در هسته وارد نمایید و با دستورات cat و echo عملکرد آن را با بررسی فایل var/log/messages/ مورد بررسی قرار دهید.
مدیریت فایل سیستم مجازی proc/ با استفاده از seq_file
همان گونه که دیدیم کار با یک فایل proc/ ممکن است کاملا پیچیده باشد. بــرای رفـــع این پیــچـیدگــی API ای بــه نام seq_file در هسته لینوکس وجــود دارد کـه ما را در قالب بندی یک فایل proc/ برای خروجی یاری می*نماید که بر اساس تــرتیب (sequence) می*باشد. ایـن تـرتیب از ســه تابع ()start و ()next و ()stop تشکیل شده است. seq_file هنگامی* که یک کاربر از proc/ می*خواند راه اندازی می*شود.
یک ترتیب با صدا کردن تابع ()start آغــاز می*شود. اگــر مقــدار بازگشتــی ایــن تــابـع NULL نبـاشد تابع ()next صدا زده می*شود. نقش این تابع به عنوان یک iterator می*باشد و هــدف از صــداکــردن پشت ســرهــم ایـن تابع جابجا شدن به اطلاعات بعدی فایل proc/ می*باشد.
هر هنگام که این تابع صـدا زده می*شود تابع دیگری به نام ()show نیز صدا زده می*شود که اطلاعات دریافتی را در بافری که توسط پروسه فراهم شده می*نویسد. تابع ()next تا زمانیکه NULL را به عنوان خروجی برگرداند صدا زده می*شود. در این هنگام ترتیب با صدا زده شدن تابع ()stop خاتمه می*پذیرد.
توجه نمایید که هنگامی*که یک ترتیب خاتمه می*پذیرد تــرتیــب جــدیدی شروع می*شود. این بدان معناست که در انتهای تابع ()stop تابع ()start دوباره صدا زده می*شـــود. ایــن چرخه، هــنگامی*که ()start مقدار بازگشتی NULL باز می*گرداند خاتمه می*پذیرد. نحوه عملکرد seq_file در شکل ۱ نشان داده شده است.
شکل ۱ - نحوه عملکرد seq_file
seq_file توابع ساده*ای مانند seq_read و seq_lseek و... را بــرای file_operations فــراهــم می*نماید. امــا نمـی*تواند در proc/ بنویسد. برای انجام این کار بایستی مانند مثال قبلی عمل کرد.
به عنوان مثالی از seq_file به مثال procfs4.c مراجعه کنید. برای کسب اطلاعات بیشتر در این زمینه به این صفحات وب در سایت*های LWN و KernelNewbies مراجعه کنید:
http://lwn.net/Articles/22355
http://www.kernelnewbies.org/documents/seq_file_howto.txtهمچنین می*توانید پیــاده ســازی seq_file در هسته لینوکس را در مســیر linux source/fs/seq_file.c مورد مطالعه قرار دهید. در قسمت آینده مرور مختصری بر proc/ به عنوان ورودی و sysfs خواهیم داشت.
در قسمت قبل با چگونگی خواندن از و نوشتن در فایل سیستم مجازی proc/ آشنا شدیم. در
این قسمت مدیریت این فایل سیستم را با استفاده از inode*ها و seq_file*ها از نظر می*گذرانیم.
در هسته لینوکس مکانیزم استانداردی برای ثبت فایل سیستم وجود دارد. از آن جاییکه هر فایل سیستم بایستی توابع مخصوص به خود برای به کار بردن inode و عملیات فایل داشته باشد ساختار ویژه*ای به نام struct inode_operations برای نگهداری اشاره*گر به تمام آن توابع وجود دارد که در خود اشاره*گری به ساختار struct file_operations دارد.
در فایل سیستمproc/ هنگامی*که یک فایل جدید ثبت می*شود ما اجازه خواهیم داشت که ساختار inode_operations ای که برای دسترسی به این فایل به کار می*رود را تعیین کنیم.
بـــه طـور خلاصه در ایـن مــکـانیزم یــک struct inode_operations وجـــود دارد کــه در خــود اشاره*گــری بــه یــک struct file_operations دارد کــه این ساختار نیز اشاره*گرهایی بــه تــوابـعـی مانند procfs_read و procfs_write دارد که وظیفه خواندن از و نوشتن در proc/ را بر عهده دارند.
نکته قابل توجه دیگر وجود توابعی مانند module_permission است. این تابع هنگامی* کــه یـک پروسه عملی در proc/ انجام می*دهد صدا زده شده و تعیین می*کند که آیا پروسه مذکور حق انجام عمل مورد نظر را دارد یا نه؟
در حال حاضر این قضاوت بر اساس عمل مذکور و uid کاربر حاضر (که در متغییر current که اشــاره*گری بــه ساختاری در مورد اطلاعات پروسه حاضر است , وجود دارد.) صورت می*پذیرد. اما باید توجه داشت که این قضاوت می*تواند به دلخواه ما که ماژول هسته را می*نویسیم صورت گیرد.
نکته دیگری که در اینجا بایستی ذکر گردد نقش توابع read و write برای هسته برعکس نقشی اســت کــه در مـورد یک پروسه وجود دارد. تابع read به عنوان تابع خروجی و تابع write به عنوان تابع ورودی در هسته استفاده می*شود. دلیل این موضوع آن است که هنگامی*که یک پروسه از هسته چیزی می*خــوانـد هسته بایستی آن را به عنوان خروجی بیرون دهد و هنگامیکه یک پروسه در هسته می*نویسد هسته بایستی آن را به عنوان ورودی دریافت دارد.
بــرای فــهم عمیق*تــر و چگــونــگی کاربرد ساختارهای inode_operations و module_permission به مثال procfs3.c که توضیحات کاملی در کــد برای آن وجود دارد مراجعه کنید. مـاژول را کامپایل نموده و در هسته وارد نمایید و با دستورات cat و echo عملکرد آن را با بررسی فایل var/log/messages/ مورد بررسی قرار دهید.
مدیریت فایل سیستم مجازی proc/ با استفاده از seq_file
همان گونه که دیدیم کار با یک فایل proc/ ممکن است کاملا پیچیده باشد. بــرای رفـــع این پیــچـیدگــی API ای بــه نام seq_file در هسته لینوکس وجــود دارد کـه ما را در قالب بندی یک فایل proc/ برای خروجی یاری می*نماید که بر اساس تــرتیب (sequence) می*باشد. ایـن تـرتیب از ســه تابع ()start و ()next و ()stop تشکیل شده است. seq_file هنگامی* که یک کاربر از proc/ می*خواند راه اندازی می*شود.
یک ترتیب با صدا کردن تابع ()start آغــاز می*شود. اگــر مقــدار بازگشتــی ایــن تــابـع NULL نبـاشد تابع ()next صدا زده می*شود. نقش این تابع به عنوان یک iterator می*باشد و هــدف از صــداکــردن پشت ســرهــم ایـن تابع جابجا شدن به اطلاعات بعدی فایل proc/ می*باشد.
هر هنگام که این تابع صـدا زده می*شود تابع دیگری به نام ()show نیز صدا زده می*شود که اطلاعات دریافتی را در بافری که توسط پروسه فراهم شده می*نویسد. تابع ()next تا زمانیکه NULL را به عنوان خروجی برگرداند صدا زده می*شود. در این هنگام ترتیب با صدا زده شدن تابع ()stop خاتمه می*پذیرد.
توجه نمایید که هنگامی*که یک ترتیب خاتمه می*پذیرد تــرتیــب جــدیدی شروع می*شود. این بدان معناست که در انتهای تابع ()stop تابع ()start دوباره صدا زده می*شـــود. ایــن چرخه، هــنگامی*که ()start مقدار بازگشتی NULL باز می*گرداند خاتمه می*پذیرد. نحوه عملکرد seq_file در شکل ۱ نشان داده شده است.
شکل ۱ - نحوه عملکرد seq_file
seq_file توابع ساده*ای مانند seq_read و seq_lseek و... را بــرای file_operations فــراهــم می*نماید. امــا نمـی*تواند در proc/ بنویسد. برای انجام این کار بایستی مانند مثال قبلی عمل کرد.
به عنوان مثالی از seq_file به مثال procfs4.c مراجعه کنید. برای کسب اطلاعات بیشتر در این زمینه به این صفحات وب در سایت*های LWN و KernelNewbies مراجعه کنید:
http://lwn.net/Articles/22355
http://www.kernelnewbies.org/documents/seq_file_howto.txtهمچنین می*توانید پیــاده ســازی seq_file در هسته لینوکس را در مســیر linux source/fs/seq_file.c مورد مطالعه قرار دهید. در قسمت آینده مرور مختصری بر proc/ به عنوان ورودی و sysfs خواهیم داشت.
+ نوشته شده توسط امیرحسین عربی زاده در جمعه یازدهم خرداد 1386 و ساعت
15:43 |


