Hello community, here is the log from the commit of package perl-Sys-Virt for openSUSE:Factory checked in at 2013-08-04 17:05:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Sys-Virt (Old) and /work/SRC/openSUSE:Factory/.perl-Sys-Virt.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Sys-Virt" Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Sys-Virt/perl-Sys-Virt.changes 2013-05-28 12:08:14.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.perl-Sys-Virt.new/perl-Sys-Virt.changes 2013-08-04 17:05:23.000000000 +0200 @@ -1,0 +2,15 @@ +Tue Jul 30 14:56:44 MDT 2013 - [email protected] + +- Update to 1.1.1 + - Add all new APIs and constants in libvirt 1.1.1 + +------------------------------------------------------------------- +Tue Jul 30 08:51:05 MDT 2013 - [email protected] + +- Update to 1.1.0 + - Add support for v3 of migration APIs + - Add all new constants in libvirt 1.1.0 + - Fix handling of sparse typed parameters + - Fix misc typos in docs + +------------------------------------------------------------------- Old: ---- Sys-Virt-1.0.5.tar.gz New: ---- Sys-Virt-1.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Sys-Virt.spec ++++++ --- /var/tmp/diff_new_pack.t4veVJ/_old 2013-08-04 17:05:24.000000000 +0200 +++ /var/tmp/diff_new_pack.t4veVJ/_new 2013-08-04 17:05:24.000000000 +0200 @@ -17,7 +17,7 @@ Name: perl-Sys-Virt -Version: 1.0.5 +Version: 1.1.1 Release: 0 %define cpan_name Sys-Virt Summary: Represent and manage a libvirt hypervisor connection ++++++ Sys-Virt-1.0.5.tar.gz -> Sys-Virt-1.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/AUTHORS new/Sys-Virt-1.1.1/AUTHORS --- old/Sys-Virt-1.0.5/AUTHORS 2013-05-14 15:24:54.000000000 +0200 +++ new/Sys-Virt-1.1.1/AUTHORS 2013-07-30 16:34:30.000000000 +0200 @@ -11,5 +11,6 @@ Anthony Hinsinger <anthony-dot-hinsinger-at-univ-pau-dot-fr> Stepan Kasal <skasal-at-redhat-dot-com> Ludwig Nussel <ludwig-dot-nussel-at-suse-dot-de> + Zhe Peng <zpeng-at-redhat-dot-com> -- End diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/Changes new/Sys-Virt-1.1.1/Changes --- old/Sys-Virt-1.0.5/Changes 2013-05-14 15:24:54.000000000 +0200 +++ new/Sys-Virt-1.1.1/Changes 2013-07-30 16:34:30.000000000 +0200 @@ -1,5 +1,16 @@ Revision history for perl module Sys::Virt +1.1.1 2013-07-30 + + - Add all new constants/apis in libvirt 1.1.1 + +1.1.0 2013-07-29 + + - Add support for v3 of migration APIs + - Add all new constants in libvirt 1.1.0 + - Fix handling of sparse typed parameters + - Fix misc typos in docs + 1.0.5 2013-05-14 - Add all new APIs in libvirt 1.0.4 and 1.0.5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/MANIFEST new/Sys-Virt-1.1.1/MANIFEST --- old/Sys-Virt-1.0.5/MANIFEST 2013-05-14 15:25:08.000000000 +0200 +++ new/Sys-Virt-1.1.1/MANIFEST 2013-07-30 16:34:51.000000000 +0200 @@ -40,6 +40,8 @@ MANIFEST.SKIP META.yml META.yml.PL +MYMETA.json +MYMETA.yml perl-Sys-Virt.spec perl-Sys-Virt.spec.PL README diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/META.yml new/Sys-Virt-1.1.1/META.yml --- old/Sys-Virt-1.0.5/META.yml 2013-05-14 15:25:08.000000000 +0200 +++ new/Sys-Virt-1.1.1/META.yml 2013-07-30 16:34:51.000000000 +0200 @@ -1,7 +1,7 @@ --- #YAML:1.0 name: Sys-Virt abstract: Extension for the libvirt library -version: 1.0.5 +version: 1.1.1 author: - Daniel P. Berrange <[email protected]> license: perl diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/MYMETA.json new/Sys-Virt-1.1.1/MYMETA.json --- old/Sys-Virt-1.0.5/MYMETA.json 1970-01-01 01:00:00.000000000 +0100 +++ new/Sys-Virt-1.1.1/MYMETA.json 2013-07-30 16:34:38.000000000 +0200 @@ -0,0 +1,46 @@ +{ + "abstract" : "unknown", + "author" : [ + "Daniel Berrange <[email protected]>" + ], + "dynamic_config" : 0, + "generated_by" : "ExtUtils::MakeMaker version 6.64, CPAN::Meta::Converter version 2.120921", + "license" : [ + "unknown" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "Sys-Virt", + "no_index" : { + "directory" : [ + "t", + "inc" + ] + }, + "prereqs" : { + "build" : { + "requires" : { + "ExtUtils::MakeMaker" : "0" + } + }, + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : "0" + } + }, + "runtime" : { + "requires" : { + "Test::CPAN::Changes" : "0", + "Test::More" : "0", + "Test::Pod" : "0", + "Test::Pod::Coverage" : "0", + "Time::HiRes" : "0", + "XML::XPath" : "0" + } + } + }, + "release_status" : "stable", + "version" : "v1.1.1" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/MYMETA.yml new/Sys-Virt-1.1.1/MYMETA.yml --- old/Sys-Virt-1.0.5/MYMETA.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/Sys-Virt-1.1.1/MYMETA.yml 2013-07-30 16:34:38.000000000 +0200 @@ -0,0 +1,27 @@ +--- +abstract: unknown +author: + - 'Daniel Berrange <[email protected]>' +build_requires: + ExtUtils::MakeMaker: 0 +configure_requires: + ExtUtils::MakeMaker: 0 +dynamic_config: 0 +generated_by: 'ExtUtils::MakeMaker version 6.64, CPAN::Meta::Converter version 2.120921' +license: unknown +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: 1.4 +name: Sys-Virt +no_index: + directory: + - t + - inc +requires: + Test::CPAN::Changes: 0 + Test::More: 0 + Test::Pod: 0 + Test::Pod::Coverage: 0 + Time::HiRes: 0 + XML::XPath: 0 +version: v1.1.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/Makefile.PL new/Sys-Virt-1.1.1/Makefile.PL --- old/Sys-Virt-1.0.5/Makefile.PL 2013-05-14 15:24:54.000000000 +0200 +++ new/Sys-Virt-1.1.1/Makefile.PL 2013-07-30 16:34:30.000000000 +0200 @@ -3,7 +3,7 @@ # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. -my $libvirtver = "1.0.5"; +my $libvirtver = "1.1.1"; my $stat = system "pkg-config --atleast-version=$libvirtver libvirt"; die "cannot run pkg-config to check libvirt version" if $stat == -1; die "libvirt >= $libvirtver is required\n" unless $stat == 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/README new/Sys-Virt-1.1.1/README --- old/Sys-Virt-1.0.5/README 2013-05-14 15:24:54.000000000 +0200 +++ new/Sys-Virt-1.1.1/README 2013-07-30 16:34:30.000000000 +0200 @@ -7,6 +7,6 @@ The only pre-requisite for this module is libvirt itself. For installation instructions, consult the INSTALL file. -The current minimum required version of libvirt is 1.0.5 +The current minimum required version of libvirt is 1.1.1 -- End diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/Virt.xs new/Sys-Virt-1.1.1/Virt.xs --- old/Sys-Virt-1.0.5/Virt.xs 2013-05-14 15:24:54.000000000 +0200 +++ new/Sys-Virt-1.1.1/Virt.xs 2013-07-30 16:34:30.000000000 +0200 @@ -743,6 +743,44 @@ } +static int +_domain_event_device_removed_callback(virConnectPtr con, + virDomainPtr dom, + const char *devAlias, + void *opaque) +{ + AV *data = opaque; + SV **self; + SV **cb; + SV *domref; + dSP; + + self = av_fetch(data, 0, 0); + cb = av_fetch(data, 1, 0); + + SvREFCNT_inc(*self); + + ENTER; + SAVETMPS; + + PUSHMARK(SP); + XPUSHs(*self); + domref = sv_newmortal(); + sv_setref_pv(domref, "Sys::Virt::Domain", (void*)dom); + virDomainRef(dom); + XPUSHs(domref); + XPUSHs(sv_2mortal(newSVpv(devAlias, 0))); + PUTBACK; + + call_sv(*cb, G_DISCARD); + + FREETMPS; + LEAVE; + + return 0; +} + + static void _domain_event_free(void *opaque) { @@ -1293,23 +1331,23 @@ unsigned int i; char * ptr; STRLEN len; - int ret = 0; /* We only want to set parameters which we're actually changing * so here we figure out which elements of 'params' we need to * update, and overwrite the others */ - for (i = 0 ; i < nparams ; i++) { + for (i = 0 ; i < nparams ;) { if (!hv_exists(newparams, params[i].field, strlen(params[i].field))) { if ((nparams-i) > 1) memmove(params+i, params+i+1, sizeof(*params)*(nparams-(i+1))); + nparams--; continue; } - ret++; + i++; } - for (i = 0 ; i < ret ; i++) { + for (i = 0 ; i < nparams ; i++) { SV **val; val = hv_fetch (newparams, params[i].field, strlen(params[i].field), 0); @@ -1346,7 +1384,7 @@ } } - return ret; + return nparams; } @@ -2523,6 +2561,9 @@ case VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE: callback = VIR_DOMAIN_EVENT_CALLBACK(_domain_event_balloonchange_callback); break; + case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED: + callback = VIR_DOMAIN_EVENT_CALLBACK(_domain_event_device_removed_callback); + break; default: callback = VIR_DOMAIN_EVENT_CALLBACK(_domain_event_generic_callback); break; @@ -2634,6 +2675,39 @@ virDomainPtr +_create_with_files(con, xml, fdssv, flags=0) + virConnectPtr con; + const char *xml; + SV *fdssv; + unsigned int flags; + PREINIT: + AV *fdsav; + unsigned int nfds; + int *fds; + int i; + CODE: + if (!SvROK(fdssv)) + return; + fdsav = (AV*)SvRV(fdssv); + nfds = av_len(fdsav) + 1; + Newx(fds, nfds, int); + + for (i = 0 ; i < nfds ; i++) { + SV **fd = av_fetch(fdsav, i, 0); + fds[i] = SvIV(*fd); + } + + if (!(RETVAL = virDomainCreateXMLWithFiles(con, xml, nfds, fds, flags))) { + Safefree(fds); + _croak_error(); + } + + Safefree(fds); + OUTPUT: + RETVAL + + +virDomainPtr _define_xml(con, xml) virConnectPtr con; const char *xml; @@ -3459,6 +3533,16 @@ } +void +set_memory_stats_period(dom, val, flags=0) + virDomainPtr dom; + int val; + unsigned int flags; + PPCODE: + if (virDomainSetMemoryStatsPeriod(dom, val, flags) < 0) + _croak_error(); + + int get_max_vcpus(dom) virDomainPtr dom; @@ -3640,98 +3724,130 @@ } -virDomainPtr -migrate(dom, destcon, flags=0, dname=&PL_sv_undef, uri=&PL_sv_undef, bandwidth=0) - virDomainPtr dom; - virConnectPtr destcon; - unsigned long flags; - SV *dname; - SV *uri; - unsigned long bandwidth; -PREINIT: - const char *dnamestr = NULL; - const char *uristr = NULL; - CODE: - if (SvOK(dname)) - dnamestr = SvPV_nolen(dname); - if (SvOK(uri)) - uristr = SvPV_nolen(uri); - - if ((RETVAL = virDomainMigrate(dom, destcon, flags, dnamestr, uristr, bandwidth)) == NULL) - _croak_error(); - OUTPUT: - RETVAL - void -migrate_to_uri(dom, desturi, flags=0, dname=&PL_sv_undef, bandwidth=0) - virDomainPtr dom; - const char *desturi; - unsigned long flags; - SV *dname; - unsigned long bandwidth; -PREINIT: - const char *dnamestr = NULL; +create_with_files(dom, fdssv, flags=0) + virDomainPtr dom; + SV *fdssv; + unsigned int flags; + PREINIT: + AV *fdsav; + unsigned int nfds; + int *fds; + int i; PPCODE: - if (SvOK(dname)) - dnamestr = SvPV_nolen(dname); + if (!SvROK(fdssv)) + return; + fdsav = (AV*)SvRV(fdssv); + nfds = av_len(fdsav) + 1; + Newx(fds, nfds, int); - if (virDomainMigrateToURI(dom, desturi, flags, dnamestr, bandwidth) < 0) - _croak_error(); + for (i = 0 ; i < nfds ; i++) { + SV **fd = av_fetch(fdsav, i, 0); + fds[i] = SvIV(*fd); + } + + if (virDomainCreateWithFiles(dom, nfds, fds, flags) < 0) { + Safefree(fds); + _croak_error(); + } + + Safefree(fds); virDomainPtr -migrate2(dom, destcon, dxml=&PL_sv_undef, flags=0, dname=&PL_sv_undef, uri=&PL_sv_undef, bandwidth=0) +_migrate(dom, destcon, newparams, flags=0) virDomainPtr dom; virConnectPtr destcon; - SV *dxml; + HV *newparams; unsigned long flags; - SV *dname; - SV *uri; - unsigned long bandwidth; -PREINIT: - const char *dnamestr = NULL; - const char *uristr = NULL; - const char *dxmlstr = NULL; - CODE: - if (SvOK(dxml)) - dxmlstr = SvPV_nolen(dxml); - if (SvOK(dname)) - dnamestr = SvPV_nolen(dname); - if (SvOK(uri)) - uristr = SvPV_nolen(uri); - - if ((RETVAL = virDomainMigrate2(dom, destcon, dxmlstr, - flags, dnamestr, uristr, bandwidth)) == NULL) - _croak_error(); + PREINIT: + virTypedParameter *params; + int nparams; + CODE: + nparams = 5; + Newx(params, nparams, virTypedParameter); + + memcpy(params[0].field, VIR_MIGRATE_PARAM_URI, + VIR_TYPED_PARAM_FIELD_LENGTH); + params[0].type = VIR_TYPED_PARAM_STRING; + + memcpy(params[1].field, VIR_MIGRATE_PARAM_DEST_NAME, + VIR_TYPED_PARAM_FIELD_LENGTH); + params[1].type = VIR_TYPED_PARAM_STRING; + + memcpy(params[2].field, VIR_MIGRATE_PARAM_DEST_XML, + VIR_TYPED_PARAM_FIELD_LENGTH); + params[2].type = VIR_TYPED_PARAM_STRING; + + memcpy(params[3].field, VIR_MIGRATE_PARAM_GRAPHICS_URI, + VIR_TYPED_PARAM_FIELD_LENGTH); + params[3].type = VIR_TYPED_PARAM_STRING; + + memcpy(params[4].field, VIR_MIGRATE_PARAM_BANDWIDTH, + VIR_TYPED_PARAM_FIELD_LENGTH); + params[4].type = VIR_TYPED_PARAM_ULLONG; + + + nparams = vir_typed_param_from_hv(newparams, params, nparams); + + /* No need to support virDomainMigrate/virDomainMigrate2, since + * virDomainMigrate3 takes care to call the older APIs internally + * if it is possible todo so + */ + if ((RETVAL = virDomainMigrate3(dom, destcon, params, nparams, flags)) == NULL) { + Safefree(params); + _croak_error(); + } + Safefree(params); OUTPUT: RETVAL void -migrate_to_uri2(dom, dconnuri, miguri=&PL_sv_undef, dxml=&PL_sv_undef, flags=0, dname=&PL_sv_undef, bandwidth=0) +_migrate_to_uri(dom, desturi, newparams, flags=0) virDomainPtr dom; - const char *dconnuri; - SV *miguri; - SV *dxml; + const char *desturi; + HV *newparams; unsigned long flags; - SV *dname; - unsigned long bandwidth; -PREINIT: - const char *miguristr = NULL; - const char *dxmlstr = NULL; - const char *dnamestr = NULL; - PPCODE: - if (SvOK(dxml)) - dxmlstr = SvPV_nolen(dxml); - if (SvOK(miguri)) - miguristr = SvPV_nolen(miguri); - if (SvOK(dname)) - dnamestr = SvPV_nolen(dname); + PREINIT: + virTypedParameter *params; + int nparams; + PPCODE: + nparams = 5; + Newx(params, nparams, virTypedParameter); - if (virDomainMigrateToURI2(dom, dconnuri, miguristr, dxmlstr, - flags, dnamestr, bandwidth) < 0) + memcpy(params[0].field, VIR_MIGRATE_PARAM_URI, + VIR_TYPED_PARAM_FIELD_LENGTH); + params[0].type = VIR_TYPED_PARAM_STRING; + + memcpy(params[1].field, VIR_MIGRATE_PARAM_DEST_NAME, + VIR_TYPED_PARAM_FIELD_LENGTH); + params[1].type = VIR_TYPED_PARAM_STRING; + + memcpy(params[2].field, VIR_MIGRATE_PARAM_DEST_XML, + VIR_TYPED_PARAM_FIELD_LENGTH); + params[2].type = VIR_TYPED_PARAM_STRING; + + memcpy(params[3].field, VIR_MIGRATE_PARAM_GRAPHICS_URI, + VIR_TYPED_PARAM_FIELD_LENGTH); + params[3].type = VIR_TYPED_PARAM_STRING; + + memcpy(params[4].field, VIR_MIGRATE_PARAM_BANDWIDTH, + VIR_TYPED_PARAM_FIELD_LENGTH); + params[4].type = VIR_TYPED_PARAM_ULLONG; + + nparams = vir_typed_param_from_hv(newparams, params, nparams); + + /* No need to support virDomainMigrateToURI/virDomainMigrateToURI2, since + * virDomainMigrate3 takes care to call the older APIs internally + * if it is possible todo so + */ + if (virDomainMigrateToURI3(dom, desturi, params, nparams, flags) < 0) { + Safefree(params); _croak_error(); + } + Safefree(params); void @@ -6392,6 +6508,7 @@ REGISTER_CONSTANT(VIR_DOMAIN_RUNNING_MIGRATION_CANCELED, STATE_RUNNING_MIGRATION_CANCELED); REGISTER_CONSTANT(VIR_DOMAIN_RUNNING_SAVE_CANCELED, STATE_RUNNING_SAVE_CANCELED); REGISTER_CONSTANT(VIR_DOMAIN_RUNNING_WAKEUP, STATE_RUNNING_WAKEUP); + REGISTER_CONSTANT(VIR_DOMAIN_RUNNING_CRASHED, STATE_RUNNING_CRASHED); REGISTER_CONSTANT(VIR_DOMAIN_BLOCKED_UNKNOWN, STATE_BLOCKED_UNKNOWN); @@ -6405,6 +6522,7 @@ REGISTER_CONSTANT(VIR_DOMAIN_PAUSED_FROM_SNAPSHOT, STATE_PAUSED_FROM_SNAPSHOT); REGISTER_CONSTANT(VIR_DOMAIN_PAUSED_SHUTTING_DOWN, STATE_PAUSED_SHUTTING_DOWN); REGISTER_CONSTANT(VIR_DOMAIN_PAUSED_SNAPSHOT, STATE_PAUSED_SNAPSHOT); + REGISTER_CONSTANT(VIR_DOMAIN_PAUSED_CRASHED, STATE_PAUSED_CRASHED); REGISTER_CONSTANT(VIR_DOMAIN_SHUTDOWN_UNKNOWN, STATE_SHUTDOWN_UNKNOWN); REGISTER_CONSTANT(VIR_DOMAIN_SHUTDOWN_USER, STATE_SHUTDOWN_USER); @@ -6419,6 +6537,7 @@ REGISTER_CONSTANT(VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT, STATE_SHUTOFF_FROM_SNAPSHOT); REGISTER_CONSTANT(VIR_DOMAIN_CRASHED_UNKNOWN, STATE_CRASHED_UNKNOWN); + REGISTER_CONSTANT(VIR_DOMAIN_CRASHED_PANICKED, STATE_CRASHED_PANICKED); REGISTER_CONSTANT(VIR_DOMAIN_PMSUSPENDED_UNKNOWN, STATE_PMSUSPENDED_UNKNOWN); @@ -6462,7 +6581,13 @@ REGISTER_CONSTANT(VIR_MIGRATE_UNSAFE, MIGRATE_UNSAFE); REGISTER_CONSTANT(VIR_MIGRATE_OFFLINE, MIGRATE_OFFLINE); REGISTER_CONSTANT(VIR_MIGRATE_COMPRESSED, MIGRATE_COMPRESSED); + REGISTER_CONSTANT(VIR_MIGRATE_ABORT_ON_ERROR, MIGRATE_ABORT_ON_ERROR); + REGISTER_CONSTANT_STR(VIR_MIGRATE_PARAM_BANDWIDTH, MIGRATE_PARAM_BANDWIDTH); + REGISTER_CONSTANT_STR(VIR_MIGRATE_PARAM_DEST_NAME, MIGRATE_PARAM_DEST_NAME); + REGISTER_CONSTANT_STR(VIR_MIGRATE_PARAM_DEST_XML, MIGRATE_PARAM_DEST_XML); + REGISTER_CONSTANT_STR(VIR_MIGRATE_PARAM_GRAPHICS_URI, MIGRATE_PARAM_GRAPHICS_URI); + REGISTER_CONSTANT_STR(VIR_MIGRATE_PARAM_URI, MIGRATE_PARAM_URI); REGISTER_CONSTANT(VIR_DOMAIN_XML_SECURE, XML_SECURE); REGISTER_CONSTANT(VIR_DOMAIN_XML_INACTIVE, XML_INACTIVE); @@ -6500,6 +6625,7 @@ REGISTER_CONSTANT(VIR_DOMAIN_EVENT_SHUTDOWN, EVENT_SHUTDOWN); REGISTER_CONSTANT(VIR_DOMAIN_EVENT_PMSUSPENDED, EVENT_PMSUSPENDED); REGISTER_CONSTANT(VIR_DOMAIN_EVENT_PMSUSPENDED_DISK, EVENT_PMSUSPENDED_DISK); + REGISTER_CONSTANT(VIR_DOMAIN_EVENT_CRASHED, EVENT_CRASHED); REGISTER_CONSTANT(VIR_DOMAIN_EVENT_DEFINED_ADDED, EVENT_DEFINED_ADDED); REGISTER_CONSTANT(VIR_DOMAIN_EVENT_DEFINED_UPDATED, EVENT_DEFINED_UPDATED); @@ -6512,6 +6638,8 @@ REGISTER_CONSTANT(VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT, EVENT_STARTED_FROM_SNAPSHOT); REGISTER_CONSTANT(VIR_DOMAIN_EVENT_STARTED_WAKEUP, EVENT_STARTED_WAKEUP); + REGISTER_CONSTANT(VIR_DOMAIN_EVENT_CRASHED_PANICKED, EVENT_CRASHED_PANICKED); + REGISTER_CONSTANT(VIR_DOMAIN_EVENT_SUSPENDED_PAUSED, EVENT_SUSPENDED_PAUSED); REGISTER_CONSTANT(VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED, EVENT_SUSPENDED_MIGRATED); REGISTER_CONSTANT(VIR_DOMAIN_EVENT_SUSPENDED_IOERROR, EVENT_SUSPENDED_IOERROR); @@ -6616,6 +6744,7 @@ REGISTER_CONSTANT(VIR_DOMAIN_EVENT_ID_PMWAKEUP, EVENT_ID_PMWAKEUP); REGISTER_CONSTANT(VIR_DOMAIN_EVENT_ID_TRAY_CHANGE, EVENT_ID_TRAY_CHANGE); REGISTER_CONSTANT(VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE, EVENT_ID_BALLOON_CHANGE); + REGISTER_CONSTANT(VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED, EVENT_ID_DEVICE_REMOVED); REGISTER_CONSTANT(VIR_DOMAIN_EVENT_WATCHDOG_NONE, EVENT_WATCHDOG_NONE); REGISTER_CONSTANT(VIR_DOMAIN_EVENT_WATCHDOG_PAUSE, EVENT_WATCHDOG_PAUSE); @@ -6701,6 +6830,7 @@ REGISTER_CONSTANT(VIR_DOMAIN_VCPU_LIVE, VCPU_LIVE); REGISTER_CONSTANT(VIR_DOMAIN_VCPU_CONFIG, VCPU_CONFIG); REGISTER_CONSTANT(VIR_DOMAIN_VCPU_MAXIMUM, VCPU_MAXIMUM); + REGISTER_CONSTANT(VIR_DOMAIN_VCPU_GUEST, VCPU_GUEST); REGISTER_CONSTANT(VIR_DOMAIN_SHUTDOWN_DEFAULT, SHUTDOWN_DEFAULT); @@ -6950,6 +7080,7 @@ REGISTER_CONSTANT(VIR_CONNECT_LIST_NODE_DEVICES_CAP_STORAGE, LIST_CAP_STORAGE); REGISTER_CONSTANT(VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST, LIST_CAP_FC_HOST); REGISTER_CONSTANT(VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPORTS, LIST_CAP_VPORTS); + REGISTER_CONSTANT(VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_GENERIC, LIST_CAP_SCSI_GENERIC); stash = gv_stashpv( "Sys::Virt::StorageVol", TRUE ); @@ -7063,6 +7194,8 @@ REGISTER_CONSTANT(VIR_FROM_INITCTL, FROM_INITCTL); REGISTER_CONSTANT(VIR_FROM_CGROUP, FROM_CGROUP); REGISTER_CONSTANT(VIR_FROM_IDENTITY, FROM_IDENTITY); + REGISTER_CONSTANT(VIR_FROM_ACCESS, FROM_ACCESS); + REGISTER_CONSTANT(VIR_FROM_SYSTEMD, FROM_SYSTEMD); REGISTER_CONSTANT(VIR_ERR_OK, ERR_OK); @@ -7153,4 +7286,6 @@ REGISTER_CONSTANT(VIR_ERR_OPERATION_UNSUPPORTED, ERR_OPERATION_UNSUPPORTED); REGISTER_CONSTANT(VIR_ERR_SSH, ERR_SSH); REGISTER_CONSTANT(VIR_ERR_RESOURCE_BUSY, ERR_RESOURCE_BUSY); + REGISTER_CONSTANT(VIR_ERR_ACCESS_DENIED, ERR_ACCESS_DENIED); + REGISTER_CONSTANT(VIR_ERR_DBUS_SERVICE, ERR_DBUS_SERVICE); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/lib/Sys/Virt/Domain.pm new/Sys-Virt-1.1.1/lib/Sys/Virt/Domain.pm --- old/Sys-Virt-1.0.5/lib/Sys/Virt/Domain.pm 2013-05-14 15:24:54.000000000 +0200 +++ new/Sys-Virt-1.1.1/lib/Sys/Virt/Domain.pm 2013-07-30 16:34:30.000000000 +0200 @@ -64,7 +64,12 @@ if ($params{nocreate}) { $self = Sys::Virt::Domain::_define_xml($con, $params{xml}); } else { - $self = Sys::Virt::Domain::_create($con, $params{xml}, $params{flags}); + if (exists $params{fds}) { + $self = Sys::Virt::Domain::_create_with_files($con, $params{xml}, + $params{fds}, $params{flags}); + } else { + $self = Sys::Virt::Domain::_create($con, $params{xml}, $params{flags}); + } } } else { die "address, id or uuid parameters are required"; @@ -112,7 +117,7 @@ Sets the metadata element of type C<$type> to hold the value C<$val>. If C<$type> is C<Sys::Virt::Domain::METADATA_ELEMENT> then the C<$key> and C<$uri> elements specify an XML namespace -to use, otherwise they should both be C<nudef>. The optional +to use, otherwise they should both be C<undef>. The optional C<$flags> parameter defaults to zero. =item $dom->is_active() @@ -150,6 +155,15 @@ accepts one of the DOMAIN CREATION constants documented later, and defaults to 0 if omitted. +=item $dom->create_with_files($fds, $flags) + +Start a domain whose configuration was previously defined using the +C<define_domain> method in L<Sys::Virt>. The C<$fds> parameter is an +array of UNIX file descriptors which will be passed to the init +process of the container. This is only supported with container based +virtualization.The C<$flags> parameter accepts one of the DOMAIN +CREATION constants documented later, and defaults to 0 if omitted. + =item $dom->undefine() Remove the configuration associated with a domain previously defined @@ -262,6 +276,10 @@ It is not known why the domain has crashed +=item Sys::Virt::Domain::STATE_CRASHED_PANICKED + +The domain has crashed due to a kernel panic + =item Sys::Virt::Domain::STATE_NOSTATE_UNKNOWN It is not known why the domain has no state @@ -306,6 +324,10 @@ The guest is paused while a snapshot takes place +=item Sys::Virt::Domain::STATE_PAUSED_CRASHED + +The guest is paused due to a kernel panic + =item Sys::Virt::Domain::STATE_RUNNING_BOOTED The guest is running after being booted @@ -342,6 +364,10 @@ The guest is running after wakeup from power management suspend +=item Sys::Virt::Domain::STATE_RUNNING_CRASHED + +The guest was restarted after crashing + =item Sys::Virt::Domain::STATE_BLOCKED_UNKNOWN The guest is blocked for an unknown reason @@ -494,6 +520,12 @@ the live guest, or inactive config, defaulting to modifying the current state. +=item $dom->set_memory_stats_period($period, $flags) + +Set the period on which guests memory stats are refreshed, +with C<$period> being a value in seconds. The C<$flags> +parameter is currently unused. + =item $dom->shutdown() Request that the guest OS perform a graceful shutdown and @@ -540,7 +572,7 @@ is given by C<$xml>. The optional <$flags> parameter defaults to 0 but can accept one of the device hotplug flags described later. -=item $data = $dom->block_peek($path, $offset, $size[, $flags) +=item $data = $dom->block_peek($path, $offset, $size[, $flags]) Peek into the guest disk C<$path>, at byte C<$offset> capturing C<$size> bytes of data. The returned scalar may contain embedded @@ -800,56 +832,215 @@ guest domain. The elements in the returned array are all hash references, whose keys are as described for C<get_security_label>. -=item $ddom = $dom->migrate(destcon, flags, dname, uri, bandwidth) +=item $ddom = $dom->migrate(destcon, \%params, flags=0) Migrate a domain to an alternative host. The C<destcon> parameter should be a C<Sys::Virt> connection to the remote target host. -If the C<flags> parameter is zero offline migration will be -performed. The C<Sys::Virt::Domain::MIGRATE_LIVE> constant can be -used to request live migration. The C<dname> parameter allows the -guest to be renamed on the target host, if set to C<undef>, the -domains' current name will be maintained. In normal circumstances, -the source host determines the target hostname from the URI associated -with the C<destcon> connection. If the destination host is multi-homed -it may be necessary to supply an alternate destination hostame -via the C<uri> parameter. The C<bandwidth> parameter allows network -usage to be throttled during migration. If set to zero, no throttling -will be performed. The C<flags>, C<dname>, C<uri> and C<bandwidth> -parameters are all optional, and if omitted default to zero, C<undef>, -C<undef>, and zero respectively. +The C<flags> parameter takes one or more of the C<Sys::Virt::Domain::MIGRATE_XXX> +constants described later in this document. The C<%params> parameter is +a hash reference used to set various parameters for the migration +operation, with the following valid keys. + +=over 4 + +=item C<Sys::Virt::Domain::MIGRATE_PARAM_URI> + +The URI to use for initializing the domain migration. It takes a +hypervisor specific format. The uri_transports element of the hypervisor +capabilities XML includes details of the supported URI schemes. When +omitted libvirt will auto-generate suitable default URI. It is typically +only necessary to specify this URI if the destination host has multiple +interfaces and a specific interface is required to transmit migration data. + +=item C<Sys::Virt::Domain::MIGRATE_PARAM_DEST_NAME> + +The name to be used for the domain on the destination host. Omitting +this parameter keeps the domain name the same. This field is only +allowed to be used with hypervisors that support domain renaming +during migration. + +=item C<Sys::Virt::Domain::MIGRATE_PARAM_DEST_XML> + +The new configuration to be used for the domain on the destination host. +The configuration must include an identical set of virtual devices, to +ensure a stable guest ABI across migration. Only parameters related to +host side configuration can be changed in the XML. Hypervisors which +support this field will forbid migration if the provided XML would cause +a change in the guest ABI. This field cannot be used to rename the domain +during migration (use VIR_MIGRATE_PARAM_DEST_NAME field for that purpose). +Domain name in the destination XML must match the original domain name. + +Omitting this parameter keeps the original domain configuration. Using this +field with hypervisors that do not support changing domain configuration +during migration will result in a failure. + +=item C<Sys::Virt::Domain::MIGRATE_PARAM_GRAPHICS_URI> + +URI to use for migrating client's connection to domain's graphical console +as VIR_TYPED_PARAM_STRING. If specified, the client will be asked to +automatically reconnect using these parameters instead of the automatically +computed ones. This can be useful if, e.g., the client does not have a direct +access to the network virtualization hosts are connected to and needs to +connect through a proxy. The URI is formed as follows: + + protocol://hostname[:port]/[?parameters] + +where protocol is either "spice" or "vnc" and parameters is a list of +protocol specific parameters separated by '&'. Currently recognized +parameters are "tlsPort" and "tlsSubject". For example, + + spice://target.host.com:1234/?tlsPort=4567 + +=item C<Sys::Virt::Domain::MIGRATE_PARAM_BANDWIDTH> + +The maximum bandwidth (in MiB/s) that will be used for migration. If +set to 0 or omitted, libvirt will choose a suitable default. Some +hypervisors do not support this feature and will return an error if +this field is used and is not 0. + +=back + +=item $ddom = $dom->migrate(destcon, flags=0, dname=undef, uri=undef, bandwidth=0) + +Migrate a domain to an alternative host. Use of positional parameters +with C<migrate> is deprecated in favour of passing a hash reference +as described above. + +=cut + +sub migrate { + my $dom = shift; + my $destcon = shift; + + if (ref $_[0] && + ref $_[0] eq "HASH") { + my $params = shift; + my $flags = shift; + + return $dom->_migrate($destcon, $params, $flags); + } else { + my $flags = shift; + my $dname = shift; + my $uri = shift; + my $bandwidth = shift; + my $params = {}; + + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_DEST_NAME} = $dname + if defined $dname; + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_URI} = $uri + if defined $uri; + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_BANDWIDTH} = $bandwidth + if defined $bandwidth; + + return $dom->_migrate($destcon, $params, $flags); + } +} + =item $ddom = $dom->migrate2(destcon, dxml, flags, dname, uri, bandwidth) -Migrate a domain to an alternative host. This function works in the -same way as C<migrate>, except is also allows C<dxml> to specify a -changed XML configuration for the guest on the target host. +Migrate a domain to an alternative host. This method is deprecated in +favour of passing a hash ref to C<migrate>. -=item $dom->migrate_to_uri(desturi, flags, dname, bandwidth) +=cut + +sub migrate2 { + my $dom = shift; + my $destcon = shift; + my $dxml = shift; + my $flags = shift; + my $dname = shift; + my $uri = shift; + my $bandwidth = shift; + my $params = {}; + + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_DEST_XML} = $dxml + if defined $dxml; + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_DEST_NAME} = $dname + if defined $dname; + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_URI} = $uri + if defined $uri; + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_BANDWIDTH} = $bandwidth + if defined $bandwidth; + + return $dom->_migrate($destcon, $params, $flags); +} + + +=item $ddom = $dom->migrate_to_uri(destcon, \%params, flags=0) Migrate a domain to an alternative host. The C<destri> parameter should be a valid libvirt connection URI for the remote target host. -If the C<flags> parameter is zero offline migration will be -performed. The C<Sys::Virt::Domain::MIGRATE_LIVE> constant can be -used to request live migration. The C<dname> parameter allows the -guest to be renamed on the target host, if set to C<undef>, the -domains' current name will be maintained. In normal circumstances, -the source host determines the target hostname from the URI associated -with the C<destcon> connection. If the destination host is multi-homed -it may be necessary to supply an alternate destination hostame -via the C<uri> parameter. The C<bandwidth> parameter allows network -usage to be throttled during migration. If set to zero, no throttling -will be performed. The C<flags>, C<dname> and C<bandwidth> -parameters are all optional, and if omitted default to zero, C<undef>, -C<undef>, and zero respectively. +The C<flags> parameter takes one or more of the C<Sys::Virt::Domain::MIGRATE_XXX> +constants described later in this document. The C<%params> parameter is +a hash reference used to set various parameters for the migration +operation, with the same keys described for the C<migrate> API. + +=item $dom->migrate_to_uri(desturi, flags, dname, bandwidth) + +Migrate a domain to an alternative host. Use of positional parameters +with C<migrate_to_uri> is deprecated in favour of passing a hash reference +as described above. + +=cut + +sub migrate_to_uri { + my $dom = shift; + my $desturi = shift; + + if (ref $_[0] && + ref $_[0] eq "HASH") { + my $params = shift; + my $flags = shift; + + return $dom->_migrate_to_uri($desturi, $params, $flags); + } else { + my $flags = shift; + my $dname = shift; + my $uri = shift; + my $bandwidth = shift; + my $params = {}; + + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_DEST_NAME} = $dname + if defined $dname; + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_URI} = $uri + if defined $uri; + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_BANDWIDTH} = $bandwidth + if defined $bandwidth; + + return $dom->_migrate_to_uri($desturi, $params, $flags); + } +} + =item $dom->migrate_to_uri2(dconnuri, miguri, dxml, flags, dname, bandwidth) -Migrate a domain to an alternative host. This function works in almost -the same way as C<migrate_to_uri>, except is also allows C<dxml> to -specify a changed XML configuration for the guest on the target host. -The C<dconnuri> must always specify the URI of the remote libvirtd -daemon, or be C<undef>. The C<miguri> parameter can be used to specify -the URI for initiating the migration operation, or be C<undef>. +Migrate a domain to an alternative host. This method is deprecated in +favour of passing a hash ref to C<migrate_to_uri>. + +=cut + +sub migrate_to_uri2 { + my $dom = shift; + my $desturi = shift; + my $dxml = shift; + my $flags = shift; + my $dname = shift; + my $uri = shift; + my $bandwidth = shift; + my $params = {}; + + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_DEST_XML} = $dxml + if defined $dxml; + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_DEST_NAME} = $dname + if defined $dname; + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_URI} = $uri + if defined $uri; + $params->{&Sys::Virt::Domain::MIGRATE_PARAM_BANDWIDTH} = $bandwidth + if defined $bandwidth; + + return $dom->_migrate_to_uri2($desturi, $params, $flags); +} =item $dom->migrate_set_max_downtime($downtime, $flags) @@ -1670,6 +1861,10 @@ Enable compression of the migration data stream +=item Sys::Virt::Domain::MIGRATE_ABORT_ON_ERROR + +Abort if an I/O error occurrs on the disk + =back =head2 UNDEFINE CONSTANTS @@ -1935,6 +2130,10 @@ Flag to request adjustment of the maximum vCPU value +=item Sys::Virt::Domain::VCPU_GUEST + +Flag to request the guest VCPU mask + =back =head2 STATE CHANGE EVENTS @@ -2128,6 +2327,18 @@ =back +=item Sys::Virt::Domain::EVENT_CRASHED + +The domain has crashed + +=over 4 + +=item Sys::Virt::Domain::EVENT_CRASHED_PANICKED + +The domain has crashed due to a kernel panic + +=back + =back =head2 EVENT ID CONSTANTS @@ -2194,6 +2405,10 @@ Balloon target changes +=item Sys::Virt::Domain::EVENT_ID_DEVICE_REMOVED + +Asynchronous guest device removal + =back =head2 IO ERROR EVENT CONSTANTS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/lib/Sys/Virt/Error.pm new/Sys-Virt-1.1.1/lib/Sys/Virt/Error.pm --- old/Sys-Virt-1.0.5/lib/Sys/Virt/Error.pm 2013-05-14 15:24:54.000000000 +0200 +++ new/Sys-Virt-1.1.1/lib/Sys/Virt/Error.pm 2013-07-30 16:34:30.000000000 +0200 @@ -354,6 +354,14 @@ The identity management code +=item Sys::Virt::Error::FROM_ACCESS + +The access control code + +=item Sys::Virt::Error::FROM_SYSTEMD + +The systemd init service + =back =head2 ERROR CODE CONSTANTS @@ -716,6 +724,14 @@ The resource requested is already in use +=item Sys::Virt::Error::ERR_ACCESS_DENIED + +Not authorized to perform the operation + +=item Sys::Virt::Error::ERR_DBUS_SERVICE + +An error from a DBus service API + =back =head1 AUTHORS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/lib/Sys/Virt/NodeDevice.pm new/Sys-Virt-1.1.1/lib/Sys/Virt/NodeDevice.pm --- old/Sys-Virt-1.0.5/lib/Sys/Virt/NodeDevice.pm 2013-05-14 15:24:54.000000000 +0200 +++ new/Sys-Virt-1.1.1/lib/Sys/Virt/NodeDevice.pm 2013-07-30 16:34:30.000000000 +0200 @@ -160,6 +160,10 @@ Include devices with the NPIV vport capability +=item Sys::Virt::NodeDevice::LIST_CAP_SCSI_GENERIC + +Include devices with the SCSI generic capability + =back =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/lib/Sys/Virt.pm new/Sys-Virt-1.1.1/lib/Sys/Virt.pm --- old/Sys-Virt-1.0.5/lib/Sys/Virt.pm 2013-05-14 15:24:54.000000000 +0200 +++ new/Sys-Virt-1.1.1/lib/Sys/Virt.pm 2013-07-30 16:34:30.000000000 +0200 @@ -78,7 +78,7 @@ use Sys::Virt::DomainSnapshot; use Sys::Virt::Stream; -our $VERSION = '1.0.5'; +our $VERSION = '1.1.1'; require XSLoader; XSLoader::load('Sys::Virt', $VERSION); @@ -239,6 +239,29 @@ return Sys::Virt::Domain->_new(connection => $self, xml => $xml, flags => $flags); } +=item my $dom = $vmm->create_domain_with_files($xml, $fds, $flags); + +Create a new domain based on the XML description passed into the C<$xml> +parameter. The returned object is an instance of the L<Sys::Virt::Domain> +class. This method is not available with unprivileged connections to +the VMM. The C<$fds> parameter is an array of UNIX file descriptors +which will be passed to the init process of the container. This is +only supported with container based virtualization. The C<$flags> +parameter accepts one of the DOMAIN CREATION constants documented +in L<Sys::Virt::Domain>, and defaults to 0 if omitted. + +=cut + +sub create_domain_with_files { + my $self = shift; + my $xml = shift; + my $fds = shift; + my $flags = shift || 0; + + return Sys::Virt::Domain->_new(connection => $self, xml => $xml, + fds => $fds, flags => $flags); +} + =item my $dom = $vmm->define_domain($xml); Defines, but does not start, a new domain based on the XML description diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/perl-Sys-Virt.spec new/Sys-Virt-1.1.1/perl-Sys-Virt.spec --- old/Sys-Virt-1.0.5/perl-Sys-Virt.spec 2013-05-14 15:25:08.000000000 +0200 +++ new/Sys-Virt-1.1.1/perl-Sys-Virt.spec 2013-07-30 16:34:51.000000000 +0200 @@ -1,7 +1,7 @@ # Automatically generated by perl-Sys-Virt.spec.PL Name: perl-Sys-Virt -Version: 1.0.5 +Version: 1.1.1 Release: 1%{?dist}%{?extra_release} Summary: Represent and manage a libvirt hypervisor connection License: GPLv2+ or Artistic diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Sys-Virt-1.0.5/t/030-api-coverage.t new/Sys-Virt-1.1.1/t/030-api-coverage.t --- old/Sys-Virt-1.0.5/t/030-api-coverage.t 2013-05-14 15:24:54.000000000 +0200 +++ new/Sys-Virt-1.1.1/t/030-api-coverage.t 2013-07-30 16:34:30.000000000 +0200 @@ -68,6 +68,7 @@ virFreeError virResetLastError virSaveLastError +virGetLastErrorMessage virConnectAuthCallbackPtr virConnectOpen @@ -86,6 +87,7 @@ virConnectDomainEventPMWakeupCallback virConnectDomainEventTrayChangeCallback virConnectDomainEventBalloonChangeCallback +virConnectDomainEventDeviceRemovedCallback virEventAddHandleFunc virEventAddTimeoutFunc @@ -100,6 +102,11 @@ virConnectCloseFunc +virDomainMigrate +virDomainMigrate2 +virDomainMigrateToURI +virDomainMigrateToURI2 + virTypedParamsAddBoolean virTypedParamsAddDouble virTypedParamsAddFromString -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
