2015-10-12 14:35:14 +00:00
|
|
|
=head1 NAME
|
|
|
|
|
|
|
|
virt-admin - daemon administration interface
|
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
|
|
|
|
B<virt-admin> [I<OPTION>]... [I<COMMAND_STRING>]
|
|
|
|
|
|
|
|
B<virt-admin> [I<OPTION>]... I<COMMAND> [I<ARG>]...
|
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
|
|
|
|
The B<virt-admin> program is the main administration interface for modifying
|
|
|
|
the libvirt daemon configuration at runtime, changing daemon behaviour as well
|
|
|
|
as for monitoring and managing all clients connected to the daemon.
|
|
|
|
|
|
|
|
The basic structure of most virt-admin usage is:
|
|
|
|
|
|
|
|
virt-admin [OPTION]... <command> [ARG]...
|
|
|
|
|
2019-03-22 19:02:39 +00:00
|
|
|
Where I<command> is one of the commands listed below. Any I<command>
|
|
|
|
starting with B<#> is treated as a comment and silently ignored, all
|
|
|
|
other unrecognized I<command>s are diagnosed.
|
2015-10-12 14:35:14 +00:00
|
|
|
|
|
|
|
The B<virt-admin> program can be used either to run one I<COMMAND> by giving the
|
|
|
|
command and its arguments on the shell command line, or a I<COMMAND_STRING>
|
|
|
|
which is a single shell argument consisting of multiple I<COMMAND> actions
|
2019-02-21 18:36:32 +00:00
|
|
|
and their arguments joined with whitespace and separated by semicolons or
|
2019-02-26 18:49:25 +00:00
|
|
|
newlines between commands, where unquoted backslash-newline pairs are
|
|
|
|
elided. Within I<COMMAND_STRING>, virt-admin understands the
|
2015-10-12 14:35:14 +00:00
|
|
|
same single, double, and backslash escapes as the shell, although you must
|
2019-03-22 19:02:39 +00:00
|
|
|
add another layer of shell escaping in creating the single shell argument,
|
|
|
|
and any word starting with unquoted I<#> begins a comment that ends at newline.
|
2015-10-12 14:35:14 +00:00
|
|
|
If no command is given in the command line, B<virt-admin> will then start a minimal
|
|
|
|
interpreter waiting for your commands, and the B<quit> command will then exit
|
|
|
|
the program.
|
|
|
|
|
|
|
|
The B<virt-admin> program understands the following I<OPTIONS>.
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item B<-c>, B<--connect> I<URI>
|
|
|
|
|
|
|
|
Connect to the specified I<URI>, as if by the B<connect> command,
|
|
|
|
instead of the default connection.
|
|
|
|
|
|
|
|
=item B<-d>, B<--debug> I<LEVEL>
|
|
|
|
|
|
|
|
Enable debug messages at integer I<LEVEL> and above. I<LEVEL> can
|
|
|
|
range from 0 to 4 (default). See the documentation of B<VIRT_ADMIN_DEBUG>
|
|
|
|
environment variable below for the description of each I<LEVEL>.
|
|
|
|
|
|
|
|
=item B<-h>, B<--help>
|
|
|
|
|
|
|
|
Ignore all other arguments, and behave as if the B<help> command were
|
|
|
|
given instead.
|
|
|
|
|
|
|
|
=item B<-l>, B<--log> I<FILE>
|
|
|
|
|
|
|
|
Output logging details to I<FILE>.
|
|
|
|
|
|
|
|
=item B<-q>, B<--quiet>
|
|
|
|
|
|
|
|
Avoid extra informational messages.
|
|
|
|
|
|
|
|
=item B<-v>, B<--version[=short]>
|
|
|
|
|
|
|
|
Ignore all other arguments, and prints the version of the libvirt library
|
|
|
|
virt-admin is coming from
|
|
|
|
|
|
|
|
=item B<-V>, B<--version=long>
|
|
|
|
|
|
|
|
Ignore all other arguments, and prints the version of the libvirt library
|
|
|
|
virt-admin is coming from.
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
=head1 NOTES
|
|
|
|
|
|
|
|
Running B<virt-admin> requires root privileges due to the
|
|
|
|
communications channels used to talk to the daemon. Consider changing the
|
|
|
|
I<unix_sock_group> ownership setting to grant access to specific set of users
|
|
|
|
or modifying I<unix_sock_rw_perms> permissions. Daemon configuration file
|
|
|
|
provides more information about setting permissions.
|
|
|
|
|
|
|
|
=head1 GENERIC COMMANDS
|
|
|
|
|
|
|
|
The following commands are generic.
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item B<help> [I<command-or-group>]
|
|
|
|
|
|
|
|
This lists each of the virt-admin commands. When used without options, all
|
|
|
|
commands are listed, one per line, grouped into related categories,
|
|
|
|
displaying the keyword for each group.
|
|
|
|
|
|
|
|
To display detailed information for a specific command, use its name as the
|
|
|
|
option.
|
|
|
|
|
|
|
|
=item B<quit>, B<exit>
|
|
|
|
|
|
|
|
quit this interactive terminal
|
|
|
|
|
|
|
|
=item B<version>
|
|
|
|
|
|
|
|
Will print out the version info about which libvirt library was this client
|
|
|
|
built from. As opposed to I<virsh> client, the output already includes
|
|
|
|
the version of the daemon.
|
|
|
|
|
|
|
|
B<Example>
|
|
|
|
|
|
|
|
$ virt-admin version
|
|
|
|
Compiled against library: libvirt 1.2.21
|
|
|
|
Using library: libvirt 1.2.21
|
|
|
|
Running against daemon: 1.2.20
|
|
|
|
|
|
|
|
=item B<cd> [I<directory>]
|
|
|
|
|
|
|
|
Will change current directory to I<directory>. The default directory
|
|
|
|
for the B<cd> command is the home directory or, if there is no I<HOME>
|
|
|
|
variable in the environment, the root directory.
|
|
|
|
|
|
|
|
This command is only available in interactive mode.
|
|
|
|
|
|
|
|
=item B<pwd>
|
|
|
|
|
|
|
|
Will print the current directory.
|
|
|
|
|
|
|
|
=item B<connect> [I<URI>]
|
|
|
|
|
|
|
|
(Re)-Connect to a daemon's administrating server. The I<URI> parameter
|
|
|
|
specifies how to connect to the administrating server.
|
2016-07-27 11:23:03 +00:00
|
|
|
If I<LIBVIRT_ADMIN_DEFAULT_URI> or I<uri_default> (see below) were set,
|
2015-10-12 14:35:14 +00:00
|
|
|
I<connect> is automatically issued every time a command that requires an
|
|
|
|
active connection is executed. Note that this only applies if there is no
|
|
|
|
connection at all or there is an inactive one.
|
|
|
|
|
|
|
|
To find the currently used URI, check the I<uri> command documented below.
|
|
|
|
|
|
|
|
=item B<uri>
|
|
|
|
|
|
|
|
Prints the administrating server canonical URI, can be useful in shell mode. If
|
2016-07-27 11:23:03 +00:00
|
|
|
no I<uri> was specified, neither I<LIBVIRT_ADMIN_DEFAULT_URI> environment
|
|
|
|
variable nor I<uri_default> option (libvirt-admin.conf) were set,
|
|
|
|
libvirtd:///system is used.
|
2015-10-12 14:35:14 +00:00
|
|
|
|
|
|
|
=back
|
|
|
|
|
2016-09-07 11:42:06 +00:00
|
|
|
=head1 DAEMON COMMANDS
|
|
|
|
|
|
|
|
The following commands allow to monitor the daemon's state as well as directly
|
|
|
|
change its internal configuration.
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
2016-09-07 15:27:52 +00:00
|
|
|
=item B<server-list>
|
2016-09-07 11:42:06 +00:00
|
|
|
|
|
|
|
Lists all manageable servers contained within the daemon the client is
|
|
|
|
currently connected to.
|
|
|
|
|
2016-03-09 14:12:55 +00:00
|
|
|
=item B<daemon-log-filters> [I<--filters> B<string>]
|
|
|
|
|
|
|
|
When run without arguments, this returns the currently defined set of logging
|
|
|
|
filters. Providing an argument will cause the command to define a new set of
|
|
|
|
logging filters.
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item I<--filters>
|
|
|
|
|
|
|
|
Define a new set of logging filters where multiple filters are delimited by
|
|
|
|
space. Each filter must conform to the form described in detail by
|
|
|
|
I</etc/libvirt/libvirtd.conf> (section 'Logging filters').
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
B<Example>
|
|
|
|
|
|
|
|
To define a filter which suppresses all e.g. 'virObjectUnref' DEBUG
|
|
|
|
messages, use the following:
|
|
|
|
|
|
|
|
$ virt-admin daemon-log-filters "4:util.object"
|
|
|
|
|
|
|
|
(Note the '.' symbol which can be used to more fine-grained filters tailored
|
|
|
|
to specific modules, in contrast, to affect the whole directory containing
|
|
|
|
several modules this would become "4:util"):
|
|
|
|
|
|
|
|
=item B<daemon-log-outputs> [I<--outputs> B<string>]
|
|
|
|
|
|
|
|
When run without arguments, this returns the currently defined set of logging
|
|
|
|
outputs. Providing an argument will cause the command to define a new set of
|
|
|
|
logging outputs.
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item I<--outputs>
|
|
|
|
|
|
|
|
Define a new set of logging outputs where multiple outputs are delimited by
|
|
|
|
space. Each output must conform to the form described in detail by
|
|
|
|
I</etc/libvirt/libvirtd.conf> (section 'Logging outputs').
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
B<Example>
|
|
|
|
|
|
|
|
To replace the current setting for logging outputs with one that writes to
|
|
|
|
a file while logging errors only, the following could be used:
|
|
|
|
|
|
|
|
$ virt-admin daemon-log-outputs "4:file:<absolute_path_to_the_file>"
|
|
|
|
|
|
|
|
To define multiple outputs at once they need to be delimited by spaces:
|
|
|
|
|
|
|
|
$ virt-admin daemon-log-outputs "4:stderr 2:syslog:<msg_ident>"
|
|
|
|
|
2016-09-07 11:42:06 +00:00
|
|
|
=back
|
|
|
|
|
2016-02-17 08:55:19 +00:00
|
|
|
=head1 SERVER COMMANDS
|
|
|
|
|
2016-09-08 08:45:28 +00:00
|
|
|
The following commands manipulate daemon's server internal configuration.
|
2016-02-17 08:55:19 +00:00
|
|
|
The I<server> is specified by its name.
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
2016-09-07 15:27:52 +00:00
|
|
|
=item B<server-threadpool-info> I<server>
|
2016-02-17 08:55:19 +00:00
|
|
|
|
|
|
|
Retrieve server's threadpool attributes. These attributes include:
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item I<minWorkers>
|
|
|
|
as the bottom limit to the number of active workers,
|
|
|
|
|
|
|
|
=item I<maxWorkers>
|
|
|
|
as the top limit to the number of active workers,
|
|
|
|
|
|
|
|
=item I<nWorkers>
|
|
|
|
as the current number of workers in the threadpool,
|
|
|
|
|
|
|
|
=item I<freeWorkers>
|
|
|
|
as the current number of workers available for a task,
|
|
|
|
|
|
|
|
=item I<prioWorkers>
|
|
|
|
as the current number of priority workers in the threadpool, and
|
|
|
|
|
|
|
|
=item I<jobQueueDepth>
|
|
|
|
as the current depth of threadpool's job queue.
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
B<Background>
|
|
|
|
|
|
|
|
Each daemon server utilizes a threadpool to accomplish tasks requested by
|
|
|
|
clients connected to it. Every time a client request arrives to the server,
|
|
|
|
it checks whether there is a worker available to accomplish the given task or
|
|
|
|
it should create a new worker for the job (rather than being destroyed, the
|
|
|
|
worker becomes free once the task is finished). Creating new workers, however,
|
|
|
|
is only possible when the current number of workers is still below the
|
|
|
|
configured upper limit.
|
|
|
|
|
|
|
|
In addition to these 'standard' workers, a threadpool also contains a special
|
|
|
|
set of workers called I<priority> workers. Their purpose is to perform tasks
|
|
|
|
that, unlike tasks carried out by normal workers, are within libvirt's full
|
|
|
|
control and libvirt guarantees that such a task cannot hang, thus will always
|
|
|
|
finish. An example of such a task this would be destroying a domain:
|
|
|
|
$ virsh destroy <domain>.
|
|
|
|
|
2016-09-07 15:27:52 +00:00
|
|
|
=item B<server-threadpool-set> I<server> [I<--min-workers> B<count>]
|
2016-02-17 08:55:19 +00:00
|
|
|
[I<--max-workers> B<count>] [I<--priority-workers> B<count>]
|
|
|
|
|
|
|
|
Change threadpool attributes on a server. Only a fraction of all attributes as
|
2016-09-07 15:27:52 +00:00
|
|
|
described in I<server-threadpool-info> is supported for the setter.
|
2016-02-17 08:55:19 +00:00
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item I<--min-workers>
|
|
|
|
|
|
|
|
The bottom limit to number of active workers in a threadpool.
|
|
|
|
|
|
|
|
=item I<--max-workers>
|
|
|
|
|
|
|
|
The upper limit to number of active workers in a threadpool. If used in
|
|
|
|
combination with option I<--min-workers>, the value for the upper limit has to
|
|
|
|
be greater than the value for the bottom limit, otherwise the command results
|
|
|
|
in an error.
|
|
|
|
|
|
|
|
=item I<--priority-workers>
|
|
|
|
|
|
|
|
The current number of active priority workers in a threadpool.
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
2016-09-07 15:27:52 +00:00
|
|
|
=item B<server-clients-info> I<server>
|
2016-04-09 16:49:44 +00:00
|
|
|
|
|
|
|
Get information about the current setting of limits regarding connections of new
|
|
|
|
clients. This information comprises of the limits to the maximum number of
|
|
|
|
clients connected to I<server>, maximum number of clients waiting for
|
|
|
|
authentication, in order to be connected to the server, as well as the current
|
|
|
|
runtime values, more specifically, the current number of clients connected to
|
|
|
|
I<server> and the current number of clients waiting for authentication.
|
|
|
|
|
|
|
|
B<Example>
|
2016-09-07 15:27:52 +00:00
|
|
|
# virt-admin server-clients-info libvirtd
|
2016-04-09 16:49:44 +00:00
|
|
|
nclients_max : 120
|
|
|
|
nclients : 3
|
|
|
|
nclients_unauth_max : 20
|
|
|
|
nclients_unauth : 0
|
|
|
|
|
2016-09-07 15:27:52 +00:00
|
|
|
=item B<server-clients-set> I<server> [I<--max-clients> B<count>]
|
2016-04-09 16:49:44 +00:00
|
|
|
[I<--max-unauth-clients> B<count>]
|
|
|
|
|
|
|
|
Set new client-related limits on I<server>.
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item I<--max-clients>
|
|
|
|
|
|
|
|
Change the upper limit of the maximum overall number of clients connected to
|
|
|
|
I<server> to value B<count>. The value for this limit has to be always greater
|
|
|
|
than the value of I<--max-unauth-clients>.
|
|
|
|
|
|
|
|
=item I<--max-unauth-clients>
|
|
|
|
|
|
|
|
Change the upper limit of the maximum number of clients waiting for
|
|
|
|
authentication, in order to be connected to I<server>, to value B<count>.
|
|
|
|
The value for this limit has to be always lower than the value of
|
|
|
|
I<--max-clients>.
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
2016-02-17 08:55:19 +00:00
|
|
|
=back
|
|
|
|
|
2016-04-22 11:12:01 +00:00
|
|
|
=head1 CLIENT COMMANDS
|
|
|
|
|
2016-09-08 08:45:28 +00:00
|
|
|
The following commands provide management and monitoring of clients connected to
|
2016-04-22 11:12:01 +00:00
|
|
|
one of daemon's available servers. Clients are specified by their numeric ID
|
|
|
|
which is obtained by listing all clients connected to a specified server
|
2016-09-07 15:27:52 +00:00
|
|
|
(see command B<client-list>).
|
2016-04-22 11:12:01 +00:00
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
2016-09-07 15:27:52 +00:00
|
|
|
=item B<client-list> I<server>
|
|
|
|
|
|
|
|
Print a table showing the list of clients connected to <server>, also providing
|
|
|
|
information about transport type used on client's connection (supported
|
|
|
|
transports include B<unix>, B<tcp>, and B<tls>), as well as providing
|
|
|
|
information about client's connection time (system local time is used).
|
|
|
|
|
2016-04-22 11:12:01 +00:00
|
|
|
=item B<client-info> I<server> I<client>
|
|
|
|
|
|
|
|
Retrieve identity information about I<client> from I<server>. The attributes
|
|
|
|
returned may vary depending on the connection transport used.
|
|
|
|
Transport-dependent attributes include local client process's pid, uid,
|
|
|
|
user name, and group name, as well as socket address of the remote peer, see
|
|
|
|
B<Examples> below.
|
|
|
|
|
|
|
|
On the other hand, transport-independent attributes include client's SELinux
|
|
|
|
context (if enabled on the host) and SASL username (if SASL authentication is
|
|
|
|
enabled within daemon).
|
|
|
|
|
|
|
|
B<Examples>
|
|
|
|
|
|
|
|
# virt-admin client-info libvirtd 1
|
|
|
|
id : 1
|
|
|
|
connection_time: 2016-05-03 13:27:04+0200
|
|
|
|
transport : unix
|
|
|
|
readonly : yes
|
|
|
|
unix_user_id : 0
|
|
|
|
unix_user_name : root
|
|
|
|
unix_group_id : 0
|
|
|
|
unix_group_name: root
|
|
|
|
unix_process_id: 10201
|
|
|
|
|
|
|
|
# virt-admin client-info libvirtd 2
|
|
|
|
id : 2
|
|
|
|
connection_time: 2016-05-03 13:30:33+0200
|
|
|
|
transport : tcp
|
|
|
|
readonly : no
|
|
|
|
sock_addr : 127.0.0.1:57060
|
|
|
|
|
2016-04-28 08:38:32 +00:00
|
|
|
=item B<client-disconnect> I<server> I<client>
|
|
|
|
|
|
|
|
Close a connection originating from I<client>. The I<server> argument
|
|
|
|
specifies the name of the server I<client> is currently connected to.
|
|
|
|
|
2016-04-22 11:12:01 +00:00
|
|
|
=back
|
|
|
|
|
2015-10-12 14:35:14 +00:00
|
|
|
=head1 ENVIRONMENT
|
|
|
|
|
|
|
|
The following environment variables can be set to alter the behaviour
|
|
|
|
of C<virt-admin>
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item VIRT_ADMIN_DEBUG=<0 to 4>
|
|
|
|
|
|
|
|
Turn on verbose debugging of virt-admin commands. Valid levels are
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item * VIRT_ADMIN_DEBUG=0
|
|
|
|
|
|
|
|
DEBUG - Messages at ALL levels get logged
|
|
|
|
|
|
|
|
=item * VIRT_ADMIN_DEBUG=1
|
|
|
|
|
|
|
|
INFO - Logs messages at levels INFO, NOTICE, WARNING and ERROR
|
|
|
|
|
|
|
|
=item * VIRT_ADMIN_DEBUG=2
|
|
|
|
|
|
|
|
NOTICE - Logs messages at levels NOTICE, WARNING and ERROR
|
|
|
|
|
|
|
|
=item * VIRT_ADMIN_DEBUG=3
|
|
|
|
|
|
|
|
WARNING - Logs messages at levels WARNING and ERROR
|
|
|
|
|
|
|
|
=item * VIRT_ADMIN_DEBUG=4
|
|
|
|
|
|
|
|
ERROR - Messages at only ERROR level gets logged.
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
=item VIRT_ADMIN_LOG_FILE=C<LOGFILE>
|
|
|
|
|
|
|
|
The file to log virt-admin debug messages.
|
|
|
|
|
|
|
|
=item LIBVIRT_ADMIN_DEFAULT_URI
|
|
|
|
|
|
|
|
The daemon whose admin server to connect to by default. Set this to a URI, in
|
|
|
|
the same format as accepted by the B<connect> option. This overrides the
|
|
|
|
default URI set in any client config file.
|
|
|
|
|
|
|
|
=item VIRT_ADMIN_HISTSIZE
|
|
|
|
|
|
|
|
The number of commands to remember in the command history. The
|
|
|
|
default value is 500.
|
|
|
|
|
|
|
|
=item LIBVIRT_DEBUG=LEVEL
|
|
|
|
|
|
|
|
Turn on verbose debugging of all libvirt API calls. Valid levels are
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item * LIBVIRT_DEBUG=1
|
|
|
|
|
|
|
|
Messages at level DEBUG or above
|
|
|
|
|
|
|
|
=item * LIBVIRT_DEBUG=2
|
|
|
|
|
|
|
|
Messages at level INFO or above
|
|
|
|
|
|
|
|
=item * LIBVIRT_DEBUG=3
|
|
|
|
|
|
|
|
Messages at level WARNING or above
|
|
|
|
|
|
|
|
=item * LIBVIRT_DEBUG=4
|
|
|
|
|
|
|
|
Messages at level ERROR or above
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
2016-04-13 17:46:06 +00:00
|
|
|
For further information about debugging options consult
|
2017-10-13 15:30:41 +00:00
|
|
|
L<https://libvirt.org/logging.html>
|
2015-10-12 14:35:14 +00:00
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
=head1 BUGS
|
|
|
|
|
|
|
|
Report any bugs discovered to the libvirt community via the mailing
|
2017-10-13 15:30:41 +00:00
|
|
|
list L<https://libvirt.org/contact.html> or bug tracker
|
|
|
|
L<https://libvirt.org/bugs.html>.
|
2015-10-12 14:35:14 +00:00
|
|
|
Alternatively report bugs to your software distributor / vendor.
|
|
|
|
|
|
|
|
=head1 AUTHORS
|
|
|
|
|
|
|
|
Please refer to the AUTHORS file distributed with libvirt.
|
|
|
|
|
|
|
|
Based on the virsh man page.
|
|
|
|
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
|
|
|
|
Copyright (C) 2015 Red Hat, Inc., and the authors listed in the
|
|
|
|
libvirt AUTHORS file.
|
|
|
|
|
|
|
|
=head1 LICENSE
|
|
|
|
|
|
|
|
virt-admin is distributed under the terms of the GNU LGPL v2+.
|
|
|
|
This is free software; see the source for copying conditions. There
|
|
|
|
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
PURPOSE
|
|
|
|
|
|
|
|
=head1 SEE ALSO
|
|
|
|
|
|
|
|
L<virsh(1)>, L<virt-xml-validate(1)>, L<virt-host-validate(1)>,
|
2017-10-13 15:30:41 +00:00
|
|
|
L<https://libvirt.org/>
|
2015-10-12 14:35:14 +00:00
|
|
|
|
|
|
|
=cut
|