As a side effect, a lot more fields are now settable on the kernel command line. Existing kernel command lines & corresponding documentation should still remain backwards compatible. --- .gitignore | 2 + generator/main.ml | 4 + generator/p2v_config.ml | 458 ++++++++++++++++++++++++++++++++++++++- generator/p2v_config.mli | 2 + p2v/Makefile.am | 8 +- p2v/kernel.c | 154 ------------- p2v/p2v.h | 4 +- p2v/virt-p2v.pod | 131 +---------- po-docs/language.mk | 8 + po-docs/podfiles | 1 + 10 files changed, 475 insertions(+), 297 deletions(-) diff --git a/.gitignore b/.gitignore index 4c0ff4e1e..d855459f3 100644 --- a/.gitignore +++ b/.gitignore @@ -435,6 +435,7 @@ Makefile.in /p2v/dependencies.debian /p2v/dependencies.redhat /p2v/dependencies.suse +/p2v/kernel-config.c /p2v/p2v-config.h /p2v/stamp-test-virt-p2v-pxe-data-files /p2v/stamp-test-virt-p2v-pxe-hostkey @@ -457,6 +458,7 @@ Makefile.in /p2v/virt-p2v.1 /p2v/virt-p2v.i686 /p2v/virt-p2v.img +/p2v/virt-p2v-kernel-config.pod /p2v/virt-p2v-make-disk /p2v/virt-p2v-make-disk.1 /p2v/virt-p2v-make-kickstart diff --git a/generator/main.ml b/generator/main.ml index ecc551f72..72f31ecab 100644 --- a/generator/main.ml +++ b/generator/main.ml @@ -367,6 +367,10 @@ Run it from the top source directory using the command P2v_config.generate_p2v_config_h; output_to "p2v/config.c" P2v_config.generate_p2v_config_c; + output_to "p2v/kernel-config.c" + P2v_config.generate_p2v_kernel_config_c; + output_to "p2v/virt-p2v-kernel-config.pod" + P2v_config.generate_p2v_kernel_config_pod; (* Generate the list of files generated -- last. *) printf "generated %d lines of code\n" (get_lines_generated ()); diff --git a/generator/p2v_config.ml b/generator/p2v_config.ml index e0347d6c2..11aec5ee3 100644 --- a/generator/p2v_config.ml +++ b/generator/p2v_config.ml @@ -26,7 +26,7 @@ open Pr let generate_header = generate_header ~inputs:["generator/p2v_config.ml"] -type enum_choice = string * string (* name, comment *) +type enum_choice = string * string * string (* name, cmdline, comment *) type enum = string * enum_choice list type config_entry = @@ -39,17 +39,22 @@ type config_entry = | ConfigStringList of string | ConfigSection of string * config_entry list +type manual_entry = { + shortopt : string; + description : string; +} + (* Enums. *) let enums = [ "basis", [ - "BASIS_UNKNOWN", "RTC could not be read"; - "BASIS_UTC", "RTC is either UTC or an offset from UTC"; - "BASIS_LOCALTIME", "RTC is localtime"; + "BASIS_UNKNOWN", "unknown", "RTC could not be read"; + "BASIS_UTC", "utc", "RTC is either UTC or an offset from UTC"; + "BASIS_LOCALTIME", "localtime", "RTC is localtime"; ]; "output_allocation", [ - "OUTPUT_ALLOCATION_NONE", "output allocation not set"; - "OUTPUT_ALLOCATION_SPARSE", "sparse"; - "OUTPUT_ALLOCATION_PREALLOCATED", "preallocated"; + "OUTPUT_ALLOCATION_NONE", "none", "output allocation not set"; + "OUTPUT_ALLOCATION_SPARSE", "sparse", "sparse"; + "OUTPUT_ALLOCATION_PREALLOCATED", "preallocated", "preallocated"; ]; ] @@ -99,6 +104,245 @@ let fields = [ ]); ] +(* Some /proc/cmdline p2v.* options were renamed when we introduced + * the generator. This map creates backwards compatibility mappings + * for these. + *) +let cmdline_aliases = [ + "p2v.remote.server", ["p2v.server"]; + "p2v.remote.port", ["p2v.port"]; + "p2v.auth.username", ["p2v.username"]; + "p2v.auth.password", ["p2v.password"]; + "p2v.auth.identity.url", ["p2v.identity"]; + "p2v.auth.sudo", ["p2v.sudo"]; + "p2v.guestname", ["p2v.name"]; + "p2v.network_map", ["p2v.network"]; + "p2v.output.type", ["p2v.o"]; + "p2v.output.allocation", ["p2v.oa"]; + "p2v.output.connection", ["p2v.oc"]; + "p2v.output.format", ["p2v.of"]; + "p2v.output.storage", ["p2v.os"]; +] + +(* Some config entries are not exposed on the kernel command line. *) +let cmdline_ignore = [ + "p2v.auth.identity.file"; + "p2v.auth.identity.file_needs_update"; +] + +(* Man page snippets for each kernel command line setting. *) +let cmdline_manual = [ + "p2v.remote.server", { + shortopt = "SERVER"; + description = " +The name or IP address of the conversion server. + +This is always required if you are using the kernel configuration +method. If virt-p2v does not find this on the kernel command line +then it switches to the GUI (interactive) configuration method."; + }; + "p2v.remote.port", { + shortopt = "PORT"; + description = " +The SSH port number on the conversion server (default: C<22>)."; + }; + "p2v.auth.username", { + shortopt = "USERNAME"; + description = " +The SSH username that we log in as on the conversion server +(default: C<root>)."; + }; + "p2v.auth.password", { + shortopt = "PASSWORD"; + description = " +The SSH password that we use to log in to the conversion server. + +The default is to try with no password. If this fails then virt-p2v +will ask the user to type the password (probably several times during +conversion). + +This setting is ignored if C<p2v.auth.identity.url> is present."; + }; + "p2v.auth.identity.url", { + shortopt = "URL"; + description = " +Provide a URL pointing to an SSH identity (private key) file. The URL +is interpreted by L<curl(1)> so any URL that curl supports can be used +here, including C<https://> and C<file://>. For more information on +using SSH identities, see L</SSH IDENTITIES> below. + +If C<p2v.auth.identity.url> is present, it overrides C<p2v.auth.password>. +There is no fallback."; + }; + "p2v.auth.sudo", { + shortopt = ""; (* ignored for booleans *) + description = " +Use C<p2v.sudo> to tell virt-p2v to use L<sudo(8)> to gain root +privileges on the conversion server after logging in as a non-root +user (default: do not use sudo)."; + }; + "p2v.guestname", { + shortopt = "GUESTNAME"; + description = " +The name of the guest that is created. The default is to try to +derive a name from the physical machine’s hostname (if possible) else +use a randomly generated name."; + }; + "p2v.vcpus", { + shortopt = "N"; + description = " +The number of virtual CPUs to give to the guest. The default is to +use the same as the number of physical CPUs."; + }; + "p2v.memory", { + shortopt = "n(M|G)"; + description = " +The size of the guest memory. You must specify the unit such as +megabytes or gigabytes by using for example C<p2v.memory=1024M> or +C<p2v.memory=1G>. + +The default is to use the same amount of RAM as on the physical +machine."; + }; + "p2v.cpu.vendor", { + shortopt = "VENDOR"; + description = " +The vCPU vendor, eg. \"Intel\" or \"AMD\". The default is to use +the same CPU vendor as the physical machine."; + }; + "p2v.cpu.model", { + shortopt = "MODEL"; + description = " +The vCPU model, eg. \"IvyBridge\". The default is to use the same +CPU model as the physical machine."; + }; + "p2v.cpu.sockets", { + shortopt = "N"; + description = " +Number of vCPU sockets to use. The default is to use the same as the +physical machine."; + }; + "p2v.cpu.cores", { + shortopt = "N"; + description = " +Number of vCPU cores to use. The default is to use the same as the +physical machine."; + }; + "p2v.cpu.threads", { + shortopt = "N"; + description = " +Number of vCPU hyperthreads to use. The default is to use the same +as the physical machine."; + }; + "p2v.cpu.acpi", { + shortopt = ""; (* ignored for booleans *) + description = " +Whether to enable ACPI in the remote virtual machine. The default is +to use the same as the physical machine."; + }; + "p2v.cpu.apic", { + shortopt = ""; (* ignored for booleans *) + description = " +Whether to enable APIC in the remote virtual machine. The default is +to use the same as the physical machine."; + }; + "p2v.cpu.pae", { + shortopt = ""; (* ignored for booleans *) + description = " +Whether to enable PAE in the remote virtual machine. The default is +to use the same as the physical machine."; + }; + "p2v.rtc.basis", { + shortopt = ""; (* ignored for enums. *) + description = " +Set the basis of the Real Time Clock in the virtual machine. The +default is to try to detect this setting from the physical machine."; + }; + "p2v.rtc.offset", { + shortopt = "[+|-]HOURS"; + description = " +The offset of the Real Time Clock from UTC. The default is to try +to detect this setting from the physical machine."; + }; + "p2v.disks", { + shortopt = "sda,sdb,..."; + description = " +A list of physical hard disks to convert, for example: + + p2v.disks=sda,sdc + +The default is to convert all local hard disks that are found."; + }; + "p2v.removable", { + shortopt = "sra,srb,..."; + description = " +A list of removable media to convert. The default is to create +virtual removable devices for every physical removable device found. +Note that the content of removable media is never copied over."; + }; + "p2v.interfaces", { + shortopt = "em1,..."; + description = " +A list of network interfaces to convert. The default is to create +virtual network interfaces for every physical network interface found."; + }; + "p2v.network_map", { + shortopt = "interface:target,..."; + description = " +Controls how network interfaces are connected to virtual networks on +the target hypervisor. The default is to connect all network +interfaces to the target C<default> network. + +You give a comma-separated list of C<interface:target> pairs, plus +optionally a default target. For example: + + p2v.network=em1:ovirtmgmt + +maps interface C<em1> to target network C<ovirtmgmt>. + + p2v.network=em1:ovirtmgmt,em2:management,other + +maps interface C<em1> to C<ovirtmgmt>, and C<em2> to C<management>, +and any other interface that is found to C<other>."; + }; + "p2v.output.type", { + shortopt = "(libvirt|local|...)"; + description = " +Set the output mode. This is the same as the virt-v2v I<-o> option. +See L<virt-v2v(1)/OPTIONS>. + +If not specified, the default is C<local>, and the converted guest is +written to F</var/tmp>."; + }; + "p2v.output.allocation", { + shortopt = ""; (* ignored for enums *) + description = " +Set the output allocation mode. This is the same as the virt-v2v +I<-oa> option. See L<virt-v2v(1)/OPTIONS>."; + }; + "p2v.output.connection", { + shortopt = "URI"; + description = " +Set the output connection libvirt URI. This is the same as the +virt-v2v I<-oc> option. See L<virt-v2v(1)/OPTIONS> and +L<http://libvirt.org/uri.html>"; + }; + "p2v.output.format", { + shortopt = "(raw|qcow2|...)"; + description = " +Set the output format. This is the same as the virt-v2v I<-of> +option. See L<virt-v2v(1)/OPTIONS>."; + }; + "p2v.output.storage", { + shortopt = "STORAGE"; + description = " +Set the output storage. This is the same as the virt-v2v I<-os> +option. See L<virt-v2v(1)/OPTIONS>. + +If not specified, the default is F</var/tmp> (on the conversion server)."; + }; +] + let name_of_config_entry = function | ConfigString n | ConfigInt (n, _) @@ -126,7 +370,7 @@ let rec generate_p2v_config_h () = fun (name, fields) -> pr "enum %s {\n" name; List.iter ( - fun (n, comment) -> + fun (n, _, comment) -> pr " %-25s /* %s */\n" (n ^ ",") comment ) fields; pr "};\n"; @@ -256,9 +500,9 @@ pr "\ pr "{\n"; pr " switch (v) {\n"; List.iter ( - fun (n, comment) -> + fun (n, cmdline, _) -> pr " case %s:\n" n; - pr " fprintf (fp, \"%s\");\n" comment; + pr " fprintf (fp, \"%s\");\n" cmdline; pr " break;\n"; ) fields; pr " }\n"; @@ -395,3 +639,197 @@ and generate_field_print prefix v fields = let v = sprintf "%s%s." v n in generate_field_print (Some printable_name) v fields ) fields + +let rec generate_p2v_kernel_config_c () = + generate_header CStyle GPLv2plus; + + pr "\ +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> +#include <unistd.h> +#include <errno.h> +#include <error.h> + +#include \"xstrtol.h\" + +#include \"p2v.h\" +#include \"p2v-config.h\" + +/** + * Read the kernel command line and parse out any C<p2v.*> fields that + * we understand into the config struct. + */ +void +update_config_from_kernel_cmdline (struct config *c, char **cmdline) +{ + const char *p; + strtol_error xerr; + unsigned long long ull; + +"; + + generate_field_config "p2v" "c->" fields; + + pr " if (c->auth.identity.url != NULL) + c->auth.identity.file_needs_update = 1; + + /* Undocumented command line parameter used for testing command line + * parsing. + */ + p = get_cmdline_key (cmdline, \"p2v.dump_config_and_exit\"); + if (p) { + print_config (c, stdout); + exit (EXIT_SUCCESS); + } +} +" + +and generate_field_config prefix v fields = + List.iter ( + function + | ConfigSection (n, fields) -> + let prefix = sprintf "%s.%s" prefix n in + let v = sprintf "%s%s." v n in + generate_field_config prefix v fields + + | field -> + let n = name_of_config_entry field in + let key = sprintf "%s.%s" prefix n in + + if not (List.mem key cmdline_ignore) then ( + (* Is there an alias for this field? *) + let aliases = + try List.assoc key cmdline_aliases + with Not_found -> [] in + + pr " if ((p = get_cmdline_key (cmdline, \"%s\")) != NULL" key; + List.iter ( + fun alias -> + pr " ||\n"; + pr " (p = get_cmdline_key (cmdline, \"%s\")) != NULL" alias; + ) aliases; + pr ") {\n"; + + (* Parse the field. *) + (match field with + | ConfigString n -> + pr " free (%s%s);\n" v n; + pr " %s%s = strdup (p);\n" v n; + pr " if (%s%s == NULL)\n" v n; + pr " error (EXIT_FAILURE, errno, \"strdup\");\n" + | ConfigStringList n -> + pr " guestfs_int_free_string_list (%s%s);\n" v n; + pr " %s%s = guestfs_int_split_string (',', p);\n" v n; + pr " if (%s%s == NULL)\n" v n; + pr " error (EXIT_FAILURE, errno, \"strdup\");\n" + | ConfigInt (n, _) -> + pr " if (sscanf (p, \"%%d\", &%s%s) != 1)\n" v n; + pr " error (EXIT_FAILURE, errno,\n"; + pr " \"cannot parse %%s=%%s from the kernel command line\",\n"; + pr " %S, p);\n" key + | ConfigUnsigned n -> + pr " if (sscanf (p, \"%%u\", &%s%s) != 1)\n" v n; + pr " error (EXIT_FAILURE, errno,\n"; + pr " \"cannot parse %%s=%%s from the kernel command line\",\n"; + pr " %S, p);\n" key + | ConfigUInt64 n -> + pr " xerr = xstrtoull (p, NULL, 0, &ull, \"0kKMGTPEZY\");\n"; + pr " if (xerr != LONGINT_OK)\n"; + pr " error (EXIT_FAILURE, 0,\n"; + pr " \"cannot parse %%s=%%s from the kernel command line\",\n"; + pr " %S, p);\n" key; + pr " %s%s = ull;\n" v n + | ConfigEnum (n, enum) -> + let enum_choices = + try List.assoc enum enums + with Not_found -> failwithf "cannot find ConfigEnum %s" enum in + pr " "; + List.iter ( + fun (name, cmdline, _) -> + pr "if (STREQ (p, \"%s\"))\n" cmdline; + pr " %s%s = %s;\n" v n name; + pr " else "; + ) enum_choices; + pr "{\n"; + pr " error (EXIT_FAILURE, 0,\n"; + pr " \"invalid value %%s=%%s from the kernel command line\",\n"; + pr " %S, p);\n" key; + pr " }\n" + | ConfigBool n -> + pr " %s%s = guestfs_int_is_true (p) || STREQ (p, \"\");\n" v n + + | ConfigSection _ -> assert false (* see above *) + ); + + pr " }\n"; + pr "\n"; + ) + ) fields + +let rec generate_p2v_kernel_config_pod () = + generate_field_config_pod "p2v" fields + +and generate_field_config_pod prefix fields = + List.iter ( + function + | ConfigSection (n, fields) -> + let prefix = sprintf "%s.%s" prefix n in + generate_field_config_pod prefix fields + + | field -> + let n = name_of_config_entry field in + let key = sprintf "%s.%s" prefix n in + + if not (List.mem key cmdline_ignore) then ( + let manual_entry = + try List.assoc key cmdline_manual + with Not_found -> + failwithf "generator/p2v_config.ml: missing manual entry for %s" + key in + + (* For booleans there is no shortopt field. For enums + * we generate it. + *) + let shortopt = + match field with + | ConfigBool _ -> + assert (manual_entry.shortopt = ""); + "" + | ConfigEnum (_, enum) -> + assert (manual_entry.shortopt = ""); + + let enum_choices = + try List.assoc enum enums + with Not_found -> failwithf "cannot find ConfigEnum %s" enum in + "=(" ^ + String.concat "|" + (List.map (fun (_, cmdline, _) -> cmdline) + enum_choices) ^ + ")" + | ConfigString _ + | ConfigInt _ + | ConfigUnsigned _ + | ConfigUInt64 _ + | ConfigStringList _ + | ConfigSection _ -> "=" ^ manual_entry.shortopt in + + (* The description must not end with \n *) + if String.is_suffix manual_entry.description "\n" then + failwithf "generator/p2v_config.ml: description of %s must not end with \\n" + key; + + (* Is there an alias for this field? *) + let aliases = + try List.assoc key cmdline_aliases + with Not_found -> [] in + List.iter ( + fun k -> pr "=item B<%s%s>\n\n" k shortopt + ) (key :: aliases); + + pr "%s\n\n" manual_entry.description + ) + ) fields diff --git a/generator/p2v_config.mli b/generator/p2v_config.mli index 55d0363a3..43a02e5f1 100644 --- a/generator/p2v_config.mli +++ b/generator/p2v_config.mli @@ -18,3 +18,5 @@ val generate_p2v_config_h : unit -> unit val generate_p2v_config_c : unit -> unit +val generate_p2v_kernel_config_c : unit -> unit +val generate_p2v_kernel_config_pod : unit -> unit diff --git a/p2v/Makefile.am b/p2v/Makefile.am index f66c2a09b..cfdec535d 100644 --- a/p2v/Makefile.am +++ b/p2v/Makefile.am @@ -20,7 +20,9 @@ include $(top_srcdir)/subdir-rules.mk generator_built = \ about-authors.c \ config.c \ - p2v-config.h + kernel-config.c \ + p2v-config.h \ + virt-p2v-kernel-config.pod BUILT_SOURCES = \ $(generator_built) @@ -89,6 +91,7 @@ virt_p2v_SOURCES = \ inhibit.c \ kernel.c \ kernel-cmdline.c \ + kernel-config.c \ main.c \ nbd.c \ p2v.h \ @@ -165,10 +168,11 @@ noinst_DATA = \ virt-p2v.1 $(top_builddir)/website/virt-p2v.1.html: stamp-virt-p2v.pod -stamp-virt-p2v.pod: virt-p2v.pod +stamp-virt-p2v.pod: virt-p2v.pod virt-p2v-kernel-config.pod $(PODWRAPPER) \ --man virt-p2v.1 \ --html $(top_builddir)/website/virt-p2v.1.html \ + --insert $(srcdir)/virt-p2v-kernel-config.pod:__KERNEL_CONFIG__ \ --license GPLv2+ \ --warning safe \ $< diff --git a/p2v/kernel.c b/p2v/kernel.c index 4f999755e..33fff0356 100644 --- a/p2v/kernel.c +++ b/p2v/kernel.c @@ -42,160 +42,6 @@ static void notify_ui_callback (int type, const char *data); static void run_command (const char *stage, const char *command); -void -update_config_from_kernel_cmdline (struct config *config, char **cmdline) -{ - const char *p; - - p = get_cmdline_key (cmdline, "p2v.server"); - if (p) { - free (config->remote.server); - config->remote.server = strdup (p); - } - - p = get_cmdline_key (cmdline, "p2v.port"); - if (p) { - if (sscanf (p, "%d", &config->remote.port) != 1) - error (EXIT_FAILURE, 0, - "cannot parse p2v.port from kernel command line"); - } - - p = get_cmdline_key (cmdline, "p2v.username"); - if (p) { - free (config->auth.username); - config->auth.username = strdup (p); - } - - p = get_cmdline_key (cmdline, "p2v.password"); - if (p) { - free (config->auth.password); - config->auth.password = strdup (p); - } - - p = get_cmdline_key (cmdline, "p2v.identity"); - if (p) { - free (config->auth.identity.url); - config->auth.identity.url = strdup (p); - config->auth.identity.file_needs_update = 1; - } - - p = get_cmdline_key (cmdline, "p2v.sudo"); - if (p) - config->auth.sudo = 1; - - p = get_cmdline_key (cmdline, "p2v.name"); - if (p) { - free (config->guestname); - config->guestname = strdup (p); - } - - p = get_cmdline_key (cmdline, "p2v.vcpus"); - if (p) { - if (sscanf (p, "%d", &config->vcpus) != 1) - error (EXIT_FAILURE, 0, - "cannot parse p2v.vcpus from kernel command line"); - } - - p = get_cmdline_key (cmdline, "p2v.memory"); - if (p) { - char mem_code; - - if (sscanf (p, "%" SCNu64 "%c", &config->memory, &mem_code) != 2) - error (EXIT_FAILURE, 0, - "cannot parse p2v.memory from kernel command line"); - config->memory *= 1024; - if (mem_code == 'M' || mem_code == 'm' - || mem_code == 'G' || mem_code == 'g') - config->memory *= 1024; - if (mem_code == 'G' || mem_code == 'g') - config->memory *= 1024; - if (mem_code != 'M' && mem_code != 'm' - && mem_code != 'G' && mem_code != 'g') - error (EXIT_FAILURE, 0, - "p2v.memory on kernel command line must be followed by 'G' or 'M'"); - } - - p = get_cmdline_key (cmdline, "p2v.disks"); - if (p) { - CLEANUP_FREE char *t; - - t = strdup (p); - guestfs_int_free_string_list (config->disks); - config->disks = guestfs_int_split_string (',', t); - } - - p = get_cmdline_key (cmdline, "p2v.removable"); - if (p) { - CLEANUP_FREE char *t; - - t = strdup (p); - guestfs_int_free_string_list (config->removable); - config->removable = guestfs_int_split_string (',', t); - } - - p = get_cmdline_key (cmdline, "p2v.interfaces"); - if (p) { - CLEANUP_FREE char *t; - - t = strdup (p); - guestfs_int_free_string_list (config->interfaces); - config->interfaces = guestfs_int_split_string (',', t); - } - - p = get_cmdline_key (cmdline, "p2v.network"); - if (p) { - CLEANUP_FREE char *t; - - t = strdup (p); - guestfs_int_free_string_list (config->network_map); - config->network_map = guestfs_int_split_string (',', t); - } - - p = get_cmdline_key (cmdline, "p2v.o"); - if (p) { - free (config->output.type); - config->output.type = strdup (p); - } - - p = get_cmdline_key (cmdline, "p2v.oa"); - if (p) { - if (STREQ (p, "sparse")) - config->output.allocation = OUTPUT_ALLOCATION_SPARSE; - else if (STREQ (p, "preallocated")) - config->output.allocation = OUTPUT_ALLOCATION_PREALLOCATED; - else - fprintf (stderr, "%s: warning: don't know what p2v.oa=%s means\n", - getprogname (), p); - } - - p = get_cmdline_key (cmdline, "p2v.oc"); - if (p) { - free (config->output.connection); - config->output.connection = strdup (p); - } - - p = get_cmdline_key (cmdline, "p2v.of"); - if (p) { - free (config->output.format); - config->output.format = strdup (p); - } - - p = get_cmdline_key (cmdline, "p2v.os"); - if (p) { - free (config->output.storage); - config->output.storage = strdup (p); - } - - /* Undocumented command line parameter used for testing command line - * parsing. - */ - p = get_cmdline_key (cmdline, "p2v.dump_config_and_exit"); - if (p) { - print_config (config, stdout); - exit (EXIT_SUCCESS); - } -} - /* Perform conversion using the kernel method. */ void kernel_conversion (struct config *config, char **cmdline, int cmdline_source) diff --git a/p2v/p2v.h b/p2v/p2v.h index 021ea2946..ee661514c 100644 --- a/p2v/p2v.h +++ b/p2v/p2v.h @@ -74,8 +74,10 @@ extern const char *get_cmdline_key (char **cmdline, const char *key); #define CMDLINE_SOURCE_COMMAND_LINE 1 /* --cmdline */ #define CMDLINE_SOURCE_PROC_CMDLINE 2 /* /proc/cmdline */ -/* kernel.c */ +/* kernel-config.c */ extern void update_config_from_kernel_cmdline (struct config *config, char **cmdline); + +/* kernel.c */ extern void kernel_conversion (struct config *, char **cmdline, int cmdline_source); /* gui.c */ diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod index fc2e7d310..48548f8c6 100644 --- a/p2v/virt-p2v.pod +++ b/p2v/virt-p2v.pod @@ -302,136 +302,7 @@ You have to set some or all of the following command line arguments: =over 4 -=item B<p2v.server=SERVER> - -The name or IP address of the conversion server. - -This is always required if you are using the kernel configuration -method. If virt-p2v does not find this on the kernel command line -then it switches to the GUI (interactive) configuration method. - -=item B<p2v.port=NN> - -The SSH port number on the conversion server (default: C<22>). - -=item B<p2v.username=USERNAME> - -The SSH username that we log in as on the conversion server -(default: C<root>). - -=item B<p2v.password=PASSWORD> - -The SSH password that we use to log in to the conversion server. - -The default is to try with no password. If this fails then virt-p2v -will ask the user to type the password (probably several times during -conversion). - -This setting is ignored if C<p2v.identity> is present. - -=item B<p2v.identity=URL> - -Provide a URL pointing to an SSH identity (private key) file. The URL -is interpreted by L<curl(1)> so any URL that curl supports can be used -here, including C<https://> and C<file://>. For more information on -using SSH identities, see L</SSH IDENTITIES> below. - -If C<p2v.identity> is present, it overrides C<p2v.password>. There is -no fallback. - -=item B<p2v.sudo> - -Use C<p2v.sudo> to tell virt-p2v to use L<sudo(8)> to gain root -privileges on the conversion server after logging in as a non-root -user (default: do not use sudo). - -=item B<p2v.name=GUESTNAME> - -The name of the guest that is created. The default is to try to -derive a name from the physical machine’s hostname (if possible) else -use a randomly generated name. - -=item B<p2v.vcpus=NN> - -The number of virtual CPUs to give to the guest. The default is to -use the same as the number of physical CPUs. - -=item B<p2v.memory=NN(M|G)> - -The size of the guest memory. You must specify the unit as either -megabytes or gigabytes by using (eg) C<p2v.memory=1024M> or -C<p2v.memory=1G>. - -The default is to use the same amount of RAM as on the physical -machine. - -=item B<p2v.disks=sdX,sdY,..> - -A list of physical hard disks to convert, for example: - - p2v.disks=sda,sdc - -The default is to convert all local hard disks that are found. - -=item B<p2v.removable=srX,srY,..> - -A list of removable media to convert. The default is to create -virtual removable devices for every physical removable device found. -Note that the content of removable media is never copied over. - -=item B<p2v.interfaces=em1,..> - -A list of network interfaces to convert. The default is to create -virtual network interfaces for every physical network interface found. - -=item B<p2v.network=interface:target,...> - -Controls how network interfaces are connected to virtual networks on -the target hypervisor. The default is to connect all network -interfaces to the target C<default> network. - -You give a comma-separated list of C<interface:target> pairs, plus -optionally a default target. For example: - - p2v.network=em1:ovirtmgmt - -maps interface C<em1> to target network C<ovirtmgmt>. - - p2v.network=em1:ovirtmgmt,em2:management,other - -maps interface C<em1> to C<ovirtmgmt>, and C<em2> to C<management>, -and any other interface that is found to C<other>. - -=item B<p2v.o=[libvirt|local|...]> - -Set the output mode. This is the same as the virt-v2v I<-o> option. -See L<virt-v2v(1)/OPTIONS>. - -If not specified, the default is C<local>, and the converted guest is -written to F</var/tmp>. - -=item B<p2v.oa=sparse|preallocated> - -Set the output allocation mode. This is the same as the virt-v2v -I<-oa> option. See L<virt-v2v(1)/OPTIONS>. - -=item B<p2v.oc=...> - -Set the output connection libvirt URI. This is the same as the -virt-v2v I<-oc> option. See L<virt-v2v(1)/OPTIONS> and -L<http://libvirt.org/uri.html> - -=item B<p2v.of=raw|qcow2|...> - -Set the output format. This is the same as the virt-v2v I<-of> -option. See L<virt-v2v(1)/OPTIONS>. - -=item B<p2v.os=...> - -Set the output storage. This is the same as the virt-v2v I<-os> -option. See L<virt-v2v(1)/OPTIONS>. - -If not specified, the default is F</var/tmp> (on the conversion server). +__KERNEL_CONFIG__ =item B<p2v.pre=COMMAND> diff --git a/po-docs/language.mk b/po-docs/language.mk index 3eeb058e0..0163edab3 100644 --- a/po-docs/language.mk +++ b/po-docs/language.mk @@ -148,6 +148,14 @@ virt-sysprep.1: virt-sysprep.pod sysprep-extra-options.pod sysprep-operations.po --insert $(srcdir)/sysprep-operations.pod:__OPERATIONS__ \ $< +virt-p2v.1: virt-p2v.pod virt-p2v-kernel-config.pod + $(PODWRAPPER) \ + --no-strict-checks \ + --man $@ \ + --license GPLv2+ \ + --insert $(srcdir)/virt-p2v-kernel-config.pod:__KERNEL_CONFIG__ \ + $< + %.1: %.pod $(PODWRAPPER) \ --no-strict-checks \ diff --git a/po-docs/podfiles b/po-docs/podfiles index 31a3aca3a..b6bd39b68 100644 --- a/po-docs/podfiles +++ b/po-docs/podfiles @@ -53,6 +53,7 @@ ../lua/examples/guestfs-lua.pod ../make-fs/virt-make-fs.pod ../ocaml/examples/guestfs-ocaml.pod +../p2v/virt-p2v-kernel-config.pod ../p2v/virt-p2v-make-disk.pod ../p2v/virt-p2v-make-kickstart.pod ../p2v/virt-p2v-make-kiwi.pod -- 2.17.1