summaryrefslogtreecommitdiff
path: root/src/pulsecore
AgeCommit message (Collapse)AuthorFilesLines
2016-06-22pulsecore: Fix incorrect architecture mapping on sparc64.John Paul Adrian Glaubitz1-1/+1
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=95432 Signed-off-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> Signed-off-by: Arun Raghavan <arun@arunraghavan.net>
2016-06-22pulsecore: Don't allow unreferencing linked object.Juho Hämäläinen4-16/+9
Sink(-input) and source(-output) called unlink function when reference count dropped to zero. This would result in unlink hooks being called with an object having a reference count of zero, and this is not a situation we want modules to have to deal with. It is better to just remove the redundant unlinking code from sink(-input) and source(-output) and assert on reference count in unlink functions as well. It is expected that in well behaving code the owner of an object will always unlink the object before unreferencing. Signed-off-by: Arun Raghavan <arun@arunraghavan.net>
2016-06-22core-util: Improve pa_replace() behaviourUlrich Eckhardt2-0/+5
- Assert that the search string isn't empty. - Add test. - Improve documentation.
2016-06-22pstream: fix revoke callback settingTanu Kaskinen1-2/+2
While investigating bug 95352, I noticed that pa_pstream_set_revoke_callback() and pa_pstream_set_release_callback() were identical - both set the release callback. pa_pstream_set_revoke_callback() was obviously broken - it was setting the wrong callback. The only place where set_revoke_callback() is called is in protocol-native.c. The code there looks like this: pa_pstream_set_revoke_callback(c->pstream, pstream_revoke_callback, c); pa_pstream_set_release_callback(c->pstream, pstream_release_callback, c); Since set_release_callback() is called last, the release callback gets set correctly. The only problem is that the revoke callback stays unset. What are the consequences of that? The code that calls the revoke callback looks like this: if (p->revoke_callback) p->revoke_callback(p, block_id, p->revoke_callback_userdata); else pa_pstream_send_revoke(p, block_id); So the intended callback is replaced with a pa_pstream_send_revoke() call. What does the intended callback, that doesn't get called, do? if (!(q = pa_thread_mq_get())) pa_pstream_send_revoke(p, block_id); else pa_asyncmsgq_post(q->outq, PA_MSGOBJECT(userdata), CONNECTION_MESSAGE_REVOKE, PA_UINT_TO_PTR(block_id), 0, NULL, NULL); So the native protocol's revoke callback is anyway going to call pa_pstream_send_revoke() when called from the main thread. If the revoking is done from an IO thread, an asynchronous message is sent to the main thread instead, and the message handler will then call pa_pstream_send_revoke(). In conclusion, the only effect of this bug was that pa_pstream_send_revoke() was sometimes being called from an IO thread when it should have been called from the main thread. I don't know if this caused the crash in bug 95352. Probably not.
2016-06-22client, protocol-native: Use macros for protocol version/flag accessArun Raghavan1-5/+5
This makes it easier to read and cleaner in general.
2016-06-21sink-input,source-output: Fix crasher while setting propertyArun Raghavan2-2/+2
We were missing a case where a property is first set, and then cleared by setting a NULL value. Signed-off-by: Arun Raghavan <arun@arunraghavan.net>
2016-06-21pstream: Fix use of uninitialized value: ancillary fd cleanup flagAhmed S. Darwish1-1/+1
As reported by valrgrind ==30002== Conditional jump or move depends on uninitialised value(s) ==30002== at 0x5CB883C: pa_cmsg_ancil_data_close_fds (pstream.c:193) ==30002== by 0x5CBB161: do_write (pstream.c:759) ==30002== by 0x5CB8B51: do_pstream_read_write (pstream.c:233) ==30002== by 0x5CB8EE8: io_callback (pstream.c:279) ... The pa_cmsg_ancil_data structure has two main guards: 'creds_valid', which implies that it holds credentials information, and 'nfd', which implies it holds file descriptors. When code paths create a credentials ancillary data structure, they just set the 'nfd' guard to zero. Typically, the rest of pa_cmsg_ancil_data fields related to fds are _all_ left _uninitialized_. pa_cmsg_ancil_data_close_fds() has broken the above contract: it accesses the new 'close_fds_on_cleanup' flag, which is related to file descriptors, without checking the 'nfd == 0' guard first. Fix this inconsistency. Reported-by: Alexander E. Patrakov <patrakov@gmail.com> Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com> Signed-off-by: Arun Raghavan <arun@arunraghavan.net>
2016-06-21shm: Fix use of uninitialized value: segment's shared-memory typeAhmed S. Darwish1-7/+7
As shown by valgrind ==10615== Conditional jump or move depends on uninitialised value(s) ==10615== at 0x5CC0483: shm_marker_size (shm.c:97) ==10615== by 0x5CC1685: shm_attach (shm.c:381) ==10615== by 0x5CC1990: pa_shm_cleanup (shm.c:453) ==10615== by 0x5CC068E: sharedmem_create (shm.c:150) ... Solution is to fix the shm_marker_size() signature itself: At certain code paths like shm_attach(), we don't want to initialize _any_ field in the passed SHM segment descriptor except after making sure all error exit conditions have been passed. Reported-by: Alexander E. Patrakov <patrakov@gmail.com> Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com> Signed-off-by: Arun Raghavan <arun@arunraghavan.net>
2016-05-27resampler: Fix leaking lfe filter on init failureBarun Kumar Singh1-0/+2
Fix memory leak in pa_resampler_new() in resampler.c, Deallocating memory of r->lfe_filter in case of fail. Signed-off-by: Arun Raghavan <arun@arunraghavan.net>
2016-05-24Disable LFE remixing by defaultAlexander E. Patrakov1-2/+2
The current LFE crossover filter removes low frequencies from the main channels and puts them into the LFE channel with the wrong amplitude. It is not known for sure what is the correct relative amplitude (acoustic measurements are required with real hardware), and changing that might introduce a new bug, "it clips the LFE channel". So just disable the feature by default until a better understanding emerges how it should work. This, essentially, returns the defaults to their state as of PulseAudio 6.0. Some more observations: - Most of available active analog speakers on the market do the necessary crossover filtering already, and HDMI receivers can be configured to do that, too, so a crossover filter in PulseAudio is harmful in these use cases. - The "laptop with a builtin subwoofer" use case requires manual configuration anyway because the default crossover frequency (120 Hz) is wrong for laptop speakers. - Finally, Windows 10 with a built-in USB audio driver does not synthesize the LFE channel given a 5.1 card and a stereo audio stream by default. Hides: https://bugs.freedesktop.org/show_bug.cgi?id=95021 Signed-off-by: Alexander E. Patrakov <patrakov@gmail.com>
2016-05-13resampler: Fix a memory leak in pa_resampler_ffmpeg_init()Sachin Kumar Chauhan1-1/+3
ffmpeg_data was not freed properly before return due to error. It is now freed properly. BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=95347 Signed-off-by: Sachin Kumar Chauhan <sachin.kc@samsung.com> Signed-off-by: Arun Raghavan <arun@arunraghavan.net>
2016-05-11alsa: Reread and upate jack status when a card is unsuspendedArun Raghavan2-2/+12
This is needed so we don't keep stale jack availability information while the card is suspended. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=93259 Signed-off-by: Arun Raghavan <arun@arunraghavan.net>
2016-05-10alsa: ignore jack events when the user is inactiveTanu Kaskinen2-0/+7
See the big comment in the code for more details. BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=93259
2016-05-06pulsecore: Fixed possible memory leakDeepak Srivastava1-1/+3
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=95291 Signed-off-by: Deepak Srivastava <srivastava.d@samsung.com> Signed-off-by: Arun Raghavan <git@arunraghavan.net>
2016-05-03card: add preferred_{input, output}_portTanu Kaskinen3-0/+59
I will modify module-switch-on-port-available so that it will keep track of which input and output port the user prefers on the card, based on the user's profile and port switches. The preference needs to be saved on disk, for which I will use module-card-restore. To facilitate communication between the two modules, this patch adds preferred_input_port and preferred_output_port fields to pa_card, and a hook for monitoring the variable changes. It would be nice if the two modules would communicate directly with each other, but implementing that would be somewhat complicated, so I chose this time for adding the functionality to the core. In theory some other routing module might want to manage the new variables instead of module-switch-on-port-available, but admittedly that's not very likely to happen...
2016-04-27core: Support memfd transport; bump protocol versionAhmed S. Darwish3-15/+45
Now that all layers in the stack support memfd blocks, add memfd support for the daemon's global core mempool. Also introduce "enable-memfd=" daemon argument and configuration option. For now, memfd support is an opt-in feature to be activated only when daemon's enable-memfd= is set to yes. Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-04-27client audio: Support memfd transportAhmed S. Darwish2-2/+35
Now that all layers in the stack support memfd blocks, add memfd pools support for client context and audio playback data. Use such memfd pools by default only if the server signals memfd support in its connection negotiations. Also add ability for clients to force-disable memfd transport through the `enable-memfd=' client configuration option. Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-04-25sink-input, source-output: remove set_name()Tanu Kaskinen5-56/+2
pa_sink_input_set_property() does everything pa_sink_input_set_name() does.
2016-04-25sink-input, source-output: rework property settingTanu Kaskinen4-10/+228
pa_sink_input_update_proplist() is inconvenient in many cases, because it requires allocating a new proplist, even if the goal is to just set one property. pa_sink_input_update_properties also can't properly log property changes, because it has to assume that all values are arbitrary binary data. This patch adds pa_sink_input_set_property() for setting a string value for a single property, and pa_sink_input_set_property_arbitrary() for setting a binary value for a single property. pa_sink_input_update_properties() is reimplemented as a wrapper around pa_sink_input_set_property_arbitrary() to centralize logging and sending change notifications. (The above mentions only sink input functions for brevity, but the same changes are implemented for source outputs too.)
2016-04-25don't move streams to devices that are going awayTanu Kaskinen6-3/+27
Before a device is unlinked, the unlink hook is fired, and it's possible that a routing module tries to move streams to the unlinked device in that hook, because it doesn't know that the device is being unlinked. Of course, the unlinking is obvious when the code is in an unlink hook callback, but it's possible that some other module does something in the unlink hook that in turn triggers some other hook, and it's this second hook where the routing module may get confused. This patch adds an "unlink_requested" flag that is set before the unlink hook is fired, and moving streams to a device with that flag set is prevented. This patch is motivated by seeing module-device-manager moving a stream to a sink that was being unlinked. It was a complex case where an alsa card was changing its profile, while an echo-cancel sink was connected to the old alsa sink. module-always-sink loaded a null sink in the middle of the profile change, and after a stream had been rescued to the null sink, module-device-manager decided to move it back to the old alsa sink that was being unlinked. That move made no sense, so I came up with this patch.
2016-04-24protocol-native: Disable srbchannel for setups without SCM_CREDENTIALSAhmed S. Darwish2-2/+7
srbchannel needs fd passing. Otherwise we get the following error for systems without SCM_CREDENTIALS support: Code should not be reached at pulsecore/pstream-util.c:95, function pa_pstream_send_tagstruct_with_fds(). Aborting. [[ The root cause is that we define HAVE_CREDS only if SCM_CREDENTIALS is defined, but SCM_CREDENTIALS is a Linux-specific symbol. Thus HAVE_CREDS is always disabled on Solaris. And since pulse couples the non-portable creds passing support with the portable fd passing one, through _35_ places where HAVE_CREDS is used, a real fix needs a PA redesign -- assuming that latency on Solaris is something people care about. ]] BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=94339 Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-04-02memblock/pstream: Fix two compiler warningsDavid Henningsson2-2/+4
Fix two compiler warnings recently introduced by the memfd patch set. Signed-off-by: David Henningsson <diwic@ubuntu.com>
2016-04-02pstream: Support memfd blocks transportAhmed S. Darwish12-54/+411
Now that we have the necessary infrastructure to memexport and mempimport a memfd memblock, extend that support higher up in the chain with pstreams. A PA endpoint can now _transparently_ send a memfd memblock to the other end by simply calling pa_pstream_send_memblock() – provided the block's memfd pool was earlier registered with the pstream. If the pipe does not support memfd transfers, we fall back to sending the block's full data instead of just its reference. ** Further details: A single pstream connection usually transfers blocks from multiple pools including the server's srbchannel mempool, the client's audio data mempool, and the server's global core mempool. If these mempools are memfd-backed, we now require registering them with the pstream before sending any blocks they cover. This is done to minimize fd passing overhead and avoid fd leaks. Moreover, to support all these pools without hard-coding their number or nature in the Pulse communication protocol itself, a new REGISTER_MEMFD_SHMID command is introduced. That command can be sent _anytime_ during the pstream's lifetime and is used for creating on demand SHM ID to memfd mappings. Suggested-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-04-02pulsecore: Specially mark global mempoolsAhmed S. Darwish5-6/+111
Color global mempools with a special mark. This special marking is needed for handling memfd-backed pools. To avoid fd leaks, memfd pools are registered with the connection pstream to create an ID<->memfd mapping on both PA endpoints. Such memory regions are then always referenced by their IDs and never by their fds, and so their fds can be safely closed later. Unfortunately this scheme cannot work with global pools since the registration ID<->memfd mechanism needs to happen for each newly connected client, and thus the need for a more special handling. That is, for the pool's fd to be always open :-( Almost all mempools are now created on a per-client basis. The only exception is the pa_core's mempool which is still shared between all clients of the system. Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-04-02memimport: Support memfd blocksAhmed S. Darwish5-19/+108
To transfer memfd-backed blocks without passing their fd every time, thus minimizing overhead and avoiding fd leaks, a command is sent with the memfd fd as ancil data very early on. This command has an ID that uniquely identifies the memfd region. Further memfd block references are then exclusively done using this ID. This commit implements the details of such 'permanent' mappings on the receiving end, using memimport segments. Suggested-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-04-02pulsecore: Introduce memfd supportAhmed S. Darwish3-65/+206
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus developers, to share pages between processes in an anonymous, no global registry needed, no mount-point required, relatively secure, manner. This patch introduces the necessary building blocks for using memfd shared memory transfers in PulseAudio. Memfd support shall also help us in laying out the necessary (but not yet sufficient) groundwork for application sandboxing, protecting PA from its clients, and protecting clients data from each other. We plan to exclusively use memfds, instead of POSIX SHM, on the way forward. Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-04-02SHM: Refactor private allocationsAhmed S. Darwish1-73/+87
pa_shm_create_rw() is responsible for creating two types of memory: POSIX shared memory and regular malloc()-ed ones. A third memory type, memfds, will be added later. Thus to add this extra shared memory type in a sane manner, refactor private memory allocations into their own static methods. Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-04-02pulsecore: Transform pa_mempool_new() into a factory methodAhmed S. Darwish7-23/+78
Soon we're going to have three types of memory pools: POSIX shm_open() pools, memfd memfd_create() ones, and privately malloc()-ed pools. Thus introduce annotations for the memory types supported and change pa_mempool_new() into a factory method based on required memory. Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-04-02srbchannel: Introduce per-client SHM filesAhmed S. Darwish3-17/+27
The PA daemon currently uses a single SHM file for all clients sending and receiving commands over the low-latency srbchannel mechanism. To avoid leaks between clients in that case, and to provide the necessary ground work later for sandboxing and memfds, create the srbchannel SHM files on a per-client basis. Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-04-02pulsecore: Reference count mempoolsAhmed S. Darwish7-8/+72
In future commits, server-wide SHMs will be replaced with per-client ones that will be dynamically created and freed according to clients connections open and close. Meanwhile, current PA design does not guarantee that the per-client mempool blocks are referenced only by client-specific objects. Thus reference count the pools and let each memblock inside the pool itself, or just attached to it, increment the pool's refcount upon allocation. This way, per-client mempools will only be freed when no further component in the system holds any references to its blocks. DiscussionLink: https://goo.gl/qesVMV Suggested-by: Tanu Kaskinen <tanuk@iki.fi> Suggested-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-04-02pulsecore: Cache daemon shm size inside pa_coreAhmed S. Darwish2-0/+6
The daemon `shm-size-bytes' configuration value was read, and then directly used, for creating the initial server-wide SHM files. This is fine for now, but soon, such server-wide SHMs will be replaced with per-client SHM files that will be dynamically created and deleted according to clients open and close. Thus, appropriately cache this configuration value. Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-25log: journal: Prevent duplicate values for CODE_* fieldsAhmed S. Darwish1-0/+11
sd_journal_send() implicitly add fields for the source file, function name and code line from where it's invoked. As code location fields CODE_FILE, CODE_LINE and CODE_FUNC are handled by PA's log module, we do not want the automatic values supplied by the sd_journal API. Without suppressing these, both the actual log event source and the call to sd_journal_send() will be logged: $ journalctl -b -f -o json-pretty [...] CODE_FILE : [ pulsecore/log.c, pulsecore/module.c ], CODE_LINE : [ 505, 181 ], MESSAGE : Failed to load module module-gconf CODE_FUNC : [ pa_log_levelv_meta, pa_module_load ], [...] (Commit log adapted from abrt libreport commit d1eaae97f0287f) Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-02-18core: Fix GCC 6 compiler warning regarding left shift of negative valuePeter Meerwald1-2/+4
In file included from pulse/timeval.c:32:0: pulse/timeval.c: In function 'pa_timeval_add': ./pulsecore/macro.h:303:28: warning: left shift of negative value [-Wshift-negative-value] ? ~(~(type) 0 << (8*sizeof(type)-1)) reported by Ubuntu gcc-6 gcc-6 adds -Wshift-negative-value (enabled by -Wextra) which warns about left shifting a negative value. Such shifts are undefined because they depend on the representation of negative values. also works with -Wshift-overflow=2 Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
2016-01-22source-output: remap volume_factor_source when starting moveTanu Kaskinen1-0/+3
This gets rid of an error message from the debug log. If volume_factor_source would actually be used somewhere, this bug would have caused more severe problems. volume_factor_source should have the source's channel map. When moving the stream, the volume needs to be remapped from the old source's channel map to the new source's map. However, when the stream is being moved, there is a period where the old source has already been forgotten and the new source isn't yet known, so the remapping can't be done directly between the two channel maps. Instead, the volume is remapped from the old source's map to the stream's own map when the move starts, and again remapped from the stream's map to the new source's map when the move finishes. The first remapping was missing, causing the second remapping fail and print an error to the log. (I checked the sink input code as well. It didn't have this bug.)
2016-01-22source-output: do volume_factor_source application before resamplingTanu Kaskinen1-13/+7
Applying the volume after resampling means mismatch between the volume channel map and the data channel map. volume_factor_source is not currently used anywhere, so this bug hasn't been causing any problems. I noticed it while reading the code.
2016-01-15build-sys: Use #ifdef with HAVE_FAST_64BIT_OPERATIONSArun Raghavan1-1/+1
The define is made conditionally. Reported by: Kamil Rytarowski <n54@gmx.com>
2016-01-12sink-input, source-output: Add some debug output on start_move()Arun Raghavan2-0/+4
2016-01-08NetBSD: Stop depending upon nonstandard __WORDSIZEKamil Rytarowski1-1/+1
There is no way to check CPU type in a portable way across ABIs. Assume if pointers are 64-bit that CPU is capable to perform fast 64-bit operations. Add an extra check to handle x32-ABI. PulseAudio by default builds with -Wundef. If we add -Werror=undef this missing define is fatal. By default build log is full of entries like: In file included from ./pulsecore/core.h:47:0, from ./pulsecore/module.h:31, from ./pulsecore/sink-input.h:31, from pulsecore/sound-file-stream.c:36: ./pulsecore/sample-util.h: In function 'pa_mult_s16_volume': ./pulsecore/sample-util.h:58:5: warning: "__WORDSIZE" is not defined [-Wundef] #if __WORDSIZE == 64 || ((ULONG_MAX) > (UINT_MAX)) ^ (NetBSD-7.99.21 with default GCC 4.8.5) This change fixes build issues on NetBSD. This also address a bug reported by Shawn Walker from Oracle (possibly Solaris): Bug 90880 - builds can fail due to non-portable glibc-specific internal macro usage
2016-01-07rtpoll: Fix build error when building with DEBUG_TIMINGjungsup lee1-1/+1
This typo causes a build error when DEBUG_TIMING is defined. Signed-off-by: jungsup lee <jungsup4.lee@samsung.com>
2015-12-14conf-parser: add support for .d directoriesTanu Kaskinen2-3/+47
This allows a configuration scheme where after loading configuration from "somefile", the parser loads configuration from files in directory "somefile.d". This feature needs to be enabled on a per-file basis, though, and this patch doesn't yet enable the feature for any files.
2015-12-14typedefs.h: Move some typedefs to a separate fileDavid Henningsson9-19/+47
The relationship between sinks, sources, cards, profiles, and ports is becoming ever more intertwined, to the point that if you try to include one file from the other, you're likely to end up with some weird error somewhere else. Work around this by creating a new typedefs.h, which does not depend on anything else, and just creates a few typedefs. (Can be expanded with more typedefs in the future if the need arises.) Signed-off-by: David Henningsson <david.henningsson@canonical.com>
2015-12-08core, pulse, modules: Fix undefined behavior with array subscript of invalid ↵Kamil Rytarowski3-8/+8
type From the NetBSD manual: The first argument of these functions is of type int, but only a very restricted subset of values are actually valid. The argument must either be the value of the macro EOF (which has a negative value), or must be a non-negative value within the range representable as unsigned char. Passing invalid values leads to undefined behavior. -- ctype(3)
2015-12-08core-rtclock: Add missing declaration of struct timespecKamil Rytarowski1-0/+2
2015-12-07core-util: improve comments in pa_machine_id()Tanu Kaskinen1-8/+13
2015-12-07module: Remove redundant core argument from pa_module_unload()Kiran Krishnappa3-6/+5
pa_module_unload() takes two pointers: pa_module and pa_core. The pa_core pointer is also available via the pa_module object, so the pa_core argument is redundant [David Henningsson: Rebased to git HEAD]
2015-12-07netbsd: Improve handling of <locale> and <xlocale.h> headersKamil Rytarowski1-1/+4
NetBSD ships with strtod_l(3) in <stdlib.h>. Having strtol_l(3) doesn't imply to have <xlocale.h>. Generalize inclusion of <locale.h> and <xlocale.h>.
2015-11-27card: Only update port's preferred profile if profile is savedDavid Henningsson1-9/+18
In case pa_card_set_profile is called with save=false, then probably it makes more sense not to update the port's preferred profile as well. Signed-off-by: David Henningsson <david.henningsson@canonical.com>
2015-11-27netbsd: NetBSD ships with paccept(2) a superset of Linux-specific accept4()Kamil Rytarowski1-0/+7
[diwic: Moved paccept to #bsd line in configure.ac]
2015-11-22card: Update preferred_profile for ports when profile changesDavid Henningsson1-0/+18
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
2015-11-22device-port: Add preferred_profile field to pa_device_portDavid Henningsson2-0/+13
Signed-off-by: David Henningsson <david.henningsson@canonical.com>