Commit bbc25f0d03 juggled around some
error reporting. Unfortunately virFirewallApply tries to report the
errno stored in the firewall object and we'd try to do that when the
firewall object is NULL too. Report EINVAL if 'firewall' is NULL.
Found by Coverity.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
There's an optimization in virBufferAdd which returns early when the
length of the added string is 0 (given that auto-indent is disabled).
The optimization causes inconsistent behaviour between these two cases:
virBufferAdd(buf, "", 0); // this doesn't initialize the buffer
and
virBufferAdd(buf, "", -1); //this initializes the buffer
Since using an empty string is used to prime the buffer to an empty
string it can be confusing. Remove the optimization.
This fixes such a wrong initialization done in x86FeatureNames.
Note that our code in many places expects that if no virBuffer APIs are
used on a buffer object, then NULL should be retured, so we can't always
prime the buffer to an empty string.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Simplify the logic picking which element form to format by using
virBuffers for the partial properties and virXMLFormatElement for
combining them.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Use an allocated buffer for 'cpu_header' so that g_strdup(_printf) can
be used to fill it.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Use a dynamic string helper so that we don't have to calculate the
string lengths and then iterate from the rear.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
We can remove the check that 'idx' is negative by forcing callers to
pass unsigned numbers, which they do already or have a check that 'idx'
is positive.
This in turn allows us to remove most return value NULL checks.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
The function is used to automatically feed a buffer into a pipe which
can be used by the command to read contents of the buffer.
Rather than passing in a pipe, let's create the pipe inside
virCommandSetSendBuffer and directly associate the reader end with the
command. This way the ownership of both ends of the pipe will end up
with the virCommand right away reducing the need of cleanup in callers.
The returned value then can be used just to format the appropriate
arguments without worrying about cleanup or failure.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
The function can't fail nowadays. Remove the return value and adjust the
only caller which ensures that @cmd is non-NULL and @fd is positive.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Extract the check and reporting of error from the individual virCommand
APIs into a separate helper. This will aid future refactors.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
If WITH_PIPE2 is not defined we attempt to set the pipe to nonblocking
operation after they are created. We errorneously rewrote the existing
error message on failure to do so or even reported an error if quiet
mode was requested.
Fixes: ab36f72947
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
The function is constructing an error message from a prefix and the
contents of the qemu log file. Marking just two string modifiers as
translatable is pointless and will certainly confuse translators.
Remove the marking and add a comment which bypasses the
sc_libvirt_unmarked_diagnostics check.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Now that error message formatting doesn't use fixed size buffers we can
drop the math for calculating the maximum chunk of log to report in the
error message and use a round number. This also makes it obvious that
the chosen number is arbitrary.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Use of VIR_ERROR_MAX_LENGTH is actually misleading to the readers
because it implies that the strings in virError are 1024 bytes at most.
That isn't true at least for the 'message' field as it's constructed
from concatenating the detail string which (was) max 1024 bytes with
the string variant of the error code without limiting to 1024.
Use a local copy for declaring the struct for error transport with a
comment so that's obvious that it's a local decision to use 1k buffers.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Some error message reporting functions already have allocated buffers
which were used to format the error message, so copying the strings is
redundant.
Extract the internals from 'virRaiseErrorFull' to
'virRaiseErrorInternal' which takes allocated strings as arguments and
steals them, so that callers can reuse the buffers.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This was (probably) a relict from times when we cared about OOM
conditions and the possibility to report the error. Nowadays it doesn't
make sense as virRaiseErrorFull will do an allocated copy of the strings
and also concatenate the error message prefix with the detail which
doesn't guarantee that the result will be less than 1024 chars.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Use glib functions to do the relative name lookup instead of manual
assembly.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Passing 'strlen(src)' for length makes it equivalent to virStrcpy.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
virStrncpy was called with -1 for length of the copied source which is
equivalent to virStrcpy.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
We want a (possibly truncated) copy of the full source string so
virStrcpy is a better fit.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
15 out of 72 invocations of virStrcpy(Static) ignore the return value as
it's either impossible to fail or in certain cases a truncated copy is
still good enough. Unfortunately virStrcpy doesn't copy anything in
such case as the checks are done first.
Fix this by using g_strlcpy for the implementation and removing
G_GNUC_WARN_UNUSED_RESULT from the function so that callers can decide
when it's okay.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Similarly to the crash workaround:
commit 0db4743645
Author: Daniel P. Berrangé <berrange@redhat.com>
Date: Tue Jul 28 16:52:47 2020 +0100
util: avoid crash due to race in glib event loop code
we need to do this in the other event loop as crash in that one was also
reported:
https://bugzilla.redhat.com/show_bug.cgi?id=1931331
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This way it can be used from other places as well.
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Generated using the following spatch:
@@
expression path;
@@
- virFileMakePath(path)
+ g_mkdir_with_parents(path, 0777)
However, 14 occurrences were not replaced, e.g. in
virHostdevManagerNew(). I don't really understand why.
Fixed by hand afterwards.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
These functions are identical. Made using this spatch:
@@
expression path, mode;
@@
- virFileMakePathWithMode(path, mode)
+ g_mkdir_with_parents(path, mode)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Refractoring includes:
* removal of VIR_FREE
* inversion of the condition
Signed-off-by: Kristina Hanicova <khanicov@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
By:
* declaration of an autofreed variable in for loop
* use of a new variable
* removal of VIR_FREE
Signed-off-by: Kristina Hanicova <khanicov@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
VIR_DOMAIN_HYPERV_STIMER happens to have the same numerical value as
VIR_DOMAIN_FEATURE_HYPERV, resulting in the if-block to always being
executed when a "<hyperv>" tag is found, whether or not it actually
contained a "<stimer>" tag. This had no ill effects, as virXPathNodeSet()
would simply return 0 if that tag does not exist.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Variables using `g_autofree` should not be manually VIR_FREE'd and reused.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Previous commit removed all usage of this function so we can remove it.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Now that we enforce the cpu.shares range kernel will no longer silently
change the value that libvirt configures so there is no need to read
the value back to get the actual configuration.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Before the conversion to using systemd DBus API to set the cpu.shares
there was some magic conversion done by kernel which was documented in
virsh manpage as well. Now systemd errors out if the value is out of
range.
Since we enforce the range for other cpu cgroup attributes 'quota' and
'period' it makes sense to do the same for 'shares' as well.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Commit a208176ca1 introduced this feature
with an incorrect "svme-addr-check" spelling.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Tim Wiederhake <twiederh@redhat.com>
Commit 887dd0d331 caused a small regression in NodeDeviceDetach in the libxl
driver when the 'driver' parameter is not specified. E.g.
# virsh nodedev-detach pci_0000_0a_10_0
error: Failed to detach device pci_0000_0a_10_0
error: An error occurred, but the cause is unknown
If the driver name is not specified, NULL is passed to
virDomainDriverNodeDeviceDetachFlags, in which case virPCIDeviceSetStubDriver
is never called to set the stub to pciback. Fix it by setting the driver to
"xen" if it is not specified when invoking NodeDeviceDetach.
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Introduced in QEMU 6.0.0 by 623972ceae091b31331ae4a1dc94fe5cbb891937
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Trying to report an OOM error is pointless since our infrastructure to
report error needs to allocate memory to report the error.
In addition our code mistakenly reported OOM errors even in cases where
a function could fail for another reason, which would make issues harder
to debug.
Remove the virReportOOMError and backend so that programmers are forced
to think about what can happen. In case when there's another failure
possible a specific error should be reported and otherwise a direct
abort() is better since the logger would abort on g_new anyways.
This patch also removes the syntas-check which forces use of
virReportOOMError instead of using VIR_ERR_NO_MEMORY with other
functions. This allows possible future use when we'd end up in a
situation where trying to recover from an OOM would make sense, such as
when attempting to allocate a massive buffer.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
The function has also non-OOM failure case when the passed string has 0
length, so reporting OOM error is not correct.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
OOM isn't the only failure glfs_new can encounter. Report an error which
might give more insight. libgfapi seems to be setting errno but
reporting a system error migt be misleading.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
The yajl library returns a wide range of error codes so reporting OOM on
any failure is wrong. In case the error was really based by memory issue
the error reporting will probably cause an abort anyways. Change the
error message so that we know that it happened in JSON at least.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
'xmlNewDoc' and 'xmlNewDocComment' return NULL only on allocation
failure. Attempting to raise an error is pointless.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
Attempting to report error in case when we ran out of memory is
pointless.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
Trying to report an error on OOM is pointless since error handling
allocates memory.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
The function just allocates a helper object. Reporting errors would be
pointless when we encounter OOM situation.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
If the argument of 'xmlSaveUri' is non-NULL the function returns NULL on
OOM failure only. Thus we can directly abort rather than try to do the
impossible recovery.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
Out of memory isn't the only reason the function can fail. Add a message
stating that copying of a XML node failed.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
Add a wrapper that will handle the out of memory condition by abort()
and also prevents callers from having to typecast the argument.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
'xmlBufferCreate' returns NULL only on allocation failure. Add a wrapper
which will call 'abort()' in such case in a centralised spot. It doesn't
make much sense to continue execution from here.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
The function is used in many places and fails only on allocation
failures. Since trying to recover from allocation failure of a small
buffer by reporting error doesn't make sense add a wrapper for
'nlmsg_alloc_simple' which will 'abort()' on failure and replace all
allocations of netlink message with the new helper.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
There's nothing that would set the 'err' field of virFirewallPtr to
ENOMEM so we can remove the checks.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
VIR_APPEND_ELEMENT_COPY will abort the program on OOM so there's no need
to check.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
VIR_EXPAND_N will abort so we can simplify the hash iterator.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
Switch to use g_autoptr for 'doc' and 'new' local variables.
Additionally report proper error when 'xmlAddChild' fails because OOM is
not the only error it can report.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
'virLogGetFilters' doesn't return failure and 'virLogGetOutputs' reports
it's own errors.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
The function can't fail nowadays, remove the return value and adjust
callers.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
Get the buffer contents into a temporary variable with automatic
clearing so that the error branches don't have to reset the buffer.
Additionally handle the NULL string case before assignment.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
The function is supposed to always consume the passed environment
variable string. Use a temp variable with autofree and g_steal_pointer
to prevent having to free it manually.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
Since error checking was removed when switching to g_strdup, it doesn't
make much sense to have 'tmp' around.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
This function finds "swtmp", "swtpm_setup" and "swtpm_ioctl"
binaries in $PATH and stores resolved paths in global variables
so that they can be obtainer later. Anyway, the resolved path is
marked as g_autofree and to avoid its freeing later on in the
function the variable is set to NULL manually. Well, we have
g_steal_pointer() for that.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
When starting a guest with TPM of type='emulator' an external
process is started with it (swtpm) to emulate TPM. This external
process is passed path to a log file via --logfile. The path to
the log file is generated in qemuTPMEmulatorPrepareHost() which
works, until the daemon is restarted. The problem is that the
path is not stored in private data or anywhere inside live XML
and thus later, when qemuExtTPMStop() is called (when shutting
off the guest) the stored logpath is NULL and thus its seclabel
is not cleaned up (see virSecuritySELinuxRestoreTPMLabels()).
Fortunately, qemuExtDevicesStop() (which calls qemuExtTPMStop()
eventually) does call qemuExtDevicesInitPaths() where the log
path can be generated again.
Basically, tpm->data.emulator.storagepath is generated in
qemuExtTPMInitPaths() and its seclabels are restored properly,
and this commit move logfile onto the same level.
This means, that the log path doesn't have to be generated in
qemuExtDevicesStart() because it was already done in
qemuExtDevicesPrepareHost().
This change also renders @vmname argument of
qemuTPMEmulatorPrepareHost() unused and thus is removed.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1769196
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Strictly not needed, but the rest of paths is generated in
separate functions. Helps with code readability.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
In files: src/lxc/lxc_native: in lxcAddNetworkRouteDefinition(),
src/conf/networkcommon_conf: in virNetDevIPRouteCreate() and
virNetDevIPRouteParseXML()
Signed-off-by: Kristina Hanicova <khanicov@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
In files: src/conf/domain_conf: in virDomainNetIPInfoParseXML(),
src/lxc/lxc_native: in lxcAddNetworkRouteDefinition(),
src/vz/vz_sdk: in prlsdkGetRoutes(), src/conf/networkcommon_conf:
in virNetDevIPRouteCreate()
Signed-off-by: Kristina Hanicova <khanicov@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
This was added to qemu in commit 5447089c2b3b084b51670af36fc86ee3979e04be.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
This was added to qemu in commit 623972ceae091b31331ae4a1dc94fe5cbb891937.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
This was added to qemu in commit 623972ceae091b31331ae4a1dc94fe5cbb891937.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Example:
../src/hyperv/hyperv_driver.c:3007:54: error: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 7 has type ‘size_t’ {aka ‘unsigned int’} [-Werror=format=]
3007 | virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not attach serial port %lu"), i);
Signed-off-by: Cole Robinson <crobinso@redhat.com>
virHostdevReAttachPCIDevices() is called when we want to re-attach
a list of hostdevs back to the host, either on the shutdown path or
via a 'virsh detach-device' call. This function always count on the
existence of the device in the host to work, but this can lead to
problems. For example, a SR-IOV device can be removed via an admin
"echo 0 > /sys/bus/pci/devices/<addr>/sriov_numvfs", making the kernel
fire up and eventfd_signal() to the process, asking for the process to
release the device. The result might vary depending on the device driver
and OS/arch, but two possible outcomes are:
1) the hypervisor driver will detach the device from the VM, issuing a
delete event to Libvirt. This can be observed in QEMU;
2) the 'echo 0 > ...' will hang waiting for the device to be unplugged.
This means that the VM process failed/refused to release the hostdev back
to the host, and the hostdev will be detached during VM shutdown.
Today we don't behave well for both cases. We'll fail to remove the PCI device
reference from mgr->activePCIHostdevs and mgr->inactivePCIHostdevs because
we rely on the existence of the PCI device conf file in the sysfs. Attempting
to re-utilize the same device (assuming it is now present back in the host)
can result in an error like this:
$ ./run tools/virsh start vm1-sriov --console
error: Failed to start domain vm1-sriov
error: Requested operation is not valid: PCI device 0000:01:00.2 is in use by driver QEMU, domain vm1-sriov
For (1), a VM destroy/start cycle is needed to re-use the VF in the guest.
For (2), the effect is more nefarious, requiring a Libvirtd daemon restart
to use the VF again in any guest.
We can make it a bit better by checking, during virHostdevReAttachPCIDevices(),
if there is any missing PCI device that will be left behind in activePCIHostdevs
and inactivePCIHostdevs lists. Remove any missing device found from both lists,
unconditionally, matching the current state of the host. This change affects
the code path in (1) (processDeviceDeletedEvent into qemuDomainRemoveDevice, all
the way back to qemuHostdevReAttachPCIDevices) and also in (b) (qemuProcessStop
into qemuHostdevReAttachDomainDevices).
NB: Although this patch enables the possibility of 'outside Libvirt' SR-IOV
hotunplug of PCI devices, if the hypervisor and the PCI driver copes with it,
our goal is to mitigate what it is still considered a user oopsie. For all
supported purposes, the admin must remove the SR-IOV VFs from all running domains
before removing the VFs from the host.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/72
Reviewed-by: Laine Stump <laine@redhat.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
This change will allow us to remove PCI devices from a list
without the need of a PCI Device object, which will be need
in the next patch.
Reviewed-by: Laine Stump <laine@redhat.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
We're going to need a way to remove a PCI Device from a list without having
a valid virPCIDevicePtr, because the device is missing from the host. This
means that virPCIDevicesListDel() must operate with a PCI Device address
instead.
Turns out that virPCIDevicesListDel() and its related functions only use
the virPCIDeviceAddressPtr of the virPCIDevicePtr, so this change is
simple to do and will not cause hassle in all other callers. Let's
start adapting virPCIDeviceListFindIndex() and crawl our way up to
virPCIDevicesListDel().
Reviewed-by: Laine Stump <laine@redhat.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>