guestfs-hacking(1) Virtualization Support guestfs-hacking(1) (NAME) guestfs-hacking - libguestfs (DESCRIPTION) libguestfs . (THE SOURCE CODE) libguestfs : https://github.com/libguestfs/libguestfs (boilerplate) libguestfs ( RPC ) . git checkout . (generator) ("./configure && make -C generator"). libguestfs autotools configure.ac Makefile.am . "THE BUILD SYSTEM" . generator API . lib . appliance daemon appliance appliance . "SOURCE CODE SUBDIRECTORIES" . API . ( ). C lib . (daemon) ( RPC) C daemon . guestfs-building(1) ..SS " (SOURCE CODE SUBDIRECTORIES)" ! lib daemon . generator . Makefile.am . ( customize) ( python) (generator) . align virt-alignment-scan(1). appliance (appliance) libguestfs . bash (tab-completion) Bash. build-aux autotools. builder virt-builder(1). cat virt-cat(1) virt-filesystems(1) virt-log(1) virt-ls(1) virt-tail(1). common common : common/edit libguestfs. common/errnostring daemon errno . common/mlcustomize "virt-customize" . common/mlgettext (wrapper) libguestfs ocaml-gettext . ./configure . common/mlpcre OCaml (PCRE). ocaml-pcre Markus Mottl . common/mlprogress OCaml ( common/progress). common/mlstdutils OCaml . common/mltools OCaml virt OCaml ( "virt-sysprep" "virt-customize" ) . common/mlutils OCaml C "common/utils" POSIX OCaml . common/mlvisit OCaml (visit) ( common/visit). common/mlxml OCaml libxml2. common/options guestfish guestmount virt. common/parallel libvirt. common/progress . common/protocol XDR daemon . common/qemuopts qemu qemu. common/structs (structs) libguestfs . common/utils . common/visit guestfs. common/windows . contrib . customize virt-customize(1). daemon (daemon) libguestfs . df virt-df(1). dib virt-dib(1). diff virt-diff(1). docs . edit virt-edit(1). examples API C. fish guestfish(1) virt-copy-in(1) virt-copy-out(1) virt-tar-in(1) virt-tar-out(1). format virt-format(1). fuse guestmount(1) FUSE ( ) libguestfs. generator (boilerplate) C RPC . get-kernel virt-get-kernel(1). inspector virt-inspector(1) . lib C. logo . Arthur . m4 M4 autoconf. " (THE BUILD SYSTEM)" . make-fs virt-make-fs(1). po gettext. po-docs PO POD. po . rescue virt-rescue(1)..IP resize 4 virt-resize(1). sparsify virt-sparsify(1). sysprep virt-sysprep(1). tests . test-data . test-tool qemu/kernel libguestfs . tmp ( /tmp ) . libguestfs (appliance) . tools Perl (virt-win-reg(1) ). utils "boot-benchmark". v2v libguestfs > 1.42 virt-v2v(1) : https://github.com/libguestfs/virt-v2v website http://libguestfs.org. csharp erlang golang haskell java lua ocaml php perl python ruby (Language bindings). (THE BUILD SYSTEM) Libguestfs GNU autotools ( autoconf automake libtool). ./configure configure.ac m4/guestfs-*.m4 . configure m4 m4/guestfs-daemon.m4 (daemon) . Makefile.am ("SUBDIRS") . common-rules.mk Makefile.am ( ) . subdir-rules.mk Makefile.am . make . : make help API (ADDING A NEW API) (boilerplate) libguestfs API libguestfs . (action) API : 1. ( ) generator/actions_*.ml generator/proc_nr.ml . daemon appliance API ( "ARCHITECTURE" guestfs-internals(1) ). "guestfs_sync" guestfs(3) appliance . "guestfs_set_trace" guestfs(3) handle . "daemon_functions" . (procedure number) RPC libguestfs . . "non_daemon_functions" . RPC daemon -1 . 2. ( C): daemon "do_" "daemon/" . "guestfs_impl_" "lib/" . . 3. : libguestfs 1.38 daemon OCaml . "impl = OCaml ..." generator . daemon/file.ml . "make" . RPC (language bindings) . OCaml . API ( ) API . API (generator/actions_*.ml) "tests/*/" . "tests/*/" . API actions_*.ml . : /dev/sda 2 GB . /dev/sdb 2 GB /dev/sdb1 ext2 . /dev/sdc 10 MB . /dev/sdd ISO ( images/test.iso ). appliance libguestfs . "guestfs_kill_subprocess" guestfs(3) :-x "Init*" generator/types.ml . types.ml . . (prerequisite clause) . (skip) . libguestfs . "Always" . (packagers) "make check" . SKIP_TEST__=1 : "SKIP_TEST_COMMAND_3=1" "guestfs_command" guestfs(3) . : SKIP_TEST_=1 : "SKIP_TEST_ZEROFREE=1" "guestfs_zerofree" guestfs(3) . : TEST_ONLY="vfs_type zerofree" tests/c-api/tests.c . API . guestfish . daemon . fprintf daemon stderr "guestfish -v" ..SS " (ADDING A NEW LANGUAGE BINDING)" generator ( generator ). . generator/ocaml.ml generator/perl.ml . . (ad-hoc) . OCaml Perl OCaml (canonical) OCaml . : - 000+ : 010 020 create 030 create-flags 040 handle 050 060 (explicit close) 065 ( GC) 070 optargs 080 version 090 retvalues - 100 (launch) LV - 400+ : 410 close 420 log 430 (progress messages) - 800+ ( ) - 900+ 100 430 +800 +900 handle (launch) . (FORMATTING CODE) C . . TAB (spaces-not-TABs) K&R . Emacs ( ~/.emacs) : ;;; In libguestfs, indent with spaces everywhere (not TABs). ;;; Exceptions: Makefile and ChangeLog modes. (add-hook 'find-file-hook '(lambda () (if (and buffer-file-name (string-match "/libguestfs\\>" (buffer-file-name)) (not (string-equal mode-name "Change Log")) (not (string-equal mode-name "Makefile"))) (setq indent-tabs-mode nil)))) ;;; When editing C sources in libguestfs, use this style. (defun libguestfs-c-mode () "C mode with adjusted defaults for use with libguestfs." (interactive) (c-set-style "K&R") (setq c-indent-level 2) (setq c-basic-offset 2)) (add-hook 'c-mode-hook '(lambda () (if (string-match "/libguestfs\\>" (buffer-file-name)) (libguestfs-c-mode)))) : ./configure --enable-werror : "make check" . "TESTS" automake . automake . "make check-valgrind" valgrind . <> . "make check-valgrind-local-guests" libvirt ( ) valgrind . "make check-direct" backend appliance . backend "./configure --with-default-backend=..." . "make check-valgrind-direct" valgrind backend appliance . "make check-with-upstream-qemu" qemu . qemu QEMUDIR ( $HOME/d/qemu) : make check-with-upstream-qemu QEMUDIR=/usr/src/qemu "make check-with-upstream-libvirt" libvirt . backend libvirt "./configure --with-default-backend=libvirt" . libvirt LIBVIRTDIR ( $HOME/d/libvirt) : make check-with-upstream-libvirt LIBVIRTDIR=/usr/src/libvirt "make check-slow" / . /: o "TESTS" Makefile.am . o "SLOW=1" ( 77 ). tests/functions.sh "slow_test" . o "SLOW_TESTS" Makefile.am . o Makefile.am : check-slow: $(MAKE) check TESTS="$(SLOW_TESTS)" SLOW=1 "sudo make check-root" (root) . . ( sudo(8)). : o "TESTS" Makefile.am . o euid == 0 ( 77 ). tests/functions.sh "root_test" . o "ROOT_TESTS" Makefile.am . o Makefile.am : check-root: $(MAKE) check TESTS="$(ROOT_TESTS)" "make check-all" "make check*" "check-root" . "make check-release" "make check*" tarball . : o check o check-valgrind o check-direct o check-valgrind-direct o check-slow "make installcheck" "make check" libguestfs . libguestfs libguestfs . : ./configure make clean ||: make make installcheck "make check-valgrind" Makefile.am "check-valgrind:" . Makefile.am valgrind automake . (wrapper script) : $VG virt-foo Makefile.am : check-valgrind: make VG="@VG@" check "TESTS" Makefile.am : LOG_COMPILER = $(VG) check-valgrind: make VG="@VG@" check tmp/valgrind* . (SUBMITTING PATCHES) (patches) : https://lists.libguestfs.org rjones@redhat.com (CC) . . . (I18N) (INTERNATIONALIZATION (I18N) SUPPORT) i18n ( gettext) . (daemon) . (appliance) (locale) . PO appliance . (debugging) . (MISCELLANEOUS TOPICS) OCAML (HOW OCAML PROGRAMS ARE COMPILED AND LINKED) << automake ocamlopt >> OCaml . automake OCaml ocamlc ocamlopt . OCaml C << >> ( automake "DEPENDENCIES") OCaml . OCaml C (native bindings) . C : virt_customize_SOURCES = ... crypt-c.c perl_edit-c.c C dummy.c : virt_resize_SOURCES = dummy.c OCaml automake ( ): virt_customize_DEPENDENCIES = ... customize_main.cmx (link) . automake ocamlopt "-cclib" . virt_customize_LINK = \ $(top_builddir)/ocaml-link.sh -cclib '-lutils' -- ... customize/Makefile.am : o (native code). o (pattern rules) OCaml . subdir-rules.mk Makefile.am . o OCaml "EXTRA_DIST". Automake ..SH " (MAINTAINER TASKS)" MAKEFILE (MAINTAINER MAKEFILE TARGETS) "make" libguestfs . make maintainer-commit "Version $(VERSION)." . configure.ac (clean) (rebuild) . make maintainer-tag HEAD "v$(VERSION)" : Version $(VERSION) stable Version $(VERSION) development ( <> guestfs(3) .) make maintainer-check-authors ( git) generator/authors.ml . make maintainer-check-extra-dist "make dist" ( tarball ). tarball git "EXTRA_DIST" Makefile.am . make maintainer-upload-website libguestfs libguestfs git . (MAKING A STABLE RELEASE) . <> guestfs(3) . o "make && make check" : Fedora (x86-64) Debian (x86-64) Ubuntu (x86-64) Fedora (aarch64) Fedora (ppc64) Fedora (ppc64le) o "./configure --without-libvirt" . o guestfs-release-notes.pod. o stable development http://libguestfs.org/download. o website/index.html.in. o ( configure.ac) (stable) 1.XX.0 : ./localconfigure make distclean -k ./localconfigure make && make dist make maintainer-commit make maintainer-tag o stable git: git branch stable-1.XX git push origin stable-1.XX o . o . ..SH " (INTERNAL DOCUMENTATION)" libguestfs . libguestfs . "/**" POD . (export) . lib lib/actions-support.c (actions) lib/actions-*.c. lib/appliance-cpu.c CPU . "lib/appliance-cpu.c:guestfs_int_get_cpu_model" const char * guestfs_int_get_cpu_model (int kvm) CPU "-cpu" qemu libvirt . : "host" "host" "-cpu host" . "max" "max" "-cpu max" ( ) . libvirt . (some string) "cortex-a57" "-cpu cortex-a57" . "NULL" "NULL" "-cpu" . "NULL" . QEMU : o "qemu-system-aarch64 -M virt" "cortex-a15" ( !). o KVM "-cpu host" TCG KVM "-cpu" . lib/appliance-kcmdline.c (kernel) . "lib/appliance-kcmdline.c:VALID_TERM" #define VALID_TERM $TERM . "lib/appliance-kcmdline.c:get_root_uuid_with_file" static char * get_root_uuid_with_file (guestfs_h *g, const char *appliance) extX UUID . "lib/appliance-kcmdline.c:run_qemu_img_dd" static int run_qemu_img_dd (guestfs_h *g, const char *in_file, char *out_file) in_file qemu-img(1) out_file. UUID QCOW2 "get_root_uuid_with_file" . -1 . "lib/appliance-kcmdline.c:get_root_uuid" static char * get_root_uuid (guestfs_h *g, const char *appliance) UUID . "lib/appliance-kcmdline.c:guestfs_int_appliance_command_line" char * guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance, int flags) . "direct" "libvirt" . "appliance" ( NULL ) UUID . "flags" OR ( 0): "APPLIANCE_COMMAND_LINE_IS_TCG" TCG qemu ( KVM ). . (free) . lib/appliance-uefi.c UEFI . lib/uefi.c ( ) . "lib/appliance-uefi.c:guestfs_int_get_uefi" int guestfs_int_get_uefi (guestfs_h *g, char *const *firmwares, const char **firmware, char **code, char **vars, int *flags) . aarch64 UEFI ( RHEL). "firmwares" libvirt . "NULL" . *firmware "firmwares" . *code UEFI . *vars UEFI ( ). UEFI *firmware "NULL" *code *vars. *code *vars *firmware . -1 ( UEFI ). virt-v2v.git/v2v/utils.ml:find_uefi_firmware.PP lib/appliance.c (appliance) libguestfs . "lib/appliance.c:guestfs_int_build_appliance" int guestfs_int_build_appliance (guestfs_h *g, char **kernel_rtn, char **initrd_rtn, char **appliance_rtn) . supermin supermin (fixed) (old-style) . 0 = -1 = . "appliance.kernel" "appliance.initrd" initrd "appliance.image" ext2 . "appliance.image" "NULL" ( ext2) . (free) . . : 1. "path" supermin . . 2. "supermin --build" ( ). . 3. "path" . . 4. "path" . . supermin $TMPDIR/.guestfs-$UID/ : $TMPDIR/.guestfs-$UID/lock - supermin $TMPDIR/.guestfs-$UID/appliance.d/kernel - $TMPDIR/.guestfs-$UID/appliance.d/initrd - initrd supermin $TMPDIR/.guestfs-$UID/appliance.d/root - libguestfs UID (race condition) . ( supermin >= 5 ) supermin --lock appliance.d . "lib/appliance.c:locate_or_build_appliance" static int locate_or_build_appliance (guestfs_h *g, struct appliance_files *appliance, const char *path) "path" : supermin . . supermin . : 1 = C 0 = -1 = . "lib/appliance.c:search_appliance" static int search_appliance (guestfs_h *g, struct appliance_files *appliance) "g->path" "appliance" "locate_or_build_appliance" . : 1 = C 0 = -1 = . "lib/appliance.c:build_supermin_appliance" static int build_supermin_appliance (guestfs_h *g, const char *supermin_path, struct appliance_files *appliance) supermin "supermin_path" $TMPDIR/.guestfs-$UID . : 0 = -1 = ( ). "lib/appliance.c:run_supermin_build" static int run_supermin_build (guestfs_h *g, const char *lockfile, const char *appliancedir, const char *supermin_path) "supermin --build" . "lib/appliance.c:dir_contains_file" static int dir_contains_file (guestfs_h *g, const char *dir, const char *file) true "file" "dir" . "lib/appliance.c:dir_contains_files" static int dir_contains_files (guestfs_h *g, const char *dir, ...) true "dir" . lib/command.c (wrapper) "virCommand" libvirt. : 1. () : struct command *cmd; cmd = guestfs_int_new_command (g); 2. : guestfs_int_cmd_add_arg (cmd, "qemu-img"); guestfs_int_cmd_add_arg (cmd, "info"); guestfs_int_cmd_add_arg (cmd, filename); (: "NULL" .) 3. (quoted) . ( system(3)/popen("r") ). guestfs_int_cmd_add_string_unquoted (cmd, "qemu-img info "); guestfs_int_cmd_add_string_quoted (cmd, filename); (error log) libguestfs . 5. . fork(2) waitpid(3) . r = guestfs_int_cmd_run (cmd); if (r == -1) // error // else test r using the WIF* functions 6. (handle): guestfs_int_cmd_close (cmd); ( "CLEANUP_CMD_CLOSE"). "lib/command.c:guestfs_int_new_command" struct command * guestfs_int_new_command (guestfs_h *g) (command handle) . "lib/command.c:guestfs_int_cmd_add_arg" void guestfs_int_cmd_add_arg (struct command *cmd, const char *arg) ( "execv"). "lib/command.c:guestfs_int_cmd_add_arg_format" void guestfs_int_cmd_add_arg_format (struct command *cmd, const char *fs, ...) ( "execv") printf(3). "lib/command.c:guestfs_int_cmd_add_string_unquoted" void guestfs_int_cmd_add_string_unquoted (struct command *cmd, const char *str) ( system(3)). . "lib/command.c:guestfs_int_cmd_add_string_quoted" void guestfs_int_cmd_add_string_quoted (struct command *cmd, const char *str) ( system(3)). (double quotes) (escaping) . system(3) . "lib/command.c:guestfs_int_cmd_set_stdout_callback" void guestfs_int_cmd_set_stdout_callback (struct command *cmd, cmd_stdout_callback stdout_callback, void *stdout_data, unsigned flags) (callback) (stdout) . flags "CMD_STDOUT_FLAG_LINE_BUFFER" ( ) . "\n" callback . "\0" . flags "CMD_STDOUT_FLAG_UNBUFFERED" callback . "\0" length callback . flags "CMD_STDOUT_FLAG_WHOLE_BUFFER" callback . "\0" length callback . "lib/command.c:guestfs_int_cmd_set_stderr_to_stdout" void guestfs_int_cmd_set_stderr_to_stdout (struct command *cmd) "2>&1" . "capture_errors" . "lib/command.c:guestfs_int_cmd_clear_capture_errors" void guestfs_int_cmd_clear_capture_errors (struct command *cmd) "capture_errors". (event log) stderr . "lib/command.c:guestfs_int_cmd_set_child_callback" void guestfs_int_cmd_set_child_callback (struct command *cmd, cmd_child_callback child_callback, void *data) (child) . . "lib/command.c:guestfs_int_cmd_set_child_rlimit" void guestfs_int_cmd_set_child_rlimit (struct command *cmd, int resource, long limit) rlimit . "lib/command.c:finish_command" static void finish_command (struct command *cmd) argv "NULL" "\0" . "lib/command.c:loop" static int loop (struct command *cmd) (log) callback stdout ..PP "lib/command.c:guestfs_int_cmd_run" int guestfs_int_cmd_run (struct command *cmd) (fork) waitpid . (exit status) . "WIF*" . : "error" -1 . "lib/command.c:guestfs_int_cmd_pipe_run" int guestfs_int_cmd_pipe_run (struct command *cmd, const char *mode) . "popen (..., "r"|"w")" . (file descriptor) (pipe) ("r") ("w") . "guestfs_int_cmd_pipe_wait" . (subcommand) . ( "guestfs_int_cmd_pipe_wait" ) "guestfs_int_cmd_get_pipe_errors" . "lib/command.c:guestfs_int_cmd_pipe_wait" int guestfs_int_cmd_pipe_wait (struct command *cmd) "guestfs_int_cmd_pipe_run" . ( syscall) -1 . "WIF*" "guestfs_int_cmd_get_pipe_errors" . "lib/command.c:guestfs_int_cmd_get_pipe_errors" char * guestfs_int_cmd_get_pipe_errors (struct command *cmd) . (free) . "lib/command.c:guestfs_int_cmd_close" void guestfs_int_cmd_close (struct command *cmd) "cmd" . "lib/command.c:process_line_buffer" static void process_line_buffer (struct command *cmd, int closed) (stdout) (callback) . lib/conn-socket.c POSIX . "lib/conn-socket.c:handle_log_message" static int handle_log_message (guestfs_h *g, struct connection_socket *conn) "conn->console_sock" . . : 1 () () 0 (appliance) -1 "lib/conn-socket.c:guestfs_int_new_conn_socket_listening" struct connection * guestfs_int_new_conn_socket_listening (guestfs_h *g, int daemon_accept_sock, int console_sock) (listening) . -1 "console_sock" . "daemon_accept_sock" "accept_connection" "free_connection" . "lib/conn-socket.c:guestfs_int_new_conn_socket_connected" struct connection * guestfs_int_new_conn_socket_connected (guestfs_h *g, int daemon_sock, int console_sock) (connected) . "daemon_sock" "accept_connection" . lib/create.c (API) . qemu-img(1) . "lib/create.c:VALID_FORMAT" #define VALID_FORMAT (backing format). "^[[:alnum]]+$" ( C) . lib/drives.c (handle) . "struct drive" . "lib/drives.c:create_overlay" static int create_overlay (guestfs_h *g, struct drive *drv) (overlay) . overlay (handle) ..PP "lib/drives.c:create_drive_file" static struct drive * create_drive_file (guestfs_h *g, const struct drive_create_data *data) "struct drive". "lib/drives.c:create_drive_dev_null" static struct drive * create_drive_dev_null (guestfs_h *g, struct drive_create_data *data) /dev/null. /dev/null . KVM (RHEL 5) /dev/null readonly . qemu 1.2 + virtio-scsi /dev/null segfault . /dev/null . null . "lib/drives.c:drive_to_string" static char * drive_to_string (guestfs_h *g, const struct drive *drv) "struct drive" . . "lib/drives.c:add_drive_to_handle_at" static void add_drive_to_handle_at (guestfs_h *g, struct drive *d, size_t drv_index) "struct drive" "g->drives" "drv_index". . . "lib/drives.c:add_drive_to_handle" static void add_drive_to_handle (guestfs_h *g, struct drive *d) struct drive "g->drives" handle. "lib/drives.c:guestfs_int_add_dummy_appliance_drive" void guestfs_int_add_dummy_appliance_drive (guestfs_h *g) (launch) "g->drives" . "lib/drives.c:guestfs_int_free_drives" void guestfs_int_free_drives (guestfs_h *g) handle. "lib/drives.c:VALID_FORMAT" #define VALID_FORMAT "^[-_[:alnum:]]+$" ( C locale) . "lib/drives.c:VALID_DISK_LABEL" #define VALID_DISK_LABEL . '/' ',' . <= 20 . "lib/drives.c:VALID_HOSTNAME" #define VALID_HOSTNAME (hostname) . "lib/drives.c:valid_port" static int valid_port (int port) . "lib/drives.c:valid_blocksize" static int valid_blocksize (int blocksize) . 512 4096 . "lib/drives.c:guestfs_int_checkpoint_drives" size_t guestfs_int_checkpoint_drives (guestfs_h *g) (checkpoint) (roll back) . "guestfs_add_domain" guestfs(3) . "lib/drives.c:guestfs_impl_debug_drives" char ** guestfs_impl_debug_drives (guestfs_h *g) . lib/errors.c (debug) (trace) (warning) . API libguestfs errno handle . API handle / callback . "error" "perrorf" : if (something_bad) { error (g, "something bad happened"); return -1; } "error" "perrorf" handle . "lib/errors.c:guestfs_int_warning" void guestfs_int_warning (guestfs_h *g, const char *fs, ...) . . "warning (g, fs, ...)" . . : . "lib/errors.c:guestfs_int_debug" void guestfs_int_debug (guestfs_h *g, const char *fs, ...) . . "debug (g, fs, ...)" . "g->verbose" (false) . "lib/errors.c:guestfs_int_trace" void guestfs_int_trace (guestfs_h *g, const char *fs, ...) (trace) . . . "lib/errors.c:guestfs_int_error_errno" void guestfs_int_error_errno (guestfs_h *g, int errnum, const char *fs, ...) errno (handle) (error callback) . errno "error (g, fs, ...)" . errno . "lib/errors.c:guestfs_int_perrorf" void guestfs_int_perrorf (guestfs_h *g, const char *fs, ...) perror(3) (format strings) . "perrorf (g, fs, ...)" . "lib/errors.c:guestfs_int_launch_failed_error" void guestfs_int_launch_failed_error (guestfs_h *g) (launch failed) . qemu FAQ . "lib/errors.c:guestfs_int_unexpected_close_error" void guestfs_int_unexpected_close_error (guestfs_h *g) appliance . "lib/errors.c:guestfs_int_launch_timeout" void guestfs_int_launch_timeout (guestfs_h *g) appliance (hang ) . "lib/errors.c:guestfs_int_external_command_failed" void guestfs_int_external_command_failed (guestfs_h *g, int status, const char *cmd_name, const char *extra) . "status" ( waitpid(2) system(3)). . lib/events.c "lib/events.c:replace_old_style_event_callback" static void replace_old_style_event_callback (guestfs_h *g, guestfs_event_callback cb, uint64_t event_bitmask, void *opaque, void *opaque2) API . (event handle) . "guestfs_set_*_callback" . "cb == NULL" . lib/guestfs-internal-all.h libguestfs virt ( C). lib/guestfs-internal.h . . lib/guestfs-internal.h libguestfs (lib/) . lib/guestfs-internal-all.h. "lib/guestfs-internal.h:event" struct event { uint64_t event_bitmask; guestfs_event_callback cb; void *opaque; /* opaque2 is not exposed through the API, but is used internally to * emulate the old-style callback API. */ void *opaque2; }; struct handle . "g->events" handle . "lib/guestfs-internal.h:drive" struct drive { /* file:... http:... */ struct drive_source src; /* readonly overlay [ ] * launch * . Backends * non-NULL . * * overlay backend * . qcow2 */ char *overlay; /* . */ bool readonly; char *name; char *disk_label; char *cachemode; enum discard discard; bool copyonread; int blocksize; }; "struct drive" . "lib/guestfs-internal.h:backend_ops" struct backend_ops { /* ( ) handle backend * . data libguestfs * 'void *data' . * libguestfs (opaque) . * backend * shutdown . */ size_t data_size; /* overlay COW . * . * handle . */ char *(*create_cow_overlay) (guestfs_h *g, void *data, struct drive *drv); /* hypervisor (qemu) * guestfs_set_hv LIBGUESTFS_HV . */ const char *(*get_default_hv) (guestfs_h *g, void *data); /* (Launch) (shutdown). */ int (*launch) (guestfs_h *g, void *data, const char *arg); int (*shutdown) (guestfs_h *g, void *data, int check_for_errors); /* . */ int (*get_pid) (guestfs_h *g, void *data); int (*max_disks) (guestfs_h *g, void *data); }; backend. backend ( libvirt direct) handle ( (launch) (shutdown)) . backend struct . "lib/guestfs-internal.h:connection" struct connection { const struct connection_ops *ops; /* struct connection * . */ }; (Connection module). "connection" appliance daemon . ( POSIX "virStreamPtr") . "lib/guestfs-internal.h:cached_feature" struct cached_feature { char *group; int result; }; . appliance (lib/available.c ). "lib/guestfs-internal.h:guestfs_h" struct guestfs_h { struct guestfs_h *next; /* handle . */ enum state state; /* guestfs(3) */ /* guestfs_* * handle . */ pthread_mutex_t lock; /**** handle. ****/ bool verbose; /* . */ bool trace; /* . */ bool autosync; /* . */ bool direct_mode; /* . */ bool recovery_proc; /* . */ bool enable_network; /* . */ bool selinux; /* selinux */ bool pgroup; /* */ bool close_on_exit; /* handle atexit */ int smp; /* > 1 -smp hv . */ int memsize; /* RAM (). */ char *path; /* appliance. */ char *hv; /* Hypervisor (HV). */ char *append; /* . */ struct hv_param *hv_params; /* hv. */ char *program; /* . */ char *identifier; /* handle. */ /* API add-drive*. * * launch . * * launch (dummy) * appliance . * * shutdown launch * ( : * handle ). * * ITER_DRIVES ! */ struct drive **drives; size_t nr_drives; #define ITER_DRIVES(g,i,drv) \ for (i = 0; i < (g)->nr_drives; ++i) \ if (((drv) = (g)->drives[i]) != NULL) /* Backend. : guestfs_int_set_backend backend . */ char *backend; /* non-NULL. */ char *backend_arg; /* . */ const struct backend_ops *backend_ops; void *backend_data; /* handle. */ char **backend_settings; /* backend ( NULL ). */ /**** (Runtime). ****/ /* (). */ /* - handle * guestfs_int_lazy_make_tmpdir . */ char *tmpdir; char *sockdir; /* tmpdir/cachedir/sockdir . */ char *env_tmpdir; /* $TMPDIR ( NULL) */ char *env_runtimedir; /* $XDG_RUNTIME_DIR ( NULL)*/ char *int_tmpdir; /* $LIBGUESTFS_TMPDIR guestfs_set_tmpdir NULL */ char *int_cachedir; /* $LIBGUESTFS_CACHEDIR guestfs_set_cachedir NULL */ /* . */ pthread_key_t error_data; /* error_data handle * mutex . */ pthread_mutex_t error_data_list_lock; struct error_data *error_data_list; /* (Out of memory). */ guestfs_abort_cb abort_cb; /* . */ struct event *events; size_t nr_events; /* . */ struct hash_table *pda; struct pda_entry *pda_next; /* . signal-atomic * != 0 . */ int user_cancel; struct timeval launch_t; /* guestfs_launch . */ /* bindtests. */ FILE *test_fp; /* . * '++g->unique'. handle * . */ int unique; /*** . ***/ struct connection *conn; /* appliance. */ int msg_next_serial; #if HAVE_FUSE /**** API mount-local. ****/ char *localmountpoint; struct fuse *fuse; /* FUSE handle. */ int ml_dir_cache_timeout; /* . */ Hash_table *lsc_ht, *xac_ht, *rlc_ht; /* . */ int ml_read_only; /* mount . */ int ml_debug_calls; /* FUSE. */ #endif #ifdef HAVE_LIBVIRT /* lib/libvirt-auth.c. */ #define NR_CREDENTIAL_TYPES 9 unsigned int nr_supported_credentials; int supported_credentials[NR_CREDENTIAL_TYPES]; const char *saved_libvirt_uri; /* . */ bool wrapper_warning_done; unsigned int nr_requested_credentials; virConnectCredentialPtr requested_credentials; #endif /* . */ struct cached_feature *features; size_t nr_features; /* lib/info.c. -1 = 0 1. */ int qemu_img_supports_U_option; }; libguestfs. "lib/guestfs-internal.h:version" struct version { int v_major; int v_minor; int v_micro; }; major.minor.micro . lib/version.c . lib/guid.c "lib/guid.c:guestfs_int_validate_guid" int guestfs_int_validate_guid (const char *str) GUID . "{21EC2020-3AEA-1069-A2DD-08002B30309D}" "21EC2020-3AEA-1069-A2DD-08002B30309D" . lib/handle.c "guestfs_h" // . "lib/handle.c:init_libguestfs" static void init_libguestfs (void) libguestfs libvirt libxml2 (thread) . (constructor) libguestfs . "lib/handle.c:shutdown_backend" static int shutdown_backend (guestfs_h *g, int check_for_errors) qemu . "guestfs_shutdown" "shutdown_backend" "check_for_errors=1" . "guestfs_close" "shutdown_backend" "check_for_errors=0" . "check_for_errors" . libvirt . "lib/handle.c:close_handles" static void close_handles (void) ( atexit(3)). "lib/handle.c:guestfs_int_get_backend_setting_bool" int guestfs_int_get_backend_setting_bool (guestfs_h *g, const char *name) API . lib/info.c "lib/info.c:qemu_img_supports_U_option" static int qemu_img_supports_U_option (guestfs_h *g) qemu-img info "-U" . (memoized) . qemu 2.11 . qemu >= 2.11 . lib/inspect-icon.c "lib/inspect-icon.c:guestfs_int_download_to_tmp" char * guestfs_int_download_to_tmp (guestfs_h *g, const char *filename, const char *extension, uint64_t max_size) . () . (free) . . "extension" ( "NULL" ). "max_size" . "NULL" . lib/launch-direct.c "direct". "BACKENDS" guestfs(3) . "lib/launch-direct.c:add_drive_standard_params" static int add_drive_standard_params (guestfs_h *g, struct backend_direct_data *data, struct qemuopts *qopts, size_t i, struct drive *drv) "-drive" . "lib/launch-direct.c:add_device_blocksize_params" static int add_device_blocksize_params (guestfs_h *g, struct qemuopts *qopts, struct drive *drv) physical_block_size logical_block_size "-device" . "lib/launch-direct.c:launch_passt" static int launch_passt (guestfs_h *g, long *passt_pid, char (*sockpath)[UNIX_PATH_MAX]) passt (daemonize ). -1 "passt_pid" "sockpath" . 0 . "passt_pid" PID passt . "sockpath" (unix domain socket) passt ..PP lib/launch-libvirt.c "lib/launch-libvirt.c:get_source_format_or_autodetect" static char * get_source_format_or_autodetect (guestfs_h *g, struct drive *drv) "drv->src.format" "NULL" . libvirt "allow_disk_format_probing=1" /etc/libvirt/qemu.conf . "qemu-img" libvirt . libguestfs libvirt . (free) . "NULL" . "lib/launch-libvirt.c:make_qcow2_overlay" static char * make_qcow2_overlay (guestfs_h *g, const char *backing_drive, const char *format) (overlay) qcow2 "backing_drive" () . "format" (backing file) . "format" NULL . overlay appliance . lib/launch.c "guestfs_launch" guestfs(3) . ( "BACKEND" guestfs(3) ) lib/launch-direct.c lib/launch-libvirt.c backend . "lib/launch.c:guestfs_int_launch_send_progress" void guestfs_int_launch_send_progress (guestfs_h *g, int perdozen) . appliance . : 0 / 12: launch clock starts 3 / 12: appliance created 6 / 12: detected that guest kernel started 9 / 12: detected that /init script is running 12 / 12: launch completed successfully : 1. ABI . 2. . 3. lib/proto.c . "lib/launch.c:guestfs_int_timeval_diff" int64_t guestfs_int_timeval_diff (const struct timeval *x, const struct timeval *y) "y - x" . : http://www.mpp.mpg.de/~huber/util/timevaldiff.c "lib/launch.c:guestfs_int_unblock_sigterm" void guestfs_int_unblock_sigterm (void) "SIGTERM" . fork(2) "SIGTERM" "SIGTERM" . : https://bugzilla.redhat.com/1460338. "lib/launch.c:guestfs_impl_max_disks" int guestfs_impl_max_disks (guestfs_h *g) backend ( backend). "lib/launch.c:guestfs_impl_wait_ready" int guestfs_impl_wait_ready (guestfs_h *g) "guestfs_wait_ready" guestfs(3). <= 1.0.70 () (no-op) . "lib/launch.c:guestfs_int_register_backend" void guestfs_int_register_backend (const char *name, const struct backend_ops *ops) backend . "lib/launch.c:guestfs_int_set_backend" int guestfs_int_set_backend (guestfs_h *g, const char *method) "guestfs_set_backend" guestfs(3). o (config) . o "error" . . "lib/launch.c:guestfs_int_passt_runnable" bool guestfs_int_passt_runnable (guestfs_h *g) "passt --help" 0 1 "true" . ( "passt-0^20230222.g4ddbcb9-2.el9_2.x86_64" "--help" 1 .) lib/private-data.c C API libguestfs "guestfs_h" . "PRIVATE DATA AREA" guestfs(3) ..PP (Language bindings) C (handles) ( ) . "lib/private-data.c:pda_entry" struct pda_entry { char *key; /* key */ void *data; /* opaque user data pointer */ }; gnulib "pda_entry" . (lazily) . "g->pda" "NULL" . lib/proto.c RPC ( ) . (lib/actions-*.c) . : 1. ( <> guestfs(3)). RPC . 2. RPC ( <> guestfs(3)). . : guestfs_int_send guestfs_int_recv 3. RPC "FileIn" ( <> guestfs(3)). () . : guestfs_int_send guestfs_int_send_file (possibly multiple times) guestfs_int_recv 4. RPC "FileOut" ( <> guestfs(3)). () . : guestfs_int_send guestfs_int_recv guestfs_int_recv_file (possibly multiple times) 5. "FileIn" "FileOut". API . // ("g->conn") . (log) . "lib/proto.c:child_cleanup" static void child_cleanup (guestfs_h *g) EOF qemu . "lib/proto.c:guestfs_int_progress_message_callback" void guestfs_int_progress_message_callback (guestfs_h *g, const guestfs_progress *message) . "lib/proto.c:guestfs_int_log_message_callback" void guestfs_int_log_message_callback (guestfs_h *g, const char *buf, size_t len) . "lib/proto.c:check_daemon_socket" static ssize_t check_daemon_socket (guestfs_h *g) : -1 -2 (appliance) 0 1 "lib/proto.c:guestfs_int_send_file" int guestfs_int_send_file (guestfs_h *g, const char *filename) . 0 -1 ( ) -2 . "lib/proto.c:send_file_data" static int send_file_data (guestfs_h *g, const char *buf, size_t len) (chunk) . "lib/proto.c:send_file_cancellation" static int send_file_cancellation (guestfs_h *g) . "lib/proto.c:send_file_complete" static int send_file_complete (guestfs_h *g) . "lib/proto.c:recv_from_daemon" static int recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void **buf_rtn) . 0 -1 ..PP "size_rtn" "buf_rtn" non-NULL . *size_rtn "GUESTFS_LAUNCH_FLAG" "GUESTFS_CANCEL_FLAG" . *buf_rtn ( ) "NULL" . *buf_rtn (free) . EOF ( appliance) child_cleanup . (log) . "lib/proto.c:guestfs_int_recv" int guestfs_int_recv (guestfs_h *g, const char *fn, guestfs_message_header *hdr, guestfs_message_error *err, xdrproc_t xdrp, char *ret) . "lib/proto.c:guestfs_int_recv_discard" int guestfs_int_recv_discard (guestfs_h *g, const char *fn) "guestfs_int_recv" ( ). (XXX): o int . o . "lib/proto.c:guestfs_int_recv_file" int guestfs_int_recv_file (guestfs_h *g, const char *filename) : -1 = 0 = EOF ">0" = "lib/proto.c:receive_file_data" static ssize_t receive_file_data (guestfs_h *g, void **buf_r) (chunk) . : -1 = 0 = EOF ">0" = lib/qemu.c qemu. "lib/qemu.c:generic_qmp_test" static int generic_qmp_test (guestfs_h *g, const char *qemu, const char *qmp_command, char **outp) QMP QEMU. "lib/qemu.c:parse_has_kvm" static int parse_has_kvm (guestfs_h *g, const char *json) json query-kvm QMP KVM . JSON : {"return": {"enabled": true, "present": true}} "lib/qemu.c:guestfs_int_platform_has_kvm" int guestfs_int_platform_has_kvm (guestfs_h *g, const char *qemu) (platform) KVM . qemu <<>> qemu QMP <> JSON . "lib/qemu.c:guestfs_int_qemu_escape_param" char * guestfs_int_qemu_escape_param (guestfs_h *g, const char *param) (escape) qemu. "," ",," . . XXX qemu-img lib/create.c . qemuopts . "lib/qemu.c:guestfs_int_drive_source_qemu_param" char * guestfs_int_drive_source_qemu_param (guestfs_h *g, const struct drive_source *src) + qemu. qemu "file=" . -drive qemu ( qemu-img(1)). "lib/qemu.c:guestfs_int_discard_possible" bool guestfs_int_discard_possible (guestfs_h *g, struct drive *drv) discard . discard 1 . 0 . "discard == "enable"" . lib/rescue.c virt-rescue(1). lib/stringsbuf.c NULL ( "argv"). stringsbuf "DECLARE_STRINGSBUF" . : stringsbuf (daemon) . "lib/stringsbuf.c:guestfs_int_add_string_nodup" void guestfs_int_add_string_nodup (guestfs_h *g, struct stringsbuf *sb, char *str) . strdup(3) ..PP "lib/stringsbuf.c:guestfs_int_add_string" void guestfs_int_add_string (guestfs_h *g, struct stringsbuf *sb, const char *str) . . "lib/stringsbuf.c:guestfs_int_add_sprintf" void guestfs_int_add_sprintf (guestfs_h *g, struct stringsbuf *sb, const char *fs, ...) . -sprintf . "lib/stringsbuf.c:guestfs_int_end_stringsbuf" void guestfs_int_end_stringsbuf (guestfs_h *g, struct stringsbuf *sb) . NULL . "lib/stringsbuf.c:guestfs_int_free_stringsbuf" void guestfs_int_free_stringsbuf (struct stringsbuf *sb) . lib/tmpdirs.c . "lib/tmpdirs.c:set_abs_path" static int set_abs_path (guestfs_h *g, const char *ctxstr, const char *tmpdir, char **tmpdir_ret) tmpdir . (https://bugzilla.redhat.com/882417). "ctxstr" ( API ). "lib/tmpdirs.c:guestfs_impl_get_tmpdir" char * guestfs_impl_get_tmpdir (guestfs_h *g) API "guestfs_get_tmpdir". tmpdir "NULL" . "lib/tmpdirs.c:guestfs_impl_get_cachedir" char * guestfs_impl_get_cachedir (guestfs_h *g) API "guestfs_get_cachedir". cachedir "NULL" . "lib/tmpdirs.c:guestfs_impl_get_sockdir" char * guestfs_impl_get_sockdir (guestfs_h *g) API "guestfs_get_sockdir". sockdir "NULL" . "lib/tmpdirs.c:guestfs_int_lazy_make_tmpdir" int guestfs_int_lazy_make_tmpdir (guestfs_h *g) "g->tmpdir" ( handle) handle . (lazy) (launch) . "lib/tmpdirs.c:guestfs_int_make_temp_path" char * guestfs_int_make_temp_path (guestfs_h *g, const char *name, const char *extension) . NULL . "lib/tmpdirs.c:guestfs_int_create_socketname" int guestfs_int_create_socketname (guestfs_h *g, const char *filename, char (*sockpath)[UNIX_PATH_MAX]) filename sockdir. "lib/tmpdirs.c:guestfs_int_make_pid_path" char * guestfs_int_make_pid_path (guestfs_h *g, const char *name) PID. NULL . sockdir tmpdir (dropping privileges) PID tmpdir . "lib/tmpdirs.c:guestfs_int_lazy_make_supermin_appliance_dir" char * guestfs_int_lazy_make_supermin_appliance_dir (guestfs_h *g) supermin appliance cachedir . (permissions) cachedir . . "lib/tmpdirs.c:guestfs_int_recursive_remove_dir" void guestfs_int_recursive_remove_dir (guestfs_h *g, const char *dir) . ( ). "rm -rf" . lib/umask.c umask thread-safe. glibc <> . "Umask" /proc/self/status Linux >= 4.7 . Linux thread-safe umask . : Josh Stone Jiri Jaburek Eric Blake. "lib/umask.c:guestfs_int_getumask" int guestfs_int_getumask (guestfs_h *g) umask . -1 (handle) guestfs . "lib/umask.c:get_umask_from_proc" static int get_umask_from_proc (guestfs_h *g) Linux >= 4.7 umask /proc/self/status . -1 . /proc "Umask" -2 (fallback) . "lib/umask.c:get_umask_from_fork" static int get_umask_from_fork (guestfs_h *g) umask fork. lib/unit-tests.c (Unit tests) . libguestfs (launch) . . "lib/unit-tests.c:test_split" static void test_split (void) "guestfs_int_split_string". "lib/unit-tests.c:test_concat" static void test_concat (void) "guestfs_int_concat_strings". "lib/unit-tests.c:test_join" static void test_join (void) "guestfs_int_join_strings". "lib/unit-tests.c:test_validate_guid" static void test_validate_guid (void) "guestfs_int_validate_guid". "lib/unit-tests.c:test_drive_name" static void test_drive_name (void) "guestfs_int_drive_name". "lib/unit-tests.c:test_drive_index" static void test_drive_index (void) "guestfs_int_drive_index". "lib/unit-tests.c:test_getumask" static void test_getumask (void) "guestfs_int_getumask". "lib/unit-tests.c:test_command" static void test_command (void) "guestfs_int_new_command" . XXX . . "lib/unit-tests.c:test_qemu_escape_param" static void test_qemu_escape_param (void) "guestfs_int_qemu_escape_param" XXX qemu (escape) (VM) . "lib/unit-tests.c:test_timeval_diff" static void test_timeval_diff (void) "guestfs_int_timeval_diff". lib/version.c . "lib/version.c:guestfs_int_version_from_x_y" int guestfs_int_version_from_x_y (guestfs_h *g, struct version *v, const char *str) "X.Y" . ( ) -1 0 1 . "v" . "lib/version.c:guestfs_int_version_from_x_y_re" int guestfs_int_version_from_x_y_re (guestfs_h *g, struct version *v, const char *str, const pcre2_code *re) "re" () . ( ) -1 0 1 . "v" . "lib/version.c:guestfs_int_version_from_x_y_or_x" int guestfs_int_version_from_x_y_or_x (guestfs_h *g, struct version *v, const char *str) "X.Y" . ( ) -1 0 1 . "v" . "lib/version.c:guestfs_int_parse_unsigned_int" int guestfs_int_parse_unsigned_int (guestfs_h *g, const char *str) . . >= 0 -1 . lib/wait.c "lib/wait.c:guestfs_int_waitpid" int guestfs_int_waitpid (guestfs_h *g, pid_t pid, int *status, const char *errmsg) waitpid(3) "EINTR" . : "SIGCHLD" (non-restartable) ( virt libguestfs ). SIGCHLD wait "SIGCHLD" wait "EINTR" . wait . "lib/wait.c:guestfs_int_waitpid_noerror" void guestfs_int_waitpid_noerror (pid_t pid) "guestfs_int_waitpid" . "lib/wait.c:guestfs_int_wait4" int guestfs_int_wait4 (guestfs_h *g, pid_t pid, int *status, struct rusage *rusage, const char *errmsg) wait4(2) "EINTR" . lib/whole-file.c "lib/whole-file.c:guestfs_int_read_whole_file" int guestfs_int_read_whole_file (guestfs_h *g, const char *filename, char **data_r, size_t *size_r) "filename" . "data_r" . "size_r" . . handle -1 . NUL ( NUL ). . (denial-of-service) ..SS " common/edit" common/edit/file-edit.c guestfish(1) virt-edit(1) virt-customize(1) virt-builder(1) . ( ) Perl . "common/edit/file-edit.c:edit_file_editor" int edit_file_editor (guestfs_h *g, const char *filename, const char *editor, const char *backup_extension, int verbose) "filename" "editor" . "backup_extension" (null) "filename" "backup_extension" . "editor" null $EDITOR "vi" . -1 0 ( ) 1 . "common/edit/file-edit.c:edit_file_perl" int edit_file_perl (guestfs_h *g, const char *filename, const char *perl_expr, const char *backup_extension, int verbose) "filename" "perl_expr" Perl. "backup_extension" (null) "filename" "backup_extension" . -1 0 . common/options common/options/config.c guestfish ~/.libguestfs-tools.rc /etc/libguestfs-tools.conf . "parse_config" "verbose" "g" . common/options/decrypt.c (mount) . "common/options/decrypt.c:make_mapname" static char * make_mapname (const char *device) LUKS (logical volume) : "/dev/vda2" => "cryptvda2" "/dev/vg-ssd/lv-root7" => "cryptvgssdlvroot7". c_isalnum() "/" VG LV . "common/options/decrypt.c:inspect_do_decrypt" void inspect_do_decrypt (guestfs_h *g, struct key_store *ks) : VG. common/options/display-options.c --short-options --long-options virt C . ( virt OCaml common/mltools/getopt.ml ). <<>> (tab completion) bash . "common/options/display-options.c:display_short_options" void display_short_options (const char *format) "tool --short-options" . bash . "common/options/display-options.c:display_long_options" void display_long_options (const struct option *long_options) "tool --long-options" . bash . common/options/domain.c -d guestfish ( ) . "common/options/domain.c:add_libvirt_drives" int add_libvirt_drives (guestfs_h *g, const char *guest) "guestfish -d guest" . ("> 0") -1 . common/options/inspect.c . -i guestfish(1) virt-cat(1) . "common/options/inspect.c:inspect_mount_handle" void inspect_mount_handle (guestfs_h *g, struct key_store *ks) -i . "common/options/inspect.c:print_inspect_prompt" void print_inspect_prompt (void) "inspect_mount_root" . common/options/keys.c "common/options/keys.c:read_key" char * read_key (const char *param) ('Key') /dev/tty (echo off)..PP (fish/cmds.c) free . "text:..." ( libguestfs >= 1.60). Base64 . lib/utils.c cryptsetup. common/options/options.c guestfish . guestfish virt-cat virt-ls -a "OPTION_a" fish/options.h . "drvs" "verbose" -v . "common/options/options.c:option_a" void option_a (const char *arg, const char *format, int blocksize, struct drv **drvsp) -a guestfish . "common/options/options.c:option_d" void option_d (const char *arg, struct drv **drvsp) -d . "common/options/options.c:display_mountpoints_on_failure" static void display_mountpoints_on_failure (const char *mp_device, const char *user_supplied_options) -m (mountpoints) . common/options/uri.c URI -a guestfish(1) virt-cat(1) virt-builder(1) virt-customize(1) . common/parallel common/parallel/domains.c "virt-df" libvirt ( ) "virt-df" . libvirt . "common/parallel/domains.c:free_domains" void free_domains (void) "get_all_libvirt_domains" . "common/parallel/domains.c:get_all_libvirt_domains" void get_all_libvirt_domains (const char *libvirt_uri) libguest "domains" "nr_domains" . . . common/parallel/estimate-max-threads.c "common/parallel/estimate-max-threads.c:estimate_max_threads" size_t estimate_max_threads (void) "free -m" appliance libguestfs . >= 1 . "common/parallel/estimate-max-threads.c:read_line_from" static char * read_line_from (const char *cmd) . common/parallel/parallel.c "virt-df" libguestfs libvirt . . ( ). "common/parallel/parallel.c:start_threads" int start_threads (size_t option_P, guestfs_h *options_handle, work_fn work) libvirt . "option_P" -P 0 -P ( ). "options_handle" ( "NULL" ) (handle) guestfs . ("work") ( ) "i" . . "FILE *" . 0 -1 . "start_threads" 0 -1 ..SS " common/progress" common/progress/progress.c guestfish(1) virt-resize(1) virt-sparsify(1) . "common/progress/progress.c:progress_bar_init" struct progress_bar * progress_bar_init (unsigned flags) struct . struct ( thread ). "progress_bar_reset" . "common/progress/progress.c:progress_bar_free" void progress_bar_free (struct progress_bar *bar) struct . "common/progress/progress.c:progress_bar_reset" void progress_bar_reset (struct progress_bar *bar) . "common/progress/progress.c:estimate_remaining_time" static double estimate_remaining_time (struct progress_bar *bar, double ratio) ( ) . (s.d.) . ( 0.0 ). "common/progress/progress.c:progress_bar_set" void progress_bar_set (struct progress_bar *bar, uint64_t position, uint64_t total) . callback "GUESTFS_EVENT_PROGRESS" . common/qemuopts common/qemuopts/qemuopts-tests.c . handle libguestfs handle (launch) . . common/qemuopts/qemuopts.c qemu qemu. qemu . qemu . . : o qemu "-smp 4" : [smp-opts] cpus = "4" o "-smp 4" "-smp cpus=4" ( qemu ). . o "-opt key=value,..." "key" / . : http://git.qemu.org/?p=qemu.git;a=blob;f=util/keyval.c;h=93d5db6b590427e412dfb172f1c406d6dd8958c1;hb=HEAD o (syntactic sugar) "-kernel foo" "-machine kernel=foo" . "common/qemuopts/qemuopts.c:qemuopts_create" struct qemuopts * qemuopts_create (void) qemu. "qemuopts_free" . "NULL" "errno" . "common/qemuopts/qemuopts.c:qemuopts_free" void qemuopts_free (struct qemuopts *qopts) qemu. "common/qemuopts/qemuopts.c:qemuopts_add_flag" int qemuopts_add_flag (struct qemuopts *qopts, const char *flag) : qemuopts_add_flag (qopts, "-no-user-config"); 0 . -1 "errno" . "common/qemuopts/qemuopts.c:qemuopts_add_arg" int qemuopts_add_arg (struct qemuopts *qopts, const char *flag, const char *value) : qemuopts_add_arg (qopts, "-m", "1024"); . "qemuopts_add_arg_list" . 0 . -1 "errno" . "common/qemuopts/qemuopts.c:qemuopts_add_arg_format" int qemuopts_add_arg_format (struct qemuopts *qopts, const char *flag, const char *fs, ...) . : qemuopts_add_arg_format (qopts, "-m", "%d", 1024); . "qemuopts_add_arg_list" . 0 . -1 "errno" . "common/qemuopts/qemuopts.c:qemuopts_add_arg_noquote" int qemuopts_add_arg_noquote (struct qemuopts *qopts, const char *flag, const char *value) "qemuopts_add_arg" . "qemuopts_to_script" "qemuopts_to_channel" qemu . "qemuopts_to_argv" qemu . "qemuopts_to_config*" . . "common/qemuopts/qemuopts.c:qemuopts_start_arg_list" int qemuopts_start_arg_list (struct qemuopts *qopts, const char *flag) . ( ): qemuopts_start_arg_list (qopts, "-drive"); qemuopts_append_arg_list (qopts, "file=foo"); qemuopts_append_arg_list_format (qopts, "if=%s", "ide"); qemuopts_end_arg_list (qopts); "-drive file=foo,if=ide" . "qemuopts_add_arg_list" . 0 . -1 "errno" . "common/qemuopts/qemuopts.c:qemuopts_add_arg_list" int qemuopts_add_arg_list (struct qemuopts *qopts, const char *flag, const char *elem0, ...) . : qemuopts_add_arg_list (qopts, "-drive", "file=foo", "if=ide", NULL); : "-drive file=foo,if=ide". qemu . 0 . -1 "errno" . "common/qemuopts/qemuopts.c:qemuopts_set_binary" int qemuopts_set_binary (struct qemuopts *qopts, const char *binary) qemu . 0 . -1 "errno" . "common/qemuopts/qemuopts.c:qemuopts_set_binary_by_arch" int qemuopts_set_binary_by_arch (struct qemuopts *qopts, const char *arch) qemu "qemu-system-[arch]" . "arch" "NULL" KVM : qemuopts_set_binary_by_arch (qopts, NULL); 0 . -1 "errno" . "common/qemuopts/qemuopts.c:qemuopts_to_script" int qemuopts_to_script (struct qemuopts *qopts, const char *filename) qemu . "qemuopts_set_binary*" . "#!/bin/sh" chmod 0755 . 0 . -1 "errno" . "common/qemuopts/qemuopts.c:shell_quote" static void shell_quote (const char *str, FILE *fp) "str" "fp" . "common/qemuopts/qemuopts.c:shell_and_comma_quote" static void shell_and_comma_quote (const char *str, FILE *fp) "str" qemu "fp" . "common/qemuopts/qemuopts.c:qemuopts_to_channel" int qemuopts_to_channel (struct qemuopts *qopts, FILE *fp) qemu "FILE *fp" . "qemuopts_set_binary*" . qemu . "#!/bin/sh" chmod 0755 . 0 . -1 "errno" . "common/qemuopts/qemuopts.c:qemuopts_to_argv" char ** qemuopts_to_argv (struct qemuopts *qopts) NULL execv(3) . "qemuopts_set_binary*" . "argv[0]" ..PP . "NULL" "errno" . "common/qemuopts/qemuopts.c:qemuopts_to_config_file" int qemuopts_to_config_file (struct qemuopts *qopts, const char *filename) qemu qemu "qemu -readconfig filename" . qemu (quoting) qemuopts ( ). : https://habkost.net/posts/2016/12/qemu-apis-qemuopts.html https://bugs.launchpad.net/qemu/+bug/1686364 . "-m 1024" : [memory] size = "1024" . . 0 . -1 "errno" . "common/qemuopts/qemuopts.c:qemuopts_to_config_channel" int qemuopts_to_config_channel (struct qemuopts *qopts, FILE *fp) "qemuopts_to_config_file" "FILE *fp" . common/utils common/utils/cleanups.c libguestfs "CLEANUP_*" . "__attribute__((cleanup))" gcc clang . : fn () { CLEANUP_FREE char *str = NULL; str = safe_asprintf (g, "foo"); // str is freed automatically when the function returns } cleanup : o cleanup free(3) . cleanup "NULL" o cleanup . o main() cleanup exit(3) cleanup . "CLEANUP_*" . . common/utils/gnulib-cleanups.c libguestfs "CLEANUP_*" . "__attribute__((cleanup))" gcc clang . : fn () { CLEANUP_FREE char *str = NULL; str = safe_asprintf (g, "foo"); // str is freed automatically when the function returns } cleanup : o cleanup free(3) . cleanup "NULL" o cleanup . o main() cleanup exit(3) cleanup . "CLEANUP_*" . . common/utils/guestfs-utils.h (header) libguestfs C virt . (daemon) . lib/guestfs-internal-all.h . libguestfs ( virt ) ! common/utils/libxml2-writer-macros.h XML . : o "xmlTextWriterPtr" "xo" . . o "xml_error" ( ). "CLEANUP_*" . o (casting) <<>> . "common/utils/libxml2-writer-macros.h:start_element" #define start_element XML : start_element ("name") { ... } end_element (); "..." . "common/utils/libxml2-writer-macros.h:empty_element" #define empty_element : empty_element ("name"); "" . "common/utils/libxml2-writer-macros.h:single_element" #define single_element : single_element ("name", text); "text" "common/utils/libxml2-writer-macros.h:single_element_format" #define single_element_format : single_element_format ("cores", "%d", nr_cores); "4" "common/utils/libxml2-writer-macros.h:attribute" #define attribute XML : start_element ("name") { attribute ("foo", "bar"); attribute_format ("count", "%d", count); ... } end_element (); "..." "common/utils/libxml2-writer-macros.h:attribute_ns" #define attribute_ns "attribute_ns (prefix, key, namespace_uri, value)" . "common/utils/libxml2-writer-macros.h:string" #define string (verbatim) : string ("hello"); "common/utils/libxml2-writer-macros.h:string_format" #define string_format : string ("%s, world", greeting); "common/utils/libxml2-writer-macros.h:base64" #define base64 base64: base64 (data, size); "common/utils/libxml2-writer-macros.h:comment" #define comment (comment) XML : comment ("number of items = %d", nr_items); common/utils/stringlists-utils.c . "safe_*" "error" "perrorf" "guestfs_int_*" . "common/utils/stringlists-utils.c:guestfs_int_split_string" char ** guestfs_int_split_string (char sep, const char *str) "sep" . "NULL" . ( "sep" ":" ): "str == NULL" "str == """ "[]" "str == "abc"" "["abc"]" "str == ":"" "["", ""]" common/utils/utils.c . "safe_*" "error" "perrorf" "guestfs_int_*" . "common/utils/utils.c:guestfs_int_replace_string" char * guestfs_int_replace_string (const char *str, const char *s1, const char *s2) "s1" "str" "s2" . . "NULL" . : replace_string ("abcabb", "ab", "a"); "acab" . "common/utils/utils.c:guestfs_int_exit_status_to_string" char * guestfs_int_exit_status_to_string (int status, const char *cmd_name, char *buffer, size_t buflen) wait/system ..PP "common/utils/utils.c:guestfs_int_random_string" int guestfs_int_random_string (char *ret, size_t len) . : o "ret" "\0" "len+1" . o ( "5*len" ). "common/utils/utils.c:guestfs_int_drive_name" char * guestfs_int_drive_name (size_t index, char *ret) ( 27) ( "ab") . 0 . ** . https://rwmj.wordpress.com/2011/01/09/how-are-linux-drives-named-beyond-drive-26-devsdz "common/utils/utils.c:guestfs_int_drive_index" ssize_t guestfs_int_drive_index (const char *name) "guestfs_int_drive_name". "ab" ( 27). "hd" "sd" . "common/utils/utils.c:guestfs_int_is_true" int guestfs_int_is_true (const char *str) "Tcl_GetBoolean". "common/utils/utils.c:guestfs_int_string_is_valid" bool guestfs_int_string_is_valid (const char *str, size_t min_length, size_t max_length, int flags, const char *extra) . *VALID_ lib/drives.c . "str" . "min_length" "max_length" . 0 . : "VALID_FLAG_ALPHA" ASCII (7-bit) . "VALID_FLAG_DIGIT" ASCII (7-bit) . "extra" / . ("extra = NULL" ). ( ) "true" "false" . "common/utils/utils.c:guestfs_int_fadvise_normal" void guestfs_int_fadvise_normal (int fd) . "FMODE_RANDOM" [ ] (readahead) . . "common/utils/utils.c:guestfs_int_fadvise_sequential" void guestfs_int_fadvise_sequential (int fd) . "FMODE_RANDOM" [ ] (readahead) . . "common/utils/utils.c:guestfs_int_fadvise_random" void guestfs_int_fadvise_random (int fd) . "FMODE_RANDOM" . : o (readahead) . o (page cache) . [ - ] . "common/utils/utils.c:guestfs_int_fadvise_noreuse" void guestfs_int_fadvise_noreuse (int fd) . . . "common/utils/utils.c:guestfs_int_fadvise_dontneed" void guestfs_int_fadvise_dontneed (int fd) . (dirty pages) (page cache) (drop) . . ..PP (hint) . "common/utils/utils.c:guestfs_int_fadvise_willneed" void guestfs_int_fadvise_willneed (int fd) . (page cache) . page cache . . "common/utils/utils.c:guestfs_int_shell_unquote" char * guestfs_int_shell_unquote (const char *str) . Augeas /etc/sysconfig . . . . "str" Augeas . (free) . "NULL" "errno" . bash : https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html "common/utils/utils.c:guestfs_int_is_reg" int guestfs_int_is_reg (int64_t mode) "st_mode" "guestfs_statns" "guestfs_lstatns" (regular file) (true) . "common/utils/utils.c:guestfs_int_is_dir" int guestfs_int_is_dir (int64_t mode) "st_mode" "guestfs_statns" "guestfs_lstatns" (true) . "common/utils/utils.c:guestfs_int_is_chr" int guestfs_int_is_chr (int64_t mode) "st_mode" "guestfs_statns" "guestfs_lstatns" (char device) (true) . "common/utils/utils.c:guestfs_int_is_blk" int guestfs_int_is_blk (int64_t mode) "st_mode" "guestfs_statns" "guestfs_lstatns" (block device) (true) . "common/utils/utils.c:guestfs_int_is_fifo" int guestfs_int_is_fifo (int64_t mode) "st_mode" "guestfs_statns" "guestfs_lstatns" (FIFO) (true) . "common/utils/utils.c:guestfs_int_is_lnk" int guestfs_int_is_lnk (int64_t mode) "st_mode" "guestfs_statns" "guestfs_lstatns" (true) . "common/utils/utils.c:guestfs_int_is_sock" int guestfs_int_is_sock (int64_t mode) "st_mode" "guestfs_statns" "guestfs_lstatns" (Unix domain socket) (true) . "common/utils/utils.c:guestfs_int_full_path" char * guestfs_int_full_path (const char *dir, const char *name) "dir" "name" . "/" + "filename" "/dir" + "filename" . "name" "NULL" . (free) . "errno" "NULL" . "common/utils/utils.c:guestfs_int_hexdump" void guestfs_int_hexdump (const void *data, size_t len, FILE *fp) (hexdump) "FILE *" . "common/utils/utils.c:guestfs_int_strerror" const char * guestfs_int_strerror (int errnum, char *buf, size_t buflen) strerror_r (Thread-safe). strerror_r(3) glibc (RHBZ#2030396). ( ) (non-static) . . common/utils/whole-file.c "common/utils/whole-file.c:read_whole_file" int read_whole_file (const char *filename, char **data_r, size_t *size_r) "filename" ..PP "data_r" . "size_r" . . "stderr" -1 . "guestfs_int_read_whole_file" libguestfs error() . NUL (NUL ). . (denial-of-service) . common/visit common/visit/visit.c guestfs . https://rwmj.wordpress.com/2010/12/15/tip-audit-virtual-machine-for-setuid-files "common/visit/visit.c:visit" int visit (guestfs_h *g, const char *dir, visitor_function f, void *opaque) guestfs "dir" . "dir" "/" . . "f" . "f" ( "NULL" ) "guestfs_statns" ( ) . -1 . "opaque" . 0 -1 . libguestfs stderr . common/windows common/windows/windows.c "win:" guestfish(1) . "common/windows/windows.c:is_windows" int is_windows (guestfs_h *g, const char *root) "root" . (introspection) . "common/windows/windows.c:windows_path" char * windows_path (guestfs_h *g, const char *root, const char *path, int readonly) "path" "root" API libguestfs . : o "root" o o unmount ( "readonly") mount o exit(3) .SS " daemon" daemon/command.c . "daemon/command.c:commandf" int commandf (char **stdoutput, char **stderror, unsigned flags, const char *name, ...) . stdout stderr . 0 -1 . "flags" "commandrvf" . "command(out,err,name,...)" "commandf" "flags=0" . "daemon/command.c:commandrf" int commandrf (char **stdoutput, char **stderror, unsigned flags, const char *name, ...) "command" . -1 . "commandr(out,err,name,...)" "commandrf" "flags=0" . "daemon/command.c:commandvf" int commandvf (char **stdoutput, char **stderror, unsigned flags, char const *const *argv) "command" argv . "commandv(out,err,argv)" "commandvf" "flags=0" . "daemon/command.c:commandrvf" int commandrvf (char **stdoutput, char **stderror, unsigned flags, char const* const *argv) system(3) . fork/execvp . "stdoutput" "NULL" *stdoutput stdout . "stderror" "NULL" *stderror stderr . \n "reply_with_error" . : "COMMAND_FLAG_FOLD_STDOUT_ON_STDERR" stdout ( parted) stdout *stderror . "stdoutput=NULL" . "COMMAND_FLAG_CHROOT_COPY_FILE_TO_STDIN" chroot ( https://bugzilla.redhat.com/579608 ) sysroot chroot stdin . OR . daemon/hexdump.c . "commandrv(out,err,argv)" "commandrvf" "flags=0" . daemon/device-name-translation.c "daemon/device-name-translation.c:device_name_translation_init" void device_name_translation_init (void) daemon. daemon /dev/disk/by-path . "ls -lv" . "daemon/device-name-translation.c:device_name_translation" char * device_name_translation (const char *device) . Libguestfs ( "BLOCK DEVICE NAMING" guestfs(3) "guestfs_canonical_device_name" guestfs(3) ). : /dev/sdX[N] /dev/hdX[N] /dev/vdX[N] N X . qemu /dev/disk/by-path/ . /dev/mdX /dev/VG/LV /dev/mapper/... /dev/dm-N . (free) . "NULL" . "reply_with_*" . "ENXIO" appliance . daemon/guestfsd.c daemon guestfs guestfs appliance . . "daemon/guestfsd.c:shell_quote" void shell_quote (const char *str, FILE *fp) "str" "fp" (shell quoted) ..PP "daemon/guestfsd.c:sysroot_shell_quote" void sysroot_shell_quote (const char *path, FILE *fp) "sysroot" + "path" "fp" (shell quoted) . . daemon/internal.c API . daemon/utils-c.c (Bindings) . OCaml "reply*" . daemon/utils.c (daemon) . "daemon/utils.c:is_root_device_stat" static int is_root_device_stat (struct stat *statbuf) (root device) true ( ). "daemon/utils.c:is_device_parameter" int is_device_parameter (const char *device) "Device" "Dev_or_Path" . . "Dev_or_Path" . "daemon/utils.c:sysroot_path" char * sysroot_path (const char *path) "/path" "/sysroot/path". "NULL" . "reply_with_perror ("malloc")" . (free) . %R printf (shell quoting) . "daemon/utils.c:sysroot_realpath" char * sysroot_realpath (const char *path) sysroot "sysroot_path" . "NULL" . "reply_with_perror ("malloc")" . (free) . %R printf (shell quoting) . "daemon/utils.c:is_power_of_2" int is_power_of_2 (unsigned long v) "v" true . : http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2 "daemon/utils.c:split_lines_sb" struct stringsbuf split_lines_sb (char *str) NULL stringsbuf . . . : "" "[]" "\n" "[""]" "a\nb" "["a"; "b"]" "a\nb\n" "["a"; "b"]" "a\nb\n\n" "["a"; "b"; ""]" ( 'out' "command*()" ). add_string() strdup . "argv" "struct stringsbuf" "NULL" . "daemon/utils.c:filter_list" char ** filter_list (bool (*p) (const char *str), char **strs) . "p (str) == true" . (double-free) . "daemon/utils.c:trim" void trim (char *str) . "daemon/utils.c:parse_btrfsvol" int parse_btrfsvol (const char *desc_orig, mountable_t *mountable) mountable (subvolume) btrfs . stub ..PP (subvolume) btrfs : btrfsvol:/dev/sda3/root /dev/sda3 btrfs root . "btrfsvol:" . "mountable->device" "mountable->volume" . "daemon/utils.c:mountable_to_string" char * mountable_to_string (const mountable_t *mountable) "mountable_t" "reply_with_error" . "daemon/utils.c:prog_exists" int prog_exists (const char *prog) $PATH . "daemon/utils.c:random_name" int random_name (char *template) "/sysroot/XXXXXXXX.XXX" . . 'X' '/' . : 8.3 FAT . ASCII . ( RNG ). -1 . "daemon/utils.c:udev_settle_file" void udev_settle_file (const char *file) LVM udev . "/dev" . . "udevadm settle" . "daemon/utils.c:make_exclude_from_file" char * make_exclude_from_file (const char *function, char *const *excludes) "excludes" . (unlink) . "function" . daemon/xattr.c "daemon/xattr.c:split_attr_names" static char ** split_attr_names (char *buf, size_t len) listxattr(2) "foo\0bar\0baz" "len" . ( \0 \0 "len" ). . "buf" (double-free) ..SS " fish" fish/alloc.c "alloc" "sparse" guestfish . "fish/alloc.c:alloc_disk" int alloc_disk (const char *filename, const char *size_str, int add, int sparse) . guestfish . fish/copy.c "copy-in" "copy-out" guestfish . fish/destpaths.c (tab-completion) guestfish . fish/display.c "display" guestfish ( ) . fish/echo.c "echo" guestfish . fish/edit.c "edit" guestfish Jan Ondrej. fish/events.c guestfish : "event" "delete-event" "list-events". fish/fish.c guestfish . . "fish/fish.c:parse_command_line" static struct parsed_command parse_command_line (char *buf, int *exit_on_error_rtn) '!' '#' . "buf" () . "exit_on_error_rtn" "exit_on_error" ( '-' ) . "parsed_command.status" : 1 guestfish ( "cmd_rtn"/"argv_rtn"/"pipe_rtn" ) 0 guestfish -1 "fish/fish.c:parse_quoted_string" static ssize_t parse_quoted_string (char *p) . . "fish/fish.c:execute_and_inline" static int execute_and_inline (const char *cmd, int global_exit_on_error) " ) . "fish/fish.c:issue_command" int issue_command (const char *cmd, char *argv[], const char *pipecmd, int rc_exit_on_error_flag) . "rc_exit_on_error_flag" "exit_on_error" ( --remote) . "issue_command" . "fish/fish.c:extended_help_message" void extended_help_message (void) . : guestfish disk.img guestfish disk.img ( "disk.img" ). "fish/fish.c:error_cb" static void error_cb (guestfs_h *g, void *data, const char *msg) . libguestfs . "fish/fish.c:free_n_strings" static void free_n_strings (char **str, size_t len) "char**" NULL . "fish/fish.c:decode_ps1" static char * decode_ps1 (const char *str) "str" () . "fish/fish.c:win_prefix" char * win_prefix (const char *path) "win:..." Windows. ..PP "NULL" . "fish/fish.c:file_in" char * file_in (const char *arg) "FileIn" ("-" "-< ) . (fish/cmds.c) "free_file_in" . "fish/fish.c:file_out" char * file_out (const char *arg) "FileOut" ("-" ) . (fish/cmds.c) "free (str)" . "fish/fish.c:progress_callback" void progress_callback (guestfs_h *g, void *data, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len) (callback) . fish/glob.c "glob" guestfish . "fish/glob.c:expand_devicename" static char ** expand_devicename (guestfs_h *g, const char *device) glob "/dev/sd*" (https://bugzilla.redhat.com/635971). "guestfs_glob_expand_device" "guestfs_list_devices" . "/dev/sd*" . "/dev/" + "*" VG LV glob . (XXX): o . . o API . "fish/glob.c:add_strings_matching" static int add_strings_matching (char **pp, const char *glob, char ***ret, size_t *size_r) fnmatch(3) POSIX "pp" "glob" . "ret" . *size_r "ret" . "fish/glob.c:single_element_list" static char ** single_element_list (const char *element) "element" . fish/help.c "help" guestfish . "fish/help.c:display_help" int display_help (const char *cmd, size_t argc, char *argv[]) "help". . (context-sensitive) . (mount) . fish/hexedit.c "hexedit" guestfish . fish/lcd.c "fish/lcd.c:run_lcd" int run_lcd (const char *cmd, size_t argc, char *argv[]) "lcd" guestfish ( "lcd" BSD ftp). fish/man.c "fish/man.c:run_man" int run_man (const char *cmd, size_t argc, char *argv[]) "man" guestfish fish/more.c "more" guestfish . fish/not.c "not" guestfish . fish/prep.c -N guestfish . fish/rc.c () guestfish . "fish/rc.c:rc_listen" void rc_listen (void) ( "guestfish --listen"). "fish/rc.c:rc_remote" int rc_remote (int pid, const char *cmd, size_t argc, char *argv[], int exit_on_error) ( "guestfish --remote"). fish/reopen.c "reopen" guestfish . fish/setenv.c "setenv" "unsetenv" guestfish . fish/supported.c "supported" guestfish . fish/tilde.c ("~") guestfish(1) . "fish/tilde.c:try_tilde_expansion" char * try_tilde_expansion (char *str) "~username" ( ) . "fish/tilde.c:expand_home" static char * expand_home (char *orig, const char *append) $HOME + append . "fish/tilde.c:find_home_for_username" static const char * find_home_for_username (const char *username, size_t ulen) "username" ( "ulen") "NULL" . fish/time.c "time" guestfish . python python/handle.c . ( python/actions-*.c)..SH " (SEE ALSO)" guestfs(3), guestfs-building(1), guestfs-examples(3), guestfs-internals(1), guestfs-performance(1), guestfs-release-notes(1), guestfs-testing(1), libguestfs-test-tool(1), libguestfs-make-fixed-appliance(1), http://libguestfs.org. (AUTHORS) Richard W.M. Jones ("rjones at redhat dot com") (COPYRIGHT) Copyright (C) 2009-2025 Red Hat Inc. (LICENSE) << >> (GNU Lesser General Public License) -- ( ) -- / . . << >> . << >> : Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (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 : o libguestfs. o libguestfs ( ). o . o libguestfs-test-tool(1) . libguestfs-1.60.1 2026-07-14 guestfs-hacking(1)