rockowitz / ddcutil

Control monitor settings using DDC/CI and USB
http://www.ddcutil.com
GNU General Public License v2.0
946 stars 38 forks source link

Docker support #249

Open ndandanov opened 2 years ago

ndandanov commented 2 years ago

Hi and thank you for the great work! Is it possible to use ddcutil from within a Docker container?

I tried to build one using the following simple Dockerfile:

FROM debian

RUN apt-get update && \
    apt-get install -y ddcutil && \
    rm -rf /var/lib/apt/lists/* && \
    rm -rf ~/.cache/*

with docker build -t ddcutil:v0.0.1. I then ran the container with docker run -it --name ddcutil ddcutil:v0.0.1.

But whenever I run ddcutil, the result is a segfault:

root@hash:/# ddcutil detect
Segmentation fault (core dumped)

This use case is for those who do not have any administrative rights to install new packages (even dependencies for building ddcutil), but have rights to run Docker containers.

Thanks!

rockowitz commented 2 years ago

It should be possible to build and run ddcutil in a docker image. Whether it can do anything useful is another question. I have not used docker. It appears that it is possible to access the actual i2c devices within docker. See e.g. this post.

I suggest using i2cdetect in package i2c-tools to see if you can access the monitor on one of the I2C devices. It will show slave address x50 as active if the EDID is accessible, and slave address x37 as active if DDC communication is possible.

You do not indicate which version of ddcutil you are running. The one in debian stable (bullseye), 0.9.9, is very old. You want to be running the one in test (bookwork) or unstable (sid), which is ddcutil 1.2.1.

If 1.2.1 exhibits the segfault, please execute the following command as root within the container and submit the output (which will voluminous) as an attachment of some sort, NOT in the body of a post.

# valgrind ddcutil detect --trace all 
ndandanov commented 2 years ago

Thank you, @rockowitz!

It seems like the issue indeed was related to ddcutil's version which was:

root@41f973751ea0:/# ddcutil  --version
ddcutil 0.9.9
Built without support for AMD Display Library (AMD proprietary driver).
Built with support for USB connected displays.
Built without function failure simulation.
Built with libdrm services.

Copyright (C) 2015-2020 Sanford Rockowitz
License GPLv2: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

I built a new image based on Arch Linux using the following simple Dockerfile:

FROM archlinux:latest

RUN pacman --noconfirm -Syu && \
    pacman --noconfirm -S ddcutil && \
    rm -rf ~/.cache/*

I then ran the container and also mapped all i2c devices (otherwise, these were not available in the container):

docker run $(for dev in `ls /dev/i2c*`; do echo "--device $dev "; done) -it --name ddcutil ddcutil:v0.0.1

The version is now:

[root@bd92d8bf5186 /]# ddcutil --version
ddcutil[58]: Starting.  ddcutil version 1.2.1
ddcutil 1.2.1
Built with support for USB connected displays.
Built without function failure simulation.
Built with libdrm services.

Copyright (C) 2015-2021 Sanford Rockowitz
License GPLv2: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

And so far, it seems to work correctly (at least for setting up display brightness).

Many thanks once again! I think this issue can be closed now :)

rockowitz commented 2 years ago

I'm glad to hear that ddcutil works in a container and it's so easy to configure. Can I ask you to execute ddcutil environment --verbose and submit the output as an attachment? The output will be interesting to study, and the command itself exercises ddcutil extensively.

rockowitz commented 2 years ago

I've added a FAQ entry on the web site describing your success. Let me know if it should be changed in any way.

ndandanov commented 2 years ago

Many thanks, @rockowitz! I think the FAQ entry is good. Perhaps I would add the following just before I then ran the container:

Saved this to a file named Dockerfile and built a Docker image using docker build -t ddcutil:v0.0.1 ..

Here is the output of ddcutil environment --verbose invoked from within the Docker container: https://pastebin.com/G3BuvNVf

I have hidden some of the values (serial numbers, UUID of the root partition). If you need them, please tell.

It is strange that there is one Invalid display in the status. The monitor configuration uses DisplayPort daisy chaining and is as follows:

                             +-------------------+
                             |                   |
+----------------+           |                   |
|                |DP    DP in|                   |
|  Lenovo T440p  +----------->     DELL U2414H   |
|                |           |                   |
+----------------+           |                   |
                             +---------+---------+
                                       | DP out
                                       |
                                       |
                                       | DP in
                             +---------v---------+
                             |                   |
                             |                   |
                             |                   |
                             |     DELL U3219Q   |
                             |                   |
                             |                   |
                             +-------------------+

Also, is it normal that after executing ddcutil environment --verbose, my laptop display has thin red vertical lines 3 millimeters apart from one another? It seems to get back to normal after rebooting the computer. I don't remember this hapenning after executing ddcutil outside Docker, but will check.

rockowitz commented 2 years ago

I2C communication with Multi Stream Transport connected displays (daisy chain, docking station) is, in a word, problematic. See the section Docking station connected displays from the ddcutil 1.1.0 release notes, and the issues labelled "Docking Station" or "MST" here.

Before I say more, please execute ddcutil detect --very-verbose --trcfunc is_phantom_display and submit the output as an attachment. (--very-verbose is an undocumented message level whose meaning is subject to change.)

Re the red lines, it would be hard to say what is triggering them without hacking the code to isolate the cause. The environment command does a lot of low level poking around, but except for I2C it's all read only. Since the red lines only occur with the environment command and can be resolved by rebooting I'm just going to regard it as a peculiar side-effect of executing in docker.

ndandanov commented 2 years ago

Thank you, I see that MST could be problematic. I am using my Lenovo T440p through a Lenovo Ultra Dock which could possibly also lead to complications.

Here is the output of ddcutil detect --very-verbose --trcfunc is_phantom_display: https://pastebin.com/SU1E1Q7n

The good thing about the red lines is that they are not persistent so it is not a significant issue. They do not appear in the regular use of ddcutil - to control brightness, for example.

rockowitz commented 2 years ago

@ndandanov

Fascinating!

The display at /dev/i2c-9 and /dev/i2c-10 (your Dell U2424H) where not considered the same monitor because the EDIDs are not identical! They differ in the display type bits of byte 24, with one indicating RGB 4:4:4, the other RGB 4:4:4 + YCrCb 4:2;2! What's more these bits are only set for EDID version 1.4, which is why the difference was not revealed in earlier testing! Apparently some driver is performing fixup on these bits.

Function is_phantom_display() in branch 1.2.3-dev has been altered so that instead of comparing the entire 128 byte EDIDs, only the manufacturer id, model name, product code, binary serial number and character string "serial number" are checked. When you have a chance, please build from branch 1.2.3-dev and rerun ddcutil detect --very-verbose --trcfunc is_phantom_display. Thanks.