Skip to content

Commit d475d20

Browse files
committed
Completed
1 parent f169b90 commit d475d20

File tree

1 file changed

+200
-6
lines changed

1 file changed

+200
-6
lines changed

doc/sphinx/how-to/how-to-enable-graphics-core22-on-a-device.md

+200-6
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ to run graphical snaps like `ubuntu-frame` or any other *Mir*-based
77
compositor in a snapped environment.
88

99
To this end, we will accomplish the following in order:
10-
- Assemble a `graphics-core22` snap
11-
- Test the assembled snap
12-
- Confirm that `ubuntu-frame` runs in your environment
10+
- How to assemble a `graphics-core22` provider snap
11+
- How to test a `graphics-core22` provider snap
12+
- How to test the confinement of your *Mir*-based snap that relies on the provider snap
1313

1414
## Prerequisites
1515
Before we get started, let's make sure that we have everything that we require.
@@ -96,7 +96,7 @@ While *Mir* can be enabled on platforms that do not support `GBM/KMS`, this
9696
requires a paltform implementation to be written in *Mir*. This work is out
9797
of the scope of this guide.
9898

99-
## Assemble a `graphics-core22` snap
99+
## How to assemble a `graphics-core22` provider snap
100100
With the prerequisites out of the way, it is time to assemble a
101101
`graphics-core22` snap.
102102

@@ -190,7 +190,9 @@ parts:
190190
- graphics/lib/*
191191
```
192192

193-
### Possible complications
193+
When you're ready, build your snap using `snapcraft`.
194+
195+
### Troubleshooting
194196
There are a number of ways the vendor drivers can differ from this simplest case, requiring different solutions.
195197
Let's explore a few of them.
196198

@@ -258,4 +260,196 @@ The [mesa-core22](https://github.com/canonical/mesa-core22/blob/main/snap/snapcr
258260
directory is shipped in a top-level `glvnd` path, under the path exported by the
259261
`graphics-core22` slot.
260262

261-
.
263+
## How to test a `graphics-core22` provider snap
264+
Now we have our `graphics-core22` provider snap built. However, we don't yet know if it works
265+
properly. Testing this snap is our next task.
266+
267+
For starters, install the [graphics-test-tools](https://snapcraft.io/graphics-test-tools) snap:
268+
269+
```shell
270+
sudo snap install graphics-test-tools --channel 22/stable
271+
```
272+
273+
Next, connect the snap that you've built to `graphics-test-tools`:
274+
275+
```shell
276+
sudo snap connect graphics-test-tools:graphics-core22 <your-snap>:graphics-core22
277+
```
278+
279+
With that installed, we can begin testing.
280+
281+
### Use `eglinfo` to test
282+
This is the most basic test that can be performed, and is a good indication of baseline GPU
283+
driver setup. This should list _at least_ a GBM platform with the expected vendor and
284+
`OpenGL_ES` client API. An abbreviated example (on a `mesa-core22` system):
285+
286+
```
287+
$ graphics-test-tools.eglinfo
288+
EGL client extensions string:
289+
EGL_EXT_device_base EGL_EXT_device_enumeration EGL_EXT_device_query
290+
EGL_EXT_platform_base EGL_KHR_client_get_all_proc_addresses
291+
EGL_EXT_client_extensions EGL_KHR_debug EGL_EXT_platform_device
292+
EGL_EXT_platform_wayland EGL_KHR_platform_wayland
293+
EGL_EXT_platform_x11 EGL_KHR_platform_x11 EGL_EXT_platform_xcb
294+
EGL_MESA_platform_gbm EGL_KHR_platform_gbm
295+
EGL_MESA_platform_surfaceless
296+
297+
298+
GBM platform:
299+
EGL API version: 1.5
300+
EGL vendor string: Mesa Project
301+
EGL version string: 1.5
302+
EGL client APIs: OpenGL OpenGL_ES
303+
EGL driver name: iris
304+
EGL extensions string:
305+
EGL_ANDROID_blob_cache EGL_ANDROID_native_fence_sync
306+
EGL_EXT_buffer_age EGL_EXT_create_context_robustness
307+
EGL_EXT_image_dma_buf_import EGL_EXT_image_dma_buf_import_modifiers
308+
EGL_IMG_context_priority EGL_KHR_cl_event2 EGL_KHR_config_attribs
309+
EGL_KHR_context_flush_control EGL_KHR_create_context
310+
EGL_KHR_create_context_no_error EGL_KHR_fence_sync
311+
EGL_KHR_get_all_proc_addresses EGL_KHR_gl_colorspace
312+
EGL_KHR_gl_renderbuffer_image EGL_KHR_gl_texture_2D_image
313+
EGL_KHR_gl_texture_3D_image EGL_KHR_gl_texture_cubemap_image
314+
EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap
315+
EGL_KHR_no_config_context EGL_KHR_reusable_sync
316+
EGL_KHR_surfaceless_context EGL_EXT_pixel_format_float
317+
EGL_KHR_wait_sync EGL_MESA_configless_context EGL_MESA_drm_image
318+
EGL_MESA_image_dma_buf_export EGL_MESA_query_driver
319+
EGL_WL_bind_wayland_display
320+
Configurations:
321+
bf lv colorbuffer dp st ms vis cav bi renderable supported
322+
id sz l r g b a th cl ns b id eat nd gl es es2 vg surfaces
323+
---------------------------------------------------------------------
324+
0x01 32 0 10 10 10 2 0 0 0 0 0x30335241-- y y y win
325+
0x02 32 0 10 10 10 2 16 0 0 0 0x30335241-- y y y win
326+
0x03 32 0 10 10 10 2 24 0 0 0 0x30335241-- y y y win
327+
0x04 32 0 10 10 10 2 24 8 0 0 0x30335241-- y y y win
328+
0x05 32 0 10 10 10 2 0 0 2 1 0x30335241-- y y y win
329+
… lots more configurations, then other platform details …
330+
```
331+
332+
If `eglinfo` does **NOT** list a GBM platform, or generates errors then you want to look
333+
at [possible complications](#possible-complications). If `eglinfo` does list a GBM platform
334+
then we can proceed to testing `ubuntu-frame`.
335+
336+
### Test if `ubuntu-frame` works
337+
First, install `ubuntu-frame`:
338+
```shell
339+
sudo snap install ubuntu-frame --devmode
340+
```
341+
342+
Next, disconnect it from the default graphics interface:
343+
```shell
344+
sudo snap disconnect ubuntu-frame:graphics-core22
345+
```
346+
347+
Then, connect it to your new provider snap:
348+
```shell
349+
sudo snap connect ubuntu-frame:graphics-core22 <your-snap>:graphics-core22
350+
```
351+
352+
Finally, run `ubuntu-frame`:
353+
```shell
354+
ubuntu-frame
355+
```
356+
357+
If everything previously has gone correctly this should result in `ubuntu-frame` coming
358+
up on the connected outputs. If not, the log messages will hopefully help identify issues.
359+
360+
## How to test the confinement of your *Mir*-based snap
361+
Once you have your `graphics-core22` provider snap setup, and you are confident that it works
362+
well, you'll want to make sure that you can run the snap that *depends on* your provider snap
363+
in a confined mode. Since we already have `ubuntu-frame` setup, we will use it as an example.
364+
However, you should be able to run these tests on any *Mir*-based snap.
365+
366+
First, let's uninstall `ubuntu-frame` if it is installed:
367+
368+
```shell
369+
sudo snap remove ubuntu-frame
370+
```
371+
372+
Next, we can install `ubuntu-frame` without the `--devmode` flag:
373+
```shell
374+
sudo snap install ubuntu-frame
375+
sudo snap disconnect ubuntu-frame:graphics-core22
376+
```
377+
378+
Finally, we will run `ubuntu-frame` like before:
379+
```shell
380+
ubuntu-frame
381+
```
382+
383+
If everything works, then `ubuntu-frame` is ready. If not, we'll have to troubleshoot.
384+
385+
### Troubleshooting
386+
When bringing up a confined ubuntu-frame snap on a new board with new drivers there are two
387+
separate access control mechanisms:
388+
- AppArmor
389+
- The devices cgroup
390+
391+
#### AppArmor
392+
The first is relatively easy to debug. When AppArmor would deny access to a resource, it outputs a nice
393+
message in `dmesg`:
394+
395+
```
396+
apparmor="DENIED" operation="open" profile="snap.ubuntu-frame.ubuntu-frame" name="/run/udev/data/c189:1" <other stuff>
397+
```
398+
399+
You can find the AppArmor profile at `/var/lib/snapd/apparmor/profiles/snap.ubuntu-frame.ubuntu-frame`.
400+
Make modifications to the profile using your favorite text editor. Finally, apply the change to replace
401+
the default confinement:
402+
403+
```shell
404+
sudo apparmor_parser -r /var/lib/snapd/apparmor/profiles/snap.ubuntu-frame.ubuntu-frame
405+
```
406+
407+
#### The devices cgroup
408+
The cgroup confinement is less easy to debug. The kernel emits no logs when the devices cgroup
409+
denies access to a device node. The device node on the filesystem will appear to have the correct
410+
permissions (and, for example, you will be able to touch it), but calls to `open()` will fail
411+
with `EPERM`. If everything seems to be set up correctly, and there are no errors in `dmesg`,
412+
but `Mir` is failing it’s likely that the devices cgroup confinement is to blame.
413+
414+
Additionally, it is more difficult to test as the cgroup is only set up during snap run startup,
415+
and so the knobs we need to twiddle only exist while the snap is running.
416+
417+
We can get around this by running:
418+
```shell
419+
snap run --shell ubuntu-frame
420+
```
421+
This command will get snapd to do all the initialisation and drop us into a shell.
422+
Once the shell exists, there will be two(?!) cgroup folders found under `/sys/fs/cgroup/devices`:
423+
1. /sys/fs/cgroup/devices/system.slice/snap.ubuntu-frame.ubuntu-frame.${UUID}.scope, and
424+
2. /sys/fs/cgroup/devices/snap.ubuntu-frame.ubuntu-frame
425+
426+
It is (2) that we’re after. You can check that you’ve got the right directory, because the
427+
`devices.list` file will contain a bunch of lines like:
428+
429+
```
430+
c 5:1 rwm
431+
c 5:2 rwm
432+
c 136:* rwm
433+
c 137:* rwm
434+
c 138:* rwm
435+
```
436+
437+
You now need to give the cgroup permission to access the necessary devices, for which you need
438+
the `major:minor` of the device nodes. You can find that with ls:
439+
```
440+
$ ls -la /sys/fs/cgroup/devices/snap.ubuntu-frame.ubuntu-frame
441+
crw-rw-rw- 1 root root 10, 60 Jan 10 04:56 /dev/mali0
442+
```
443+
444+
Here we see that the `/dev/mali0` device node has `major:minor` equal to `10:60`.
445+
446+
Now we can enable access to the relevant device node, via:
447+
```shell
448+
echo "c 10:60 rw" | sudo tee /sys/fs/cgroup/devices/snap.ubuntu-frame.ubuntu-frame/devices.allow
449+
```
450+
451+
And now we can go back to the shell, and try running `ubuntu-frame`:
452+
453+
```shell
454+
$SNAP/usr/local/bin/frame
455+
```

0 commit comments

Comments
 (0)