guestfs-faq(1) Virtualization Support guestfs-faq(1)

guestfs-faq - پرسش‌های متداول libguestfs (FAQ)

ابزار libguestfs روشی برای ساخت، دسترسی و تغییر ایمیج‌های دیسک است. شما می‌توانید محتوای درون ایمیج‌های دیسک را بررسی کنید، فایل‌های درون آن‌ها را تغییر دهید، آن‌ها را از ابتدا بسازید، اندازه آن‌ها را تغییر دهید و کارهای بسیار دیگری را انجام دهید. این ابزار به‌ویژه در اسکریپت‌ها، برنامه‌ها و خط فرمان بسیار کاربردی است.

ابزار libguestfs یک کتابخانه C است (از این‌رو پیشوند «lib-»)، و مجموعه‌ای از ابزارهای ساخته‌شده بر پایه این کتابخانه و بایندرهایی (bindings) برای بسیاری از زبان‌های برنامه‌نویسی رایج است.

برای کسب اطلاعات بیشتر درباره کارهایی که libguestfs می‌تواند انجام دهد، مقدمه موجود در صفحه خانگی (http://libguestfs.org) را مطالعه کنید.

ابزارهای virt (وب‌گاه: http://virt-tools.org) مجموعه کاملی از ابزارهای مدیریت مجازی‌سازی با هدف استفاده مدیران سیستم هستند. برخی از آن‌ها از libguestfs، برخی از libvirt و بسیاری دیگر از پروژه‌های متن‌باز دیگر می‌آیند. بنابراین virt tools یک ابرمجموعه از libguestfs محسوب می‌شود. با این حال libguestfs همراه با ابزارهای مهم بسیاری ارائه می‌شود. برای مشاهده فهرست کامل به http://libguestfs.org مراجعه کنید.

خیر!

بسته libvirt پیش‌نیازی برای libguestfs نیست.

ابزار libguestfs با هر ایمیج دیسکی کار می‌کند، از جمله موارد ساخته‌شده در VMware، KVM، qemu، VirtualBox، Xen و بسیاری از هایپروایزرهای دیگر، و همچنین ایمیج‌هایی که خودتان از ابتدا ساخته‌اید.

شرکت Red Hat حامی مالی توسعه libguestfs و خیل عظیمی از دیگر پروژه‌های متن‌باز است (یعنی هزینه‌های آن را می‌پردازد). اما شما می‌توانید libguestfs و ابزارهای virt را روی توزیع‌های مختلف لینوکس و Mac OS X اجرا کنید. ما تمام تلاشمان را می‌کنیم تا از همه توزیع‌های لینوکس به عنوان شهروندان درجه اول پشتیبانی کنیم. برخی از ابزارهای virt به Windows نیز پورت شده‌اند.

در مقایسه با kpartx
ابزار Libguestfs رویکرد متفاوتی نسبت به kpartx در پیش می‌گیرد. ابزار kpartx به کاربر ریشه (root) نیاز دارد و فایل‌سیستم‌ها را روی هسته میزبان سوار (mount) می‌کند (که می‌تواند ناامن باشد - guestfs-security(1) را ببینید). Libguestfs هسته میزبان شما را از مهمان‌ها ایزوله می‌کند، انعطاف‌پذیرتر و قابل اسکریپت‌نویسی است، از LVM پشتیبانی می‌کند، به دسترسی ریشه (root) نیاز ندارد، از سایر فرایندها جدا است و پس از پایان کار تمیزکاری را انجام می‌دهد. Libguestfs چیزی فراتر از دسترسی ساده به فایل است زیرا می‌توانید با استفاده از آن ایمیج‌ها را از ابتدا بسازید.
در مقایسه با vdfuse
ابزار vdfuse مشابه kpartx است اما برای ایمیج‌های VirtualBox کاربرد دارد. مقایسه بالا با kpartx را ببینید. می‌توانید از libguestfs بر روی فایل‌های پارتیشن نمایان‌شده توسط vdfuse استفاده کنید، اگرچه این کار ضروری نیست زیرا libguestfs می‌تواند مستقیماً به ایمیج‌های VirtualBox دسترسی داشته باشد.
در مقایسه با qemu-nbd
پروتکل NBD (Network Block Device) پروتکلی برای اشتراک‌گذاری دستگاه‌های بلوکی روی شبکه است. ابزار qemu-nbd یک کارساز (سرور) NBD است که می‌تواند با هر قالب دیسک پشتیبانی‌شده توسط qemu (مانند raw، qcow2) کار کند. می‌توانید از libguestfs و qemu-nbd یا nbdkit به همراه یکدیگر برای دسترسی به دستگاه‌های بلوکی روی شبکه استفاده کنید، برای نمونه: "guestfish -a nbd://remote"
در مقایسه با سوار کردن فایل‌سیستم‌ها در میزبان
سوار کردن فایل‌سیستم‌های مهمان در سیستم میزبان ناامن است و برای سیستم‌های مهمان نامعتبر باید کاملاً از آن اجتناب شود. از libguestfs برای فراهم آوردن لایه‌ای محافظ در برابر اکسپلویت‌های فایل‌سیستم استفاده کنید. همچنین guestmount(1) را ببینید.
در مقایسه با parted
ابزار Libguestfs از LVM پشتیبانی می‌کند. Libguestfs از parted استفاده می‌کند و بیشتر قابلیت‌های parted را از طریق API مربوط به libguestfs ارائه می‌دهد..SH "دریافت راهنمایی و گزارش باگ‌ها (GETTING HELP AND REPORTING BUGS)"

ساده‌ترین روش عبارت است از:

guestfish --version

توسعهٔ Libguestfs در یک شاخهٔ ناپایدار (unstable) انجام می‌شود و ما به‌صورت دوره‌ای یک شاخهٔ پایدار (stable) ایجاد می‌کنیم که وصله‌های پایدار به آن بک‌پورت (backport) می‌شوند. برای اطلاعات بیشتر، بخش “LIBGUESTFS VERSION NUMBERS” را در guestfs(3) مطالعه کنید.

اگر از مشتریان Red Hat هستید و از Red Hat Enterprise Linux استفاده می‌کنید، لطفاً با پشتیبانی Red Hat تماس بگیرید: http://redhat.com/support

یک فهرست ایمیل (mailing list) وجود دارد که عمدتاً برای اهداف توسعه است، اما کاربران نیز می‌توانند پرسش‌های خود را دربارهٔ libguestfs و ابزارهای virt مطرح کنند: https://lists.libguestfs.org

همچنین می‌توانید در کانال IRC با نام "#guestfs" در Libera Chat با ما گفتگو کنید. ما همیشه حضور نداریم، بنابراین لطفاً پس از مطرح کردن پرسش خود در کانال بمانید تا شخصی به شما پاسخ دهد.

برای سایر ابزارهای virt (مواردی که همراه با libguestfs ارائه نمی‌شوند) یک فهرست ایمیل عمومی برای ابزارهای virt وجود دارد: https://www.redhat.com/mailman/listinfo/virt-tools-list

لطفاً از پیوند زیر برای ثبت باگ در Bugzilla استفاده کنید:

https://bugzilla.redhat.com/enter_bug.cgi?component=libguestfs&product=Virtualization+Tools

تا حد امکان جزئیات و همچنین روشی برای بازتولید مشکل ارائه دهید.

خروجی کامل دستور libguestfs-test-tool(1) را نیز ضمیمه کنید.

همچنین بخش “LIBGUESTFS GOTCHAS” را در guestfs(3) برای برخی نکات فنی و ظرافت‌های استفاده از API مربوط به libguestfs بررسی کنید.

این خطای مبهم در واقع یک شکست در SELinux است. باید متغیر بولی (boolean) زیر را در SELinux فعال کنید:

setsebool -P virt_use_execmem=on

برای اطلاعات بیشتر ببینید: https://bugzilla.redhat.com/show_bug.cgi?id=806106

[این پیام خطا در libguestfs 1.21.18 به متنی گویاتر تغییر یافته است.]

این خطا نشان می‌دهد که qemu شکست خورده یا هستهٔ میزبان (host kernel) نتوانسته بوت شود. برای کسب اطلاعات بیشتر دربارهٔ علت خطا، باید دستور زیر را اجرا کنید:

libguestfs-test-tool

اگر پس از اجرای این ابزار همچنان علت خطا را متوجه نشدید، با ما تماس بگیرید (بخش قبلی را ببینید).

[این مشکل به‌صورت دائمی در libguestfs ≥ 1.26 برطرف شده است.]

اگر با هر یک از این خطاها در Debian/Ubuntu مواجه شدید، باید فرمان زیر را اجرا کنید:

sudo update-guestfs-appliance

هنگام باز کردن تصویر دیسک (disk image)، حتی با وجود اینکه libguestfs را با دسترسی ریشه (root) اجرا می‌کنید، خطای عدم دسترسی (permission denied) دریافت می‌کنید.

این مشکل از جانب libvirt رخ می‌دهد و بنابراین تنها هنگام استفاده از بک‌اند libvirt اتفاق می‌افتد. هنگامی که برنامه با دسترسی ریشه اجرا می‌شود، libvirt تصمیم می‌گیرد appliance متعلق به qemu را با کاربر "qemu.qemu" اجرا کند. متأسفانه این وضعیت معمولاً به این معنی است که qemu نمی‌تواند تصاویر دیسک را باز کند، به‌ویژه اگر مالکیت آن تصاویر متعلق به root باشد، یا در دایرکتوری‌هایی قرار داشته باشند که نیازمند دسترسی root است.

یک گزارش باگ برای رفع این مشکل در libvirt باز است: https://bugzilla.redhat.com/show_bug.cgi?id=1045069

می‌توانید با یکی از روش‌های زیر این مشکل را دور بزنید:

  • تغییر به بک‌اند مستقیم (direct backend):
    export LIBGUESTFS_BACKEND=direct
  • اجرا نکردن libguestfs با کاربر ریشه (root).
  • تغییر سطح دسترسی (chmod) تصویر دیسک و دایرکتوری‌های والد آن به‌گونه‌ای که کاربر qemu بتواند به آن‌ها دسترسی داشته باشد.
  • (روش نامطلوب) ویرایش /etc/libvirt/qemu.conf و تغییر مقدار تنظیم "user".

نکته: اگر این خطا هنگام استفاده از بستهٔ توزیع libguestfs (مانند Fedora، Debian و غیره) رخ دهد، یک گزارش باگ برای آن توزیع ثبت کنید. این خطایی نیست که کاربران عادی در صورت آماده‌سازی صحیح بستهٔ توزیع با آن مواجه شوند.

این خطا در طول مرحلهٔ بوت supermin هنگام راه‌اندازی appliance رخ می‌دهد:

supermin: mounting new root on /root
supermin: chroot
execl: /init: Permission denied
supermin: debug: listing directory /
[...followed by a lot of debug output...]

این یک باگ پیچیده مربوط به applianceهای supermin(1) است. این appliance با کپی کردن فایل‌هایی مانند /bin/bash و کتابخانه‌های متعدد از سیستم میزبان ساخته می‌شود. فایل "hostfiles" فهرستی از فایل‌هایی را که باید از سیستم میزبان به درون appliance کپی شوند تعیین می‌کند. اگر برخی از فایل‌ها روی سیستم میزبان وجود نداشته باشند نادیده گرفته می‌شوند، اما در صورتی که این فایل‌ها برای (مثلاً) اجرای /bin/bash ضروری باشند، خطای بالا را مشاهده خواهید کرد.

عیب‌یابی این مشکل نیازمند بررسی کتابخانه‌های مورد نیاز /bin/bash است، یعنی:

ldd /bin/bash

و مقایسهٔ آن با "hostfiles"، با فایل‌های واقعاً موجود در فایل‌سیستم میزبان، و با خروجی اشکال‌زدایی چاپ‌شده در پیام خطا. زمانی که متوجه شدید کدام فایل مفقود شده است، آن فایل را با استفاده از مدیر بستهٔ خود نصب کرده و دوباره امتحان کنید.

همچنین باید بررسی کنید که فایل‌هایی مانند /init و /bin/bash (درون appliance) قابل اجرا (executable) باشند. خروجی اشکال‌زدایی، حالت‌های دسترسی فایل (file modes) را نشان می‌دهد..SH "بارگیری، نصب و کامپایل LIBGUESTFS (DOWNLOADING, INSTALLING, COMPILING LIBGUESTFS)"

استفاده کنید از:
yum install '*guestf*'

برای آخرین ساخت‌ها، ببینید: http://koji.fedoraproject.org/koji/packageinfo?packageID=8391

این بسته بخشی از نصب پیش‌فرض است. تنها در RHEL 6 و 7 باید "libguestfs-winsupport" را برای دریافت پشتیبانی از مهمان Windows نصب کنید.
برای libguestfs < 1.26، پس از نصب libguestfs باید این دستور را اجرا کنید:
sudo update-guestfs-appliance

(این اسکریپت در Debian/Ubuntu با libguestfs ≥ 1.26 حذف شده است و در عوض اپلاینس بنا بر تقاضا ساخته می‌شود.)

تنها در Ubuntu:

sudo chmod 0644 /boot/vmlinuz*

ممکن است لازم باشد خود را به گروه "kvm" اضافه کنید:

sudo usermod -a -G kvm yourlogin
‏Hilko Bengen بسته libguestfs را در squeeze backports ساخته است: http://packages.debian.org/search?keywords=guestfs&searchon=names&section=all&suite=squeeze-backports
‏Hilko Bengen از libguestfs در Debian پشتیبانی می‌کند. بسته‌های رسمی Debian در دسترس هستند: http://packages.debian.org/search?keywords=libguestfs
ما نگه‌دارنده تمام‌وقتی برای Ubuntu نداریم، و بسته‌های ارائه‌شده توسط Canonical (که خارج از کنترل ما هستند) گاهی اوقات معیوب هستند.

شرکت Canonical تصمیم گرفت مجوزهای هسته را طوری تغییر دهد که به جز کاربر ریشه (root) قابل خواندن نباشد. این کار کاملاً احمقانه است، اما آن‌ها آن را تغییر نخواهند داد (https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725). بنابراین هر کاربری باید این کار را انجام دهد:

sudo chmod 0644 /boot/vmlinuz*
Ubuntu 12.04
‏libguestfs در این نسخه از Ubuntu کار می‌کند، اما لازم است febootstrap و seabios را به آخرین نسخه‌ها به‌روزرسانی کنید.

شما به febootstrap ≥ 3.14-2 از نشانی زیر نیاز دارید: http://packages.ubuntu.com/precise/febootstrap

پس از نصب یا به‌روزرسانی febootstrap، اپلاینس را بازسازی کنید:

sudo update-guestfs-appliance

شما به seabios ≥ 0.6.2-0ubuntu2.1 یا ≥ 0.6.2-0ubuntu3 از نشانی‌های زیر نیاز دارید: http://packages.ubuntu.com/precise-updates/seabios یا http://packages.ubuntu.com/quantal/seabios

همچنین باید این کار را انجام دهید (بالا را ببینید):

sudo chmod 0644 /boot/vmlinuz*
پروژه Libguestfs در 2012-07 توسط Andreis Vinogradovs (بخش libguestfs) و Maxim Koltsov (عمدتاً hivex) به Gentoo اضافه شد. اجرا کنید:
emerge libguestfs
پروژه Libguestfs در 2013-08 به Mageia اضافه شد. اجرا کنید:
urpmi libguestfs
پروژه Libguestfs در سال ۲۰۱۲ توسط Olaf Hering به SuSE اضافه شد.
پروژه Libguestfs در سال ۲۰۱۰ به AUR اضافه شد.
سایر توزیع‌های لینوکس
از سورس کامپایل کنید (بخش بعدی).
سایر توزیع‌های غیرلینوکسی
باید آن را از سورس کامپایل کرده و پورت کنید..SS "چگونه می‌توانم libguestfs را از کد مبدأ کامپایل و نصب کنم؟" شما می‌توانید libguestfs را از git یا یک tarball کد مبدأ کامپایل کنید. پیش از شروع، فایل README را بخوانید.

مخزن Git: https://github.com/libguestfs/libguestfs فایل‌های فشرده مبدأ (tarballs): http://libguestfs.org/download

دستور "make install" را اجرا نکنید! در عوض از اسکریپت "./run" استفاده کنید (README را ببینید).

کتابخانه libguestfs به supermin 5 نیاز دارد. اگر supermin 5 برای توزیع شما پورت نشده است، پرسش زیر را بررسی کنید.

ابتدا qemu،‏ supermin و/یا kernel را از کد مبدأ کامپایل کنید. شما نیازی ندارید که آن‌ها را "make install" کنید.

در دایرکتوری کد مبدأ libguestfs، دو فایل بسازید. فایل "localconfigure" باید شامل موارد زیر باشد:

source localenv
#export PATH=/tmp/qemu/x86_64-softmmu:$PATH
./configure --prefix /usr "$@"

فایل "localconfigure" را قابل اجرا کنید.

فایل "localenv" باید حاوی موارد زیر باشد:

#export SUPERMIN=/tmp/supermin/src/supermin
#export LIBGUESTFS_HV=/tmp/qemu/x86_64-softmmu/qemu-system-x86_64
#export SUPERMIN_KERNEL=/tmp/linux/arch/x86/boot/bzImage
#export SUPERMIN_KERNEL_VERSION=4.XX.0
#export SUPERMIN_MODULES=/tmp/lib/modules/4.XX.0

این خطوط را بر حسب نیاز برای استفاده از برنامه‌های جایگزینی که کامپایل کرده‌اید، از حالت کامنت خارج و تنظیم کنید.

به جای "./configure" از "./localconfigure" استفاده کنید، اما در باقی موارد libguestfs را مانند همیشه کامپایل کنید.

دستور "make install" را اجرا نکنید! در عوض از اسکریپت "./run" استفاده کنید (README را ببینید).

اگر supermin 5 از توزیع شما پشتیبانی می‌کند، اما شما تصادفاً نسخه به اندازه کافی جدیدی از supermin را نصب ندارید، پرسش پیشین را ببینید.

اگر supermin 5 اصلاً از توزیع شما پشتیبانی نمی‌کند، باید از «روش appliance ثابت» (fixed appliance method) استفاده کنید که در آن از یک appliance باینری از پیش کامپایل‌شده استفاده می‌شود. برای ساخت libguestfs بدون supermin، باید گزینهٔ "--disable-appliance --disable-daemon" را به ./configure یا ./configure ارسال کنید (بسته به این که به ترتیب از git می‌سازید یا از tarballها). سپس هنگام استفاده از libguestfs، باید متغیر محیطی "LIBGUESTFS_PATH" را روی دایرکتوری appliance از پیش کامپایل‌شده تنظیم کنید، همان‌طور که در بخش "FIXED APPLIANCE" در guestfs-internals(1) نیز شرح داده شده است.

برای applianceهای از پیش کامپایل‌شده، همچنین ببینید: http://libguestfs.org/download/binaries/appliance

وصله‌ها (Patches) برای پورت کردن supermin به توزیع‌های بیشتر لینوکس با استقبال پذیرفته می‌شوند.

نکته برای کاربران Fedora/RHEL: این پیکربندی از Fedora 18 و RHEL 7 به صورت پیش‌فرض فعال است. اگر با مشکلی مواجه شدید، لطفاً به ما اطلاع دهید یا یک باگ گزارش کنید.

قابلیت sVirt با استفاده از SELinux یک appliance سخت‌سازی‌شده (hardened) را فراهم می‌کند، که فرار (escape) یک ایمیج دیسک سرکش را از محیط قرنطینهٔ libguestfs و آسیب زدن به میزبان بسیار دشوار می‌سازد (منصفانه است بگوییم که حتی در حالت استاندارد libguestfs نیز این امر سخت خواهد بود، اما sVirt یک لایه حفاظتی اضافه برای میزبان ایجاد می‌کند و مهم‌تر از آن، ماشین‌های مجازی مستقر بر روی همان میزبان را از یکدیگر محافظت می‌کند).

در حال حاضر برای فعال کردن sVirt به libvirt نسخهٔ ۰.۱۰.۲ یا بالاتر (ترجیحاً نسخهٔ ۱.۰ یا جدیدتر)، libguestfs نسخهٔ ۱.۲۰ یا بالاتر، و خط‌مشی‌های SELinux نسخه‌های اخیر Fedora نیاز دارید. اگر از Fedora 18+ استفاده نمی‌کنید، باید تغییراتی در خط‌مشی SELinux خود اعمال کنید - از طریق لیست پستی با ما در تماس باشید.

پس از فراهم کردن پیش‌نیازها، این دستورها را اجرا کنید:

./configure --with-default-backend=libvirt       # libguestfs >= 1.22
./configure --with-default-attach-method=libvirt # libguestfs <= 1.20
make

سیستم SELinux را روی حالت Enforcing تنظیم کنید؛ پس از آن sVirt باید به طور خودکار به کار گرفته شود.

تمام، یا تقریباً تمام ویژگی‌های libguestfs باید تحت sVirt کار کنند. یک کاستی شناخته‌شده وجود دارد: virt-rescue(1) از libvirt (و در نتیجه sVirt) استفاده نخواهد کرد، بلکه به اجرای مستقیم qemu بازمی‌گردد. بنابراین در حال حاضر هنگام استفاده از virt-rescue از مزایای حفاظتی sVirt بهره‌مند نخواهید شد.

می‌توانید با فعال کردن گزارش‌گیری libvirtd (مسیر /etc/libvirt/libvirtd.log را ببینید)، متوقف کردن و راه‌اندازی مجدد libvirtd، و بررسی فایل‌های لاگ برای پیام‌های "Setting SELinux context on ..." استفاده شدن sVirt را بررسی کنید.

از نظر تئوری sVirt باید از AppArmor پشتیبانی کند، اما ما آن را آزمایش نکرده‌ایم. این کار تقریباً به طور قطع نیازمند وصله زدن libvirt و نگارش یک خط‌مشی AppArmor خواهد بود.

کتابخانه اصلی وابستگی‌های زیادی ندارد، اما سه دلیل برای وجود این فهرست طولانی از دیگر وابستگی‌ها وجود دارد:

1.
ابزار libguestfs باید بتواند قالب‌های بسیار متفاوتی از دیسک را خوانده و ویرایش کند. برای مثال، پشتیبانی از XFS به ابزارهای XFS نیاز دارد.
2.
بایندینگ‌ها (Language bindings) برای زبان‌های گوناگونی وجود دارند که همگی نیازمند ابزارهای توسعه مختص به خود هستند. تمامی بایندینگ‌های زبان‌ها (به جز C) اختیاری هستند.
3.
برخی ویژگی‌های اختیاری در کتابخانه وجود دارند که امکان غیرفعال کردن آن‌ها هست.

از نسخه libguestfs ≥ 1.26 تفکیک وابستگی‌های appliance (مورد ۱ در فهرست بالا) امکان‌پذیر شده است و در نتیجه می‌توان برای پردازش ایمیج‌های دیسک XFS به عنوان نمونه "libguestfs-xfs" را به عنوان یک زیربستهٔ مجزا در اختیار داشت. ما بسته‌بندهای پایین‌دست را تشویق می‌کنیم که تقسیم بسته اصلی libguestfs به زیربسته‌های کوچک‌تر را آغاز کنند..SS "خطاها هنگام راه‌اندازی در Fedora ≥ 18 و RHEL ≥ 7" در Fedora ≥ 18 و RHEL ≥ 7، libguestfs از libvirt برای مدیریت appliance استفاده می‌کند. پیش‌تر (و در upstream)، libguestfs نرم‌افزار qemu را مستقیماً اجرا می‌کرد:

┌──────────────────────────────────┐
│ libguestfs                       │
├────────────────┬─────────────────┤
│ direct backend │ libvirt backend │
└────────────────┴─────────────────┘
       ↓                  ↓
   ┌───────┐         ┌──────────┐
   │ qemu  │         │ libvirtd │
   └───────┘         └──────────┘
                          ↓
                      ┌───────┐
                      │ qemu  │
                      └───────┘

   upstream          Fedora 18+
   non-Fedora         RHEL 7+
   non-RHEL

بک‌اند libvirt پیشرفته‌تر است و از SELinux/sVirt (به بالا مراجعه کنید) و موارد دیگر پشتیبانی می‌کند. با این حال، پیچیده‌تر بوده و در نتیجه پایداری کمتری دارد.

اگر هنگام استفاده از بک‌اند libvirt با مشکلات مجوز مواجه شدید، می‌توانید با تنظیم این متغیر محیطی:

export LIBGUESTFS_BACKEND=direct

پیش از اجرای هر برنامه libguestfs یا ابزار virt، به بک‌اند direct سوییچ کنید.

این کار ممکن است پایداری و کارایی libguestfs را در Fedora و RHEL بهبود بخشد.

در هر زمانی پس از نصب libguestfs، دستورهای زیر را به عنوان ریشه (root) اجرا کنید:

mkdir -p /usr/local/lib/guestfs/appliance
libguestfs-make-fixed-appliance /usr/local/lib/guestfs/appliance
ls -l /usr/local/lib/guestfs/appliance

اکنون متغیر محیطی زیر را پیش از استفاده از libguestfs یا هر ابزار virt تنظیم نمایید:

export LIBGUESTFS_PATH=/usr/local/lib/guestfs/appliance

البته می‌توانید مسیر را به هر دایرکتوری که می‌خواهید تغییر دهید. شما می‌توانید appliance را میان ماشین‌هایی با معماری یکسان (مثلاً همگی x86-64) به اشتراک بگذارید، اما توجه داشته باشید که libvirt به دلیل مشکلات مجوز دسترسی، مانع از اشتراک‌گذاری appliance روی NFS خواهد شد (بنابراین یا به بک‌اند direct سوییچ کنید یا از NFS استفاده نکنید).

با اختلاف، مهم‌ترین کاری که می‌توانید انجام دهید نصب و پیکربندی مناسب Squid است. توجه داشته باشید که پیکربندی پیش‌فرضی که همراه با Squid عرضه می‌شود بسیار ناکارآمد است، بنابراین پیکربندی آن اختیاری نیست.

نقطه شروع بسیار مناسب برای پیکربندی Squid در این نشانی قرار دارد: https://fedoraproject.org/wiki/Extras/MockTricks#Using_Squid_to_Speed_Up_Mock_package_downloads

اطمینان حاصل کنید که Squid در حال اجرا است و متغیرهای محیطی $http_proxy و $ftp_proxy به آن اشاره دارند.

با اجرای Squid و پیکربندی درست آن، زمان ساخت appliance باید به چند دقیقه کاهش یابد.

چگونه می‌توانم سرعت ساخت libguestfs را در دبیان (Debian) افزایش دهم؟

هیلکو بنگن (Hilko Bengen) پیشنهاد می‌کند از "approx" که یک پروکسی آرشیو دبیان است استفاده کنید (http://packages.debian.org/approx). این ابزار در دبیان در صفحه راهنمای approx(8) مستند شده است.

نکته: بیشتر اطلاعات این بخش جابجا شده است: guestfs-performance(1).

اگر دیسک زیرین به طور کامل تخصیص نیافته باشد (مثلاً sparse raw یا qcow2)، عملیات نوشتن ممکن است کُند باشد چرا که سیستم‌عامل میزبان هنگام نوشتن شما، ناچار به انجام تخصیص‌های پرهزینه دیسک است. راه‌حل این است که در عوض از قالبی کاملاً تخصیص‌یافته استفاده کنید؛ یعنی non-sparse raw، یا qcow2 همراه با گزینه "preallocation=metadata".

ابزار libguestfs یک appliance نسبتاً بزرگ را در این مسیر کش می‌کند:

/var/tmp/.guestfs-<UID>

اگر متغیر محیطی "TMPDIR" تعریف شده باشد، به جای آن از $TMPDIR/.guestfs-<UID> استفاده می‌شود.

هنگامی که از libguestfs استفاده نمی‌کنید، حذف این دایرکتوری کاملاً بی‌خطر است.

اگر ورودی به virt-sparsify(1) از نوع raw باشد، آنگاه خروجی به صورت raw sparse خواهد بود. مطمئن شوید که خروجی را با ابزاری اندازه می‌گیرید که مفهوم تنک بودن (sparseness) را متوجه می‌شود، مانند "du -sh". این می‌تواند تفاوت بسیار چشمگیری ایجاد کند:

$ ls -lh test1.img
-rw-rw-r--. 1 rjones rjones 100M Aug  8 08:08 test1.img
$ du -sh test1.img
3.6M   test1.img

(اندازه ظاهری 100M را با اندازه واقعی 3.6M مقایسه کنید)

اگر این موضوع برای شما گیج‌کننده است، با تعیین گزینه --convert از یک قالب خروجی غیرتنک (non-sparse) استفاده نمایید؛ برای نمونه:

 virt-sparsify --convert qcow2 disk.raw disk.qcow2
تغییر اندازه یک ایمیج دیسک بسیار حساس و پیچیده است -- به‌ویژه اطمینان از اینکه داده‌ای از دست نرود یا به بوت‌لودر آسیبی نرسد. روش فعلی عملاً یک ایمیج دیسک جدید می‌سازد و داده‌ها به همراه بوت‌لودر را از ایمیج قدیمی کپی می‌کند. اگر مشکلی پیش بیاید، همیشه می‌توانید به نسخه اصلی بازگردید.
اگر قرار بود کاری کنیم که virt-resize به صورت درجا (in-place) کار کند، محدودیت‌هایی به وجود می‌آمد: برای نمونه، اجازه جابه‌جایی پارتیشن‌های موجود را نداشتید (زیرا جابه‌جایی داده‌ها درون همان دیسک در صورت قطعی برق یا خرابی ناگهانی سیستم، به احتمال بسیار زیاد به خراب شدن داده‌ها می‌انجامد)، و پشتیبانی از LVM بسیار دشوار می‌بود (به دلیل نگاشت تقریباً دلخواه بین محتوای LV و بلوک‌های دیسک زیرین).
روش دیگری که در نظر گرفته‌ایم، قرار دادن یک اسنپ‌شات روی ایمیج دیسک اصلی است تا داده‌های اصلی دست‌نخورده باقی بمانند و فقط تغییرات در اسنپ‌شات ثبت شوند. امروزه می‌توانید با استفاده از "qemu-img create" + "virt-resize" این کار را انجام دهید، اما qemu در حال حاضر آن‌قدر هوشمند نیست که تشخیص دهد چه زمانی همان بلوکی که از قبل در دیسک پشتیبان وجود دارد مجدداً روی اسنپ‌شات نوشته می‌شود، بنابراین متوجه خواهید شد که این روش هیچ فضا یا زمانی برای شما صرفه‌جویی نمی‌کند.
به طور خلاصه، این مسئله‌ای دشوار است، و روشی که اکنون داریم عمدتاً به درستی کار می‌کند، بنابراین تمایلی به تغییر آن نداریم.

در libguestfs نسخه ۱.۲۶ و جدیدتر (libguestfs ≥ 1.26)، اکنون virt-sparsify می‌تواند روی ایمیج‌های دیسک به صورت درجا کار کند. استفاده کنید از:

virt-sparsify --in-place disk.img

اما ابتدا باید بخش “IN-PLACE SPARSIFICATION” را در virt-sparsify(1) مطالعه کنید.

باز کردن سیستم‌های مهمان دوردست libvirt در حال حاضر پشتیبانی نمی‌شود. برای نمونه این دستور کار نخواهد کرد:

guestfish -c qemu://remote/system -d Guest

برای باز کردن دیسک‌های راه دور باید به نحوی آن‌ها را صادر (export) کنید و سپس به خروجی صادرشده متصل شوید. برای نمونه اگر تصمیم گرفتید از NBD استفاده کنید:

remote$ qemu-nbd -t -p 10809 guest.img
 local$ guestfish -a nbd://remote:10809 -i

امکانات دیگر شامل ssh (اگر نسخه qemu به اندازه کافی جدید باشد)، NFS یا iSCSI است. بخش “REMOTE STORAGE” را در guestfs(3) ببینید.

شما یک ایمیج دیسک دارید که داخل سیستم دیگری قرار گرفته است و نیازمند دسترسی از طریق یک کتابخانه / HTTP / REST / API اختصاصی است، یا به شکلی فشرده یا آرشیو شده است. (یک نمونه، دسترسی از راه دور به ایمیج‌های glance در OpenStack بدون دانلود واقعی آن‌ها است.)

ما یک پروژه هم‌خانواده به نام nbdkit (https://github.com/libguestfs/nbdkit) داریم. این پروژه به شما امکان می‌دهد هر منبع دیسکی را به یک سرور NBD تبدیل کنید. Libguestfs می‌تواند مستقیماً به سرورهای NBD دسترسی داشته باشد، به عنوان مثال:

guestfish -a nbd://remote

پروژه nbdkit دارای مجوز آزاد و آسان‌گیر است، بنابراین می‌توانید آن را با کتابخانه‌ها و کدهای تجاری/اختصاصی پیوند داده یا درون آن‌ها بگنجانید. همچنین دارای یک API پایدار و ساده برای افزونه‌ها است، در نتیجه می‌توانید به سادگی افزونه‌هایی برای این API بنویسید که در آینده نیز به کار خود ادامه دهند.

برنامه Qemu (و در نتیجه libguestfs) تنها از برخی ایمیج‌های دیسک خاص VMDK پشتیبانی می‌کند. سایر ایمیج‌ها کار نخواهند کرد و این خطا یا خطاهای مشابه را بازمی‌گردانند.

در حالت ایده‌آل باید کسی qemu را برای پشتیبانی از جدیدترین ویژگی‌های VMDK اصلاح کند، اما در این فاصله شما سه گزینه پیش رو دارید:

1.
اگر مهمان روی یک سرور ESX فعال و در دسترس میزبانی می‌شود، ایمیج دیسکی به نام somename-flat.vmdk را پیدا کرده و دانلود کنید. علی‌رغم این نام، این یک ایمیج دیسک خام (raw) است و توسط هر ابزاری باز می‌شود.

اگر نسخه به اندازه کافی جدیدی از qemu و libguestfs در اختیار دارید، ممکن است بتوانید با استفاده از HTTPS یا ssh به این ایمیج دیسک از راه دور دسترسی پیدا کنید. بخش “REMOTE STORAGE” را در guestfs(3) ببینید.

2.
از ابزار اختصاصی vdiskmanager متعلق به VMware برای تبدیل ایمیج به قالب خام (raw) استفاده کنید.
3.
از nbdkit به همراه افزونه اختصاصی VDDK برای صادر کردن زنده (live export) ایمیج دیسک به عنوان یک منبع NBD استفاده کنید. این کار باید به شما امکان خواندن و نوشتن روی فایل VMDK را بدهد.

قالب سیستم‌فایل UFS گونه‌های متعددی دارد که خودشناسا (self-identifying) نیستند. باید به هسته لینوکس مشخصاً گفته شود که از کدام گونه UFS استفاده کند، چیزی که libguestfs قادر به دانستن آن نیست.

هنگام سوار کردن این سیستم‌فایل‌ها باید گزینه سوار کردن مناسب "ufstype" را مشخص کنید.

صفحه https://www.kernel.org/doc/Documentation/filesystems/ufs.txt را ببینید.

سیستم‌فایل Windows ReFS نسخه مایکروسافت از روی ZFS/Btrfs است. این سیستم‌فایل هنوز مهندسی معکوس نشده و در هسته لینوکس پیاده‌سازی نشده است، بنابراین libguestfs از آن پشتیبانی نمی‌کند. در حال حاضر به نظر می‌رسد استفاده از آن در دنیای واقعی بسیار نادر باشد.

نشانه‌های متداول این مشکل:

  • هنگام ایجاد فایلی که نام آن شامل نویسه‌های غیر ASCII است، به‌ویژه نویسه‌های غیر ۸ بیتی زبان‌های آسیایی (چینی، ژاپنی و غیره) با خطا مواجه می‌شوید. سیستم‌فایل VFAT است.
  • هنگامی که محتویات یک دایرکتوری را از سیستم‌فایل VFAT فهرست می‌کنید، نام فایل‌ها به صورت علامت سؤال ظاهر می‌شوند.

این یک نقص طراحی در سیستم گنو/لینوکس (GNU/Linux) است.

سیستم‌فایل VFAT نام‌های طولانی فایل‌ها را به صورت نویسه‌های UTF-16 ذخیره می‌کند. هنگام باز کردن یا برگرداندن نام فایل‌ها، هسته لینوکس باید این نام‌ها را به نوعی از رشته‌های ۸ بیتی ترجمه کند. انتخاب بدیهی UTF-8 خواهد بود، به استثنای کاربران لینوکسی که بر استفاده از تنظیمات محلی (locales) غیر UTF-8 اصرار دارند (تنظیمات محلی کاربر برای هسته ناشناخته است زیرا تابعی از libc به شمار می‌رود).

بنابراین هنگام سوار کردن سیستم‌فایل، باید به هسته بگویید چه ترجمه‌ای را می‌خواهید انجام دهد. دو روش برای این کار وجود دارد: پارامتر "iocharset" (که به libguestfs مربوط نمی‌شود) و پرچم "utf8".

بنابراین برای استفاده از یک سیستم‌فایل VFAT باید در زمان سوار کردن، پرچم "utf8" را اضافه کنید. در guestfish، استفاده کنید از:

><fs> mount-options utf8 /dev/sda1 /

یا در خط فرمان guestfish:

guestfish [...] -m /dev/sda1:/:utf8

یا از طریق API:

guestfs_mount_options (g, "utf8", "/dev/sda1", "/");

سپس هسته، نام فایل‌ها را به رشته‌های UTF-8 و برعکس ترجمه خواهد کرد.

ما افزودن خودکار و شفاف این گزینه سوار کردن را در نظر گرفتیم، اما متأسفانه در انجام این کار چند مشکل وجود دارد:

  • در برخی از سیستم‌های لینوکس، گزینه سوار کردن "utf8" کار نمی‌کند. ما دقیقاً نمی‌دانیم چه سیستم‌هایی یا چرا، اما این موضوع به صورت موثق توسط یک کاربر گزارش شده است.
  • این کار مانع از استفاده شما از پارامتر "iocharset" می‌شود زیرا با "utf8" ناسازگار است. استفاده از این پارامتر احتمالاً ایده خوبی نیست، اما ما نمی‌خواهیم مانع از انجام آن شویم..SS "نویسه‌های غیر ASCII در سیستم‌های فایل ISO9660 به شکل زیرخط (_) نمایش داده می‌شوند." سیستم فایل به‌درستی با mkisofs یا genisoimage آماده نشده است. اطمینان حاصل کنید که سیستم فایل با استفاده از افزونه‌های Joliet و/یا Rock Ridge ایجاد شده باشد. libguestfs برای مدیریت سیستم فایل به هیچ گزینهٔ ویژهٔ سوار کردنی (mount) نیاز ندارد.

خطاهایی شبیه به این مشاهده می‌کنید:

mount: unknown filesystem type 'ntfs'

در Red Hat Enterprise Linux یا CentOS < 7.2، باید بستهٔ libguestfs-winsupport را نصب کنید. در RHEL ≥ 7.2، بستهٔ "libguestfs-winsupport" بخشی از توزیع پایهٔ RHEL است، اما پرسش بعدی را ببینید.

در RHEL 7.2 توانستیم "libguestfs-winsupport" را به توزیع پایهٔ RHEL اضافه کنیم، اما مجبور شدیم قابلیت استفاده از آن برای باز کردن و ویرایش سیستم‌های فایل را غیرفعال کنیم. این قابلیت تنها هنگام استفاده با virt-v2v(1) پشتیبانی می‌شود. اگر سعی کنید از guestfish(1) یا guestmount(1) یا برخی برنامه‌های دیگر روی یک سیستم فایل NTFS استفاده کنید، این خطا را خواهید دید:

mount: unsupported filesystem type

این یک پیکربندی پشتیبانی‌نشده است و در RHEL به کار انداخته نخواهد شد. زحمت گزارش باگ برای آن را به خود ندهید، چرا که بلافاصله وضعیت آن به "CLOSED -> WONTFIX" تغییر خواهد کرد.

می‌توانید libguestfs را خودتان کامپایل کرده و این محدودیت را حذف کنید، اما این کار مورد تأیید یا پشتیبانی Red Hat نخواهد بود.

مهمان‌های RHEL 7 و هر مهمان دیگری که از XFS استفاده می‌کند توسط libguestfs قابل باز شدن هستند، اما باید بستهٔ "libguestfs-xfs" را نصب کنید.

پیشنهاد می‌کنیم با خواندن نمای کلی API شروع کنید: “API OVERVIEW” در guestfs(3).

اگرچه نمای کلی API به بررسی C API می‌پردازد، اما حتی اگر قصد دارید از زبان برنامه‌نویسی دیگری استفاده کنید نیز ارزش خواندن دارد؛ زیرا این API یکسان است و تنها تغییرات منطقی ساده‌ای در نام فراخوانی‌ها اعمال شده است:

                C  guestfs_ln_sf (g, target, linkname);
           Python  g.ln_sf (target, linkname);
            OCaml  g#ln_sf target linkname;
             Perl  $g->ln_sf (target, linkname);
Shell (guestfish)  ln-sf target linkname
              PHP  guestfs_ln_sf ($g, $target, $linkname);

پس از آشنایی با نمای کلی API، باید به این فهرست از نقاط شروع برای اتصالات (bindings) سایر زبان‌ها نگاهی بیندازید: “USING LIBGUESTFS WITH OTHER PROGRAMMING LANGUAGES” در guestfs(3).

به طور کلی، بله. با این حال این یک مشاورهٔ حقوقی نیست - مجوزی را که همراه با libguestfs ارائه می‌شود بخوانید، و اگر سؤال خاصی دارید با یک وکیل تماس بگیرید.

در درخت سورس‌کد، مجوز در فایل "COPYING.LIB" (مجوز LGPLv2+ برای کتابخانه و اتصالات) و "COPYING" (مجوز GPLv2+ برای برنامه‌های مستقل) قرار دارد.

اگر به نظر می‌رسد هیچ برنامهٔ libguestfs اصلاً کار نمی‌کند، برنامهٔ زیر را اجرا کرده و خروجی کامل و ویرایش‌نشده را در قالب ایمیلی به "guestfs@lists.libguestfs.org" ارسال نمایید:

libguestfs-test-tool

اگر عملیات خاصی با شکست مواجه شد، تمام اطلاعات موجود در این چک‌لیست را در ایمیلی به "libguestfs" @ "redhat.com" ارائه دهید:

1.
قصد دارید چه کاری انجام دهید؟
2.
دقیقاً چه دستور(هایی) را اجرا کردید؟
3.
خطا یا خروجی دقیق این دستورها چه بود؟
4.
اشکال‌زدایی را فعال کرده، دستورها را مجدداً اجرا کنید و خروجی کامل را ضبط کنید. خروجی را ویرایش نکنید.
export LIBGUESTFS_DEBUG=1
export LIBGUESTFS_TRACE=1
5.
نسخهٔ libguestfs، نسخهٔ سیستم‌عامل و نحوهٔ نصب libguestfs (مانند از سورس‌کد، "yum install" و غیره) را قید کنید.

دو متغیر محیطی "LIBGUESTFS_*" وجود دارند که می‌توانید برای دریافت اطلاعات بیشتر از libguestfs آنها را تنظیم کنید.

"LIBGUESTFS_TRACE"
این را روی 1 تنظیم کنید تا libguestfs هر دستور / فراخوانی API را در قالبی شبیه به دستورهای guestfish چاپ کند.
"LIBGUESTFS_DEBUG"
این را روی 1 تنظیم کنید تا مقادیر انبوهی از پیام‌های اشکال‌زدایی فعال شوند. اگر فکر می‌کنید مشکلی در appliance داخلی libguestfs وجود دارد، باید از این گزینه استفاده کنید.

برای تنظیم این‌ها از طریق شل، قبل از اجرای برنامه این کار را انجام دهید:

export LIBGUESTFS_TRACE=1
export LIBGUESTFS_DEBUG=1

برای csh/tcsh دستورهای معادل عبارتند از:

setenv LIBGUESTFS_TRACE 1
setenv LIBGUESTFS_DEBUG 1

برای کسب اطلاعات بیشتر، ببینید: “ENVIRONMENT VARIABLES” در guestfs(3)..SS "چگونه هنگام استفاده از guestfish اشکال‌زدایی کنم؟" می‌توانید از همان متغیرهای محیطی ذکر شده در بالا استفاده کنید. همچنین می‌توانید از گزینه‌های guestfish شامل -x (برای ردگیری دستورات) یا -v (برای دریافت خروجی کامل اشکال‌زدایی)، یا هر دو استفاده کنید.

برای اطلاعات بیشتر، ببینید: guestfish(1).

برای فعال‌سازی ردگیری دستورات، "guestfs_set_trace" در guestfs(3) و/یا برای فعال‌سازی پیام‌های اشکال‌زدایی، "guestfs_set_verbose" در guestfs(3) را فراخوانی کنید.

برای بهترین نتیجه، این توابع را تا حد امکان زودتر فراخوانی کنید؛ در صورت امکان درست پس از ایجاد دستگیره (handle) guestfs، و قطعاً پیش از فراخوانی launch.

از API رویدادها (event API) استفاده کنید. برای نمونه‌ها، ببینید: "SETTING CALLBACKS TO HANDLE EVENTS" در guestfs(3) و برنامه examples/debug-logging.c در سورس‌های libguestfs.

اشکال‌زدایی را فعال کرده و سپس این مستندات را درباره فرایند راه‌اندازی اپلاینس بخوانید: guestfs-internals(1).

اشکال‌زدایی را فعال کرده و خروجی کامل را بررسی کنید. اگر نتوانستید متوجه شوید ماجرا از چه قرار است، یک گزارش باگ ارسال کنید که شامل خروجی کامل libguestfs-test-tool(1) باشد.

اگر از بک‌اند libvirt استفاده می‌کنید و libvirt با شکست مواجه می‌شود، می‌توانید با ویرایش /etc/libvirt/libvirtd.conf اشکال‌زدایی را فعال کنید.

اگر به عنوان کاربر غیرریشه (non-root) برنامه را اجرا می‌کنید، باید فایل دیگری را ویرایش کنید. فایل ~/.config/libvirt/libvirtd.conf را با محتوای زیر ایجاد کنید:

log_level=1
log_outputs="1:file:/tmp/libvirtd.log"

هر نشست libvirtd در حال اجرا (غیرریشه) را خاتمه دهید (kill کنید)، و دفعه بعد که دستور libguestfs را اجرا می‌کنید، حجم زیادی از اطلاعات اشکال‌زدایی مفید از libvirtd را در /tmp/libvirtd.log مشاهده خواهید کرد.

می‌توانید با مقداردهی برخی متغیرهای محیطی supermin، کرنل متفاوتی را برای اپلاینس انتخاب کنید:

export SUPERMIN_KERNEL_VERSION=4.8.0-1.fc25.x86_64
export SUPERMIN_KERNEL=/boot/vmlinuz-$SUPERMIN_KERNEL_VERSION
export SUPERMIN_MODULES=/lib/modules/$SUPERMIN_KERNEL_VERSION
rm -rf /var/tmp/.guestfs-*
libguestfs-test-tool

می‌توانید با تنظیم متغیر محیطی هایپروایزر، یک qemu متفاوت را انتخاب کنید:

export LIBGUESTFS_HV=/path/to/qemu-system-x86_64
libguestfs-test-tool

همچنین ببینید: guestfs-internals(1).

ما دستوری به نام guestmount(1) ارائه می‌دهیم که به شما امکان می‌دهد فایل‌سیستم‌های مهمان را روی سیستم میزبان سوار (mount) کنید. این به صورت یک ماژول FUSE پیاده‌سازی شده است. چرا به جای داشتن یک API بزرگ و نسبتاً پیچیده، کل libguestfs را تنها با استفاده از این سازوکار پیاده‌سازی نکنیم؟

دلایل آن دو بخش است. نخست، libguestfs فراخوانی‌های API برای انجام کارهایی مانند ایجاد و حذف پارتیشن‌ها و حجم‌های منطقی (logical volumes) ارائه می‌دهد که به سادگی درون یک مدل فایل‌سیستمی نمی‌گنجند. یا بهتر بگوییم، می‌شد آن‌ها را جا داد: به عنوان مثال، ایجاد یک پارتیشن می‌توانست به "mkdir /fs/hda1" نگاشت شود، اما آنگاه باید روشی برای تعیین اندازه پارتیشن مشخص می‌کردید (مثلاً "echo 100M > /fs/hda1/.size")، و همین‌طور نوع پارتیشن، سکتورهای شروع و پایان و غیره؛ اما به محض انجام چنین کاری، API مبتنی بر فایل‌سیستم پیچیده‌تر از API مبتنی بر فراخوانی فعلی به نظر خواهد رسید.

دلیل دوم، بازدهی و کارایی است. خود FUSE تا حد قابل قبولی کارآمد است، اما تعداد زیادی فراخوانی کوچک و مستقل به درون ماژول FUSE ارسال می‌کند. در guestmount این فراخوانی‌ها باید به پیام‌هایی برای اپلاینس libguestfs ترجمه شوند که سربار زیادی (از نظر زمان و رفت‌وبرگشت‌ها) ایجاد می‌کند. به عنوان مثال، خواندن یک فایل در تکه‌های ۶۴ کیلوبایتی ناکارآمد است زیرا هر تکه به یک رفت‌وبرگشت کامل تبدیل می‌شود. در API لایبرری libguestfs، دانلود کامل یک فایل یا دایرکتوری از طریق یکی از فراخوانی‌های جریانی (streaming) مانند "guestfs_download" یا "guestfs_tar_out" بسیار کارآمدتر است.

مشکلات مشابه مشکلات موجود در FUSE هستند.

سامانه GVFS انتزاع بهتری نسبت به POSIX/FUSE ارائه می‌دهد. یک بک‌اند FTP برای GVFS وجود دارد که دلگرم‌کننده است، چرا که FTP از نظر مفهومی مشابه API مربوط به libguestfs است. با این حال، بک‌اند FTP در GVFS به منظور حفظ تعاملی بودن، چندین اتصال هم‌زمان برقرار می‌کند؛ کاری که انجام آن به سادگی با libguestfs امکان‌پذیر نیست.

هنگامی که یک دیسک را به صورت فقط‌خواندنی (read-only) اضافه می‌کنید، libguestfs یک لایه روکش (overlay) قابل نوشتن روی دیسک زیرین قرار می‌دهد. عملیات نوشتن وارد این لایه روکش می‌شوند و هنگام بسته شدن دستگیره (یا خروج "guestfish" و غیره) دور ریخته می‌شوند.

دو دلیل برای این روش وجود دارد: نخست اینکه دیسک‌های فقط‌خواندنی در بسیاری از موارد امکان‌پذیر نیستند (برای نمونه IDE اساساً از آن‌ها پشتیبانی نمی‌کند، بنابراین نمی‌توانید یک دیسک شبیه‌سازی‌شده IDE فقط‌خواندنی داشته باشید، اگرچه این مورد در پیاده‌سازی‌های واقعی libguestfs رایج نیست).

دوم و مهم‌تر اینکه، حتی اگر دیسک‌های فقط‌خواندنی امکان‌پذیر بودند، شما آن‌ها را نمی‌خواستید. سوار کردن هر فایل‌سیستمی که ژورنال دارد، حتی با "mount -o ro";، موجب نوشتن روی فایل‌سیستم می‌شود زیرا ژورنال باید بازپخش شده و فراداده‌ها به‌روزرسانی شوند. اگر دیسک واقعاً فقط‌خواندنی بود، نمی‌توانستید یک فایل‌سیستم وضعیت‌خراب/کثیف (dirty) را سوار کنید.

برای اینکه دیسک قابل استفاده باشد، ما لایه روکش را به عنوان مکانی برای ذخیره موقت این عملیات‌های نوشتن ایجاد می‌کنیم و سپس آن را دور می‌ریزیم. این کار تضمین می‌کند که دیسک زیرین همواره دست‌نخورده باقی بماند.

همچنین توجه داشته باشید که هنگام ساختن libguestfs یک آزمون رگرسیون برای این موضوع وجود دارد (در "tests/qemu"). این یکی از دلایلی است که اجرای مجموعه آزمون‌ها برای بسته‌بندها اهمیت دارد.

خیر! گزینه "--ro" فقط بر دیسک‌هایی تأثیر می‌گذارد که از طریق خط فرمان اضافه شده‌اند، یعنی با استفاده از گزینه‌های "-a" و "-d".

در guestfish، اگر از دستور "add" استفاده کنید، دیسک به صورت خواندن-نوشتن اضافه می‌شود (مگر اینکه پرچم "readonly:true" را صراحتاً همراه با دستور مشخص کنید).

معمولاً این ایده خوبی نیست. این پرسش با جزئیات بیشتر در این ارسال لیست پستی پاسخ داده شده است: https://www.redhat.com/archives/libguestfs/2010-August/msg00024.html

همچنین پرسش بعدی را ببینید.

این دستور معمولاً کار نخواهد کرد:

guestfish --ro -a /dev/vg/my_root_fs run : fsck /dev/sda

دلیل این موضوع آن است که qemu یک اسنپ‌شات روی فایل‌سیستم اصلی ایجاد می‌کند، اما یک اسنپ‌شات دقیق در یک نقطه زمانی مشخص (point-in-time) ایجاد نمی‌کند. بلوک‌های داده روی فایل‌سیستم زیرین توسط qemu در زمان‌های متفاوتی همگام با پیشرفت عملیات fsck خوانده می‌شوند، در حالی که سیستم میزبان در این میان عملیات نوشتن انجام می‌دهد. نتیجه این است که fsck خرابی‌های عظیمی (تصوری و خیالی، نه واقعی!) مشاهده کرده و با شکست مواجه می‌شود.

کاری که باید انجام دهید ایجاد یک اسنپ‌شات در نقطه زمانی است. اگر یک حجم منطقی است، از یک اسنپ‌شات LVM2 استفاده کنید. اگر فایل‌سیستم درون موردی مانند یک فایل btrfs/ZFS قرار دارد، از اسنپ‌شات btrfs/ZFS استفاده کنید و سپس fsck را روی آن اسنپ‌شات اجرا نمایید. در عمل نیازی به استفاده از libguestfs برای این کار ندارید -- فقط /sbin/fsck را مستقیماً اجرا کنید.

ایجاد اسنپ‌شات‌های نقطه زمانی از دستگاه‌ها و فایل‌های میزبان خارج از حیطه عملکرد libguestfs است، اگرچه libguestfs می‌تواند پس از ایجاد شدن، روی آن‌ها عملیات انجام دهد..SS "تفاوت بین guestfish و virt-rescue چیست؟" بسیاری از افراد دربارهٔ دو ابزار به‌ظاهر مشابهی که ارائه می‌دهیم سردرگم می‌شوند:

$ guestfish --ro -a guest.img
><fs> run
><fs> fsck /dev/sda1
$ virt-rescue --ro guest.img
><rescue> /sbin/fsck /dev/sda1

و پرسش مرتبطی که در ادامه پیش می‌آید این است که چرا در guestfish نمی‌توان دستورهای کامل شل را به همراه همهٔ --options تایپ کرد (در حالی که در virt-rescue(1) این امکان وجود دارد).

guestfish(1) برنامه‌ای است که دسترسی ساخت‌یافته‌ای به APIِ guestfs(3) فراهم می‌کند. این ابزار به عنوان یک شل تعاملی مناسب نیز عمل می‌کند، اما هدف اصلی آن فراهم کردن دسترسی ساخت‌یافته از طریق اسکریپت‌های شل است. آن را بیشتر مانند یک بایندینگ زبان، شبیه بایندینگ‌های پایتون و زبان‌های دیگر، اما برای شل در نظر بگیرید. ویژگی متمایزکنندهٔ کلیدی guestfish (و به‌طور کلی APIِ libguestfs) توانایی خودکارسازی تغییرات است.

virt-rescue(1) روشی آزاد و بدون چارچوب ثابت برای راه‌اندازی اپلاینس libguestfs و اعمال تغییرات دلخواه روی VM شماست. این ابزار ساخت‌یافته نیست و نمی‌توانید آن را خودکارسازی کنید، اما برای انجام اصلاحات سریع و موردی (ad-hoc) روی سیستم‌های مهمان می‌تواند بسیار کاربردی باشد.

با این حال، libguestfs یک «در پشتی» (backdoor) نیز به درون اپلاینس دارد که امکان ارسال دستورهای دلخواه شل را به شما می‌دهد. این قابلیت به اندازهٔ virt-rescue منعطف نیست، زیرا نمی‌توانید با دستورهای شل تعامل برقرار کنید، اما به هر حال وجود دارد:

><fs> debug sh "cmd arg1 arg2 ..."

توجه داشته باشید که نباید به این ویژگی اتکا کنید. این قابلیت ممکن است در آینده تغییر کند یا حذف شود. اگر برنامهٔ شما به عملیات خاصی نیاز دارد، لطفاً در عوض آن را به APIِ libguestfs بیفزایید.

این پرسش‌ها همگی در سطحی بنیادین به یکدیگر مربوط می‌شوند که ممکن است در نگاه نخست آشکار نباشد.

در سطح APIِ guestfs(3)، یک «ایمیج دیسک» صرفاً توده‌ای از پارتیشن‌ها و فایل‌سیستم‌ها است.

در مقابل، زمانی که ماشین مجازی بوت می‌شود، آن فایل‌سیستم‌ها را در یک سلسله‌مراتب سازگار سوار (mount) می‌کند، مانند:

/          (/dev/sda2)
│
├── /boot  (/dev/sda1)
│
├── /home  (/dev/vg_external/Homes)
│
├── /usr   (/dev/vg_os/lv_usr)
│
└── /var   (/dev/vg_os/lv_var)

(یا حروف درایو در Windows).

این API در وهلهٔ اول ایمیج دیسک را در سطح «توده‌ای از فایل‌سیستم‌ها» می‌بیند. اما همچنین روشی برای بررسی (inspect) ایمیج دیسک دارد تا تشخیص دهد آیا حاوی یک سیستم‌عامل هست یا خیر، و اینکه دیسک‌ها هنگام بوت سیستم‌عامل چگونه سوار می‌شوند: به بخش "INSPECTION" در guestfs(3) مراجعه کنید.

کاربران انتظار دارند برخی ابزارها (مانند virt-cat(1)) با مسیرهای VM کار کنند:

virt-cat fedora.img /var/log/messages

ابزار virt-cat چگونه درمی‌یابد که /var یک پارتیشن جداگانه است؟ ترفند کار این است که virt-cat روی ایمیج دیسک عملیات بازرسی انجام می‌دهد و از آن برای ترجمهٔ صحیح مسیر بهره می‌برد.

برخی ابزارها (شامل virt-cat(1)، virt-edit(1) و virt-ls(1)) برای نگاشت مسیرهای VM از بازرسی استفاده می‌کنند. ابزارهای دیگر، مانند virt-df(1) و virt-filesystems(1)، کاملاً در سطح خام «تودهٔ بزرگ فایل‌سیستم‌ها»ی APIِ libguestfs عمل می‌کنند و بازرسی را به کار نمی‌برند.

ابزار guestfish(1) در موقعیت میانه‌ای جالب قرار دارد. اگر از گزینه‌های خط فرمان -a و -m استفاده کنید، باید دقیقاً به guestfish بگویید چگونه ایمیج‌های دیسک را بیفزاید و پارتیشن‌ها را در کجا سوار کند. این، همان سطح خام API است.

اگر از گزینهٔ -i استفاده نمایید، libguestfs عملیات بازرسی را انجام داده و فایل‌سیستم‌ها را برای شما سوار می‌کند.

خطای "no root device found in this operating system image" به این موضوع مربوط می‌شود. این پیام بدان معناست که بازرسی نتوانسته است هیچ سیستم‌عاملی را درون ایمیج دیسک ارائه‌شده بیابد. در صورتی که برنامه‌هایی مانند virt-cat را روی فایلی اجرا کنید که صرفاً یک ایمیج دیسک خام است و نه یک ایمیج ماشین مجازی، ممکن است با این پیام روبه‌رو شوید.

برخی توابع وجود دارند که برای اشکال‌زدایی و مقاصد داخلی به کار می‌روند و بخشی از API پایدار نیستند.

توابع "debug*" (یا "guestfs_debug*")، به‌ویژه "guestfs_debug" در guestfs(3) و شمار اندکی از توابع دیگر، برای اشکال‌زدایی libguestfs به کار می‌روند. اگرچه این توابع بخشی از API پایدار نیستند و بنابراین ممکن است در هر زمانی تغییر کرده یا حذف شوند، اما برخی برنامه‌ها ممکن است در حین انتظار برای افزوده‌شدن قابلیت‌ها به libguestfs مایل به فراخوانی آن‌ها باشند.

توابع "internal-*" (یا "guestfs_internal_*") صرفاً برای استفادهٔ خودِ libguestfs هستند. برنامه‌ها هیچ دلیلی برای فراخوانی آن‌ها ندارند و نباید تلاشی برای استفاده از آن‌ها به عمل آورند. به‌کارگیری آن‌ها نه تنها بخشی از API پایدار و مستند نیست، بلکه اغلب باعث بروز پیامدهای ناخواسته و مخرب خواهد شد..SH "توسعه‌دهندگان (DEVELOPERS)"

لطفاً وصله‌ها را به فهرست رایانامه libguestfs به نشانی https://lists.libguestfs.org ارسال کنید. نیازی نیست عضو فهرست باشید، اما تا زمانی که ارسالتان به‌صورت دستی تأیید شود، تأخیری وجود خواهد داشت.

لطفاً از pull requestهای github استفاده نکنید - نادیده گرفته خواهند شد. دلایل آن عبارتند از (الف) ما می‌خواهیم وصله‌ها را در فهرست رایانامه بحث و بررسی کنیم، و (ب) pull requestهای github به merge commit تبدیل می‌شوند اما ما داشتن یک تاریخچه خطی را ترجیح می‌دهیم.

قابلیت‌های جدید و بزرگی که قصد مشارکت در آن‌ها را دارید، ابتدا باید در فهرست رایانامه مورد بحث قرار گیرند (https://lists.libguestfs.org). این کار از ناامیدی و هدر رفتن زحمات، در صورتی که فکر کنیم قابلیت با پروژه libguestfs همخوانی ندارد، جلوگیری می‌کند.

اگر می‌خواهید قابلیت مفیدی را پیشنهاد دهید اما مایل به نوشتن کد آن نیستید، می‌توانید یک گزارش اشکال (بخش «GETTING HELP AND REPORTING BUGS» را ببینید) با عبارت "RFE: " در ابتدای خط خلاصه (Summary) ثبت کنید.

حدود ۵ نفر دسترسی commit به github دارند. وصله‌ها باید ابتدا در فهرست ارسال شده و ACK شوند. خط‌مشی ACK کردن و push کردن وصله‌ها در اینجا مشخص شده است:

https://www.redhat.com/archives/libguestfs/2012-January/msg00023.html

البته که می‌توانید. Git فورک کردن libguestfs را آسان می‌کند. Github آن را حتی آسان‌تر هم می‌کند. خوشحال می‌شویم اگر در فهرست رایانامه درباره فورک‌ها و دلایل آن‌ها به ما اطلاع دهید.

یک درخواست رایج این است که بتوان از libguestfs برای پایش فعالیت دیسک زنده یک مهمان استفاده کرد؛ برای نمونه، هر بار که مهمان یک فایل جدید ایجاد می‌کند مطلع شد. Libguestfs آن‌گونه که برخی تصور می‌کنند کار نمی‌کند، همان‌طور که در این نمودار می‌بینید:

           ┌─────────────────────────────────────┐
           │ monitoring program using libguestfs │
           └─────────────────────────────────────┘
                            ↓
┌───────────┐    ┌──────────────────────┐
│ live VM   │    │ libguestfs appliance │
├───────────┤    ├──────────────────────┤
│ kernel (1)│    │ appliance kernel (2) │
└───────────┘    └──────────────────────┘
     ↓                      ↓ (r/o connection)
     ┌──────────────────────┐
     |      disk image      |
     └──────────────────────┘

این سناریو ایمن است (تا زمانی که هنگام افزودن درایو، پرچم "readonly" را تنظیم کنید). با این حال، هسته libguestfs appliance (2) به دو دلیل، تمام تغییرات اعمال‌شده در disk image را نمی‌بیند:

هسته VM (1) می‌تواند داده‌ها را در حافظه کِش کند، بنابراین در disk image ظاهر نمی‌شوند.
هسته libguestfs appliance (2) انتظار ندارد که disk image در زیر پای آن تغییر کند، بنابراین کِش خود آن حتی هنگامی که هسته VM (1) ایمیج دیسک را به‌روزرسانی کند، به‌طور جادویی به‌روز نمی‌شود.

تنها راهکار پشتیبانی‌شده این است که هر زمان می‌خواهید تغییرات disk image را ببینید، کل libguestfs appliance را مجدداً راه‌اندازی کنید. در سطح API این معادل فراخوانی "guestfs_shutdown" و پس از آن "guestfs_launch" است، که یک عملیات سنگین به شمار می‌رود (همچنین ببینید: guestfs-performance(3)).

چنانچه راه‌اندازی مجدد appliance واقعاً بیش از حد پرهزینه باشد، چند ترفند پشتیبانی‌نشده وجود دارد که می‌توانید امتحان کنید:

  • فراخوانی "guestfs_drop_caches (g, 3)". این کار باعث می‌شود تمام داده‌های کِش‌شده توسط هسته libguestfs appliance (2) دور ریخته شوند، بنابراین به disk image رجوع می‌کند.

    با این حال، این کار به‌تنهایی کافی نیست، زیرا qemu نیز برخی داده‌ها را کِش می‌کند. شما همچنین باید libguestfs را وصله کنید تا حالت "cache=none" (مجدداً) فعال شود. ببینید: https://rwmj.wordpress.com/2013/09/02/new-in-libguestfs-allow-cache-mode-to-be-selected

  • به جای آن از ابزاری مانند virt-bmap استفاده کنید.
  • یک agent درون مهمان اجرا کنید.

اگر مهمان در حال انجام تغییرات بنیادین‌تری باشد (مانند حذف فایل‌سیستم‌ها)، هیچ‌کدام کارساز نخواهد بود. برای این‌گونه موارد باید appliance را مجدداً راه‌اندازی کنید.

(توجه داشته باشید که مشکل سومی نیز وجود دارد؛ برای بررسی واقعی ایمیج‌های دیسک زنده، باید از اسنپ‌شات‌های سازگار (consistent snapshots) استفاده کنید، اما این یک مشکل عمومی در استفاده از libguestfs در برابر هر ایمیج دیسک زنده است.)

guestfish(1), guestfs(3), http://libguestfs.org

Richard W.M. Jones ("rjones at redhat dot com")

Copyright (C) 2012-2025 Red Hat Inc.

این کتابخانه یک نرم‌افزار آزاد است؛ شما می‌توانید آن را تحت شرایط مجوز عمومی همگانی کمتر گنو (GNU Lesser General Public License) همان‌طور که توسط بنیاد نرم‌افزارهای آزاد منتشر شده است، بازتوزیع کرده یا تغییر دهید؛ خواه نسخه ۲ مجوز، یا (به انتخاب خودتان) هر نسخه پس از آن.

این کتابخانه با این امید توزیع شده است که سودمند باشد، اما بدون هرگونه ضمانت؛ حتی بدون ضمانت ضمنی قابلیت فروش یا مناسب بودن برای یک هدف خاص. برای جزئیات بیشتر به GNU Lesser General Public License مراجعه کنید.

شما باید همراه با این کتابخانه، رونوشتی از GNU Lesser General Public License دریافت کرده باشید؛ در غیر این صورت به نشانی زیر مکاتبه کنید: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.SH "گزارش باگ‌ها (BUGS)" برای دریافت فهرستی از باگ‌های libguestfs، از این پیوند استفاده کنید: https://bugzilla.redhat.com/buglist.cgi?component=libguestfs&product=Virtualization+Tools

برای گزارش یک باگ جدید در libguestfs، از این پیوند استفاده کنید: https://bugzilla.redhat.com/enter_bug.cgi?component=libguestfs&product=Virtualization+Tools

هنگام گزارش باگ، لطفاً موارد زیر را ارائه دهید:

  • نسخهٔ libguestfs.
  • از کجا libguestfs را تهیه کرده‌اید (برای مثال کدام توزیع لینوکس، کامپایل‌شده از سورس، غیره).
  • باگ را به‌دقت شرح دهید و روشی برای بازتولید آن ارائه دهید.
  • دستور libguestfs-test-tool(1) را اجرا کرده و خروجی کامل و ویرایش‌نشدهٔ آن را در گزارش باگ قرار دهید.
2026-07-14 libguestfs-1.60.1