From 02cb7523f5b026552940fecd33ef6c17bb985b6d Mon Sep 17 00:00:00 2001 From: Ed Reel Date: Wed, 15 Feb 2023 19:16:09 -0600 Subject: [PATCH] Fix sommelier bugs (#7903) * Fix sommelier bugs * Add binaries * Update/cleanup deps * Rubyize date timestamp Remove unneeded return line * Cleanup build options * Fix postinstall dependency. * Fix storage of xwayland pid * Update sommelier to most recent working commit Also, fix SOMMELIER_DRM_DEVICE and etc/env.d/sommelier loading logic... * modified and rebuilt for i686 * Add postinstall line directing people to the wiki. * Add arm changes and add container workaround * move error message * Add note about upstream breakage. --------- Co-authored-by: Satadru Pramanik, DO, MPH, MEng --- packages/sommelier.rb | 171 ++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 82 deletions(-) diff --git a/packages/sommelier.rb b/packages/sommelier.rb index 94c6f454a9..ab9d8a3cea 100644 --- a/packages/sommelier.rb +++ b/packages/sommelier.rb @@ -3,46 +3,49 @@ require 'package' class Sommelier < Package description 'Sommelier works by redirecting X11 programs to the built-in ChromeOS Exo Wayland server.' homepage 'https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/vm_tools/sommelier/' - version '20221117-3' + version '20230125-1' license 'BSD-Google' compatibility 'all' source_url 'https://chromium.googlesource.com/chromiumos/platform2.git' - git_hashtag 'b63df163ab11f07b63d0e7a866f044aa07c7e0b2' + git_hashtag 'dbd90c6b002f7d0867cc0b0f1538cc979b688d13' + # The 02 Feb 2022 commit fbd707f "vm_tools: Upgrades Sommelier to support xdg_shell v3" breaks functionality for Chromebrew with the error: + # wl_registry@2: error 0: invalid version for global xdg_wm_base (41): have 1, wanted 3 binary_url({ - aarch64: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/sommelier/20221117-3_armv7l/sommelier-20221117-3-chromeos-armv7l.tar.zst', - armv7l: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/sommelier/20221117-3_armv7l/sommelier-20221117-3-chromeos-armv7l.tar.zst', - i686: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/sommelier/20221117-3_i686/sommelier-20221117-3-chromeos-i686.tar.zst', - x86_64: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/sommelier/20221117-3_x86_64/sommelier-20221117-3-chromeos-x86_64.tar.zst' + aarch64: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/sommelier/20230125-1_armv7l/sommelier-20230125-1-chromeos-armv7l.tar.zst', + armv7l: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/sommelier/20230125-1_armv7l/sommelier-20230125-1-chromeos-armv7l.tar.zst', + i686: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/sommelier/20230125-1_i686/sommelier-20230125-1-chromeos-i686.tar.zst', + x86_64: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/sommelier/20230125-1_x86_64/sommelier-20230125-1-chromeos-x86_64.tar.zst' }) binary_sha256({ - aarch64: 'bb810cb6c79ea4d3767a2f1e7f55f49318aec27b661646aabb3d6b805999a13b', - armv7l: 'bb810cb6c79ea4d3767a2f1e7f55f49318aec27b661646aabb3d6b805999a13b', - i686: '3b132883f20f85eca779a8ba91d51af5f28224ade48d3e4abfb30da8014552ff', - x86_64: '271109dc9bd10e8feded352b5bdaaf2e109082c478f7a766f24ca3ee9fb33279' + aarch64: '4a5719e1ab6cbf277a3360c2f3eb60483be474b07725d123d5cbf3426540603a', + armv7l: '4a5719e1ab6cbf277a3360c2f3eb60483be474b07725d123d5cbf3426540603a', + i686: '41df727007973520d856253a93ed85787a98d1948489502184eaba5b6d6474e9', + x86_64: 'f275bc12bb18c5af2d97c6b391de77c7fa4e293f1fcb3922f03af7ae20e4e8c0' }) - depends_on 'libdrm' - depends_on 'libxcb' + depends_on 'diffutils' # L (for diff usage in postinstall) + depends_on 'gcc' # R + depends_on 'glibc' # R + depends_on 'libdrm' # R + depends_on 'libxcb' # R depends_on 'libxcomposite' => :build depends_on 'libxcvt' depends_on 'libxfixes' => :build - depends_on 'libxkbcommon' + depends_on 'libxkbcommon' # R depends_on 'llvm' # R - depends_on 'mesa' - depends_on 'pixman' + depends_on 'mesa' # R + depends_on 'pixman' # R depends_on 'procps' # for pgrep in wrapper script depends_on 'psmisc' - depends_on 'wayland' + depends_on 'wayland' # R depends_on 'xauth' + depends_on 'xhost' # for xhost in sommelierd script depends_on 'xkbcomp' # The sommelier log complains if this isn't installed. depends_on 'xorg_xset' # for xset in wrapper script - depends_on 'xhost' # for xhost in sommelierd script depends_on 'xsetroot' # for xsetroot in /usr/local/etc/sommelierrc script - depends_on 'xwayland' + depends_on 'xwayland' # L depends_on 'xxd_standalone' # for xxd in wrapper script - depends_on 'gcc' # R - depends_on 'glibc' # R no_shrink @@ -57,24 +60,6 @@ class Sommelier < Package # ../sommelier.cc:3238:10: warning: ‘char* strncpy(char*, const char*, size_t)’ specified bound 108 equals destination size [-Wstringop-truncation] Kernel.system "sed -i 's/sizeof(addr.sun_path))/sizeof(addr.sun_path) - 1)/' sommelier.cc", chdir: 'vm_tools/sommelier' - return unless ARCH == 'armv7l' || ARCH == 'aarch64' - - # See https://github.com/chromebrew/chromebrew/pull/7653#issuecomment-1320804418 - File.write 'vm_tools/sommelier/arm.patch', <<~'ARM_PATCH_EOF' - diff -Nur a/sommelier.cc b/sommelier.cc - --- a/sommelier.cc 2022-11-06 19:29:16.580361574 +0800 - +++ b/sommelier.cc 2022-11-06 19:37:28.830367176 +0800 - @@ -616,7 +616,7 @@ - data_device_manager->host_global = - sl_data_device_manager_global_create(ctx); - } - - } else if (strcmp(interface, "xdg_wm_base") == 0) { - + } else if ((strcmp(interface, "xdg_wm_base") == 0) || (strcmp(interface, "zxdg_shell_v6") == 0)) { - struct sl_xdg_shell* xdg_shell = - static_cast(malloc(sizeof(struct sl_xdg_shell))); - assert(xdg_shell); - ARM_PATCH_EOF - Kernel.system 'patch -Np1 -i arm.patch', chdir: 'vm_tools/sommelier' end def self.build @@ -82,7 +67,7 @@ class Sommelier < Package when 'armv7l', 'aarch64' @peer_cmd_prefix = '/lib/ld-linux-armhf.so.3' when 'i686' - @peer_cmd_prefix = '/lib/ld-linux-i686.so.2' + @peer_cmd_prefix = '/lib/ld-2.23.so' when 'x86_64' @peer_cmd_prefix = '/lib64/ld-linux-x86-64.so.2' end @@ -91,7 +76,7 @@ class Sommelier < Package system <<~BUILD env CC=clang CXX=clang++ \ - meson setup #{CREW_MESON_OPTIONS} \ + meson setup #{CREW_MESON_OPTIONS.gsub('-fuse-ld=mold', '-fuse-ld=lld').gsub('-ffat-lto-objects', '')} \ -Db_asneeded=false \ -Db_lto=true \ -Db_lto_mode=thin \ @@ -117,6 +102,7 @@ class Sommelier < Package SOMMELIER_ACCELERATORS='Super_L,bracketleft,bracketright' WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/var/run/chrome + SOMMELIER_VM_IDENTIFIER=chromebrew if grep -q GenuineIntel /proc/cpuinfo ;then check_linux_version() { @@ -146,9 +132,8 @@ class Sommelier < Package esac fi - if [ -f "~/.sommelier.env" ]; then - source ~/.sommelier.env - fi + # Override environment settings above. + [ -f "~/.sommelier.env" ] && source ~/.sommelier.env set +a SOMMELIERENVEOF @@ -190,7 +175,7 @@ class Sommelier < Package File.write 'sommelierd', <<~SOMMELIERDEOF #!/bin/bash -a - source ${CREW_PREFIX}/etc/env.d/sommelier.env &>/dev/null + source ${CREW_PREFIX}/etc/env.d/sommelier set +a mkdir -p #{CREW_PREFIX}/var/{log,run} checksommelierwayland () { @@ -219,7 +204,7 @@ class Sommelier < Package pkill -F #{CREW_PREFIX}/var/run/sommelier-xwayland.pid &>/dev/null DISPLAY="${DISPLAY:0:3}" - sommelier -X \ + sommelier_cmd="sommelier -X \ --x-display=${DISPLAY} \ --scale=${SCALE} \ ${SOMMELIER_DIRECT_SCALE} \ @@ -228,37 +213,45 @@ class Sommelier < Package --display=wayland-0 \ --xwayland-path=/usr/local/bin/Xwayland \ --xwayland-gl-driver-path=#{CREW_LIB_PREFIX}/dri \ - --peer-cmd-prefix="#{CREW_PREFIX}#{@peer_cmd_prefix}" \ + --peer-cmd-prefix=#{CREW_PREFIX}#{@peer_cmd_prefix} \ --enable-xshape \ --noop-driver \ --no-exit-with-child \ - /bin/sh -c "touch ~/.Xauthority + /bin/sh -c \\"touch ~/.Xauthority xauth -f ~/.Xauthority add ${DISPLAY} . $(xxd -l 16 -p /dev/urandom) - source #{CREW_PREFIX}/etc/sommelierrc" \ - &>> #{CREW_PREFIX}/var/log/sommelier.log + source #{CREW_PREFIX}/etc/sommelierrc\\"" + echo $sommelier_cmd >> #{CREW_PREFIX}/var/log/sommelier.log + $sommelier_cmd &>> #{CREW_PREFIX}/var/log/sommelier.log - echo "${!}" > #{CREW_PREFIX}/var/run/sommelier-xwayland.pid - xhost +si:localuser:root &>/dev/null + # echo "${!}" > #{CREW_PREFIX}/var/run/sommelier-xwayland.pid + pgrep Xwayland > #{CREW_PREFIX}/var/run/sommelier-xwayland.pid + xhost +si:localuser:root fi SOMMELIERDEOF # startsommelier File.write 'startsommelier', <<~STARTSOMMELIEREOF #!/bin/bash -a + # Exit if in container. + if [[ -f '/.dockerenv' ]]; then + echo "Cannot run sommelier in a container." + # Return or exit depending upon whether script was sourced. + (return 0 2>/dev/null) && return 0 || exit 0 + fi set -a # Set DRM device here so output is visible, but don't run # some of these checks in an env.d file since we don't need # them run every time a shell is opened. # Get a list of all available DRM render nodes. - DRM_DEVICES_LIST=( /sys/class/drm/renderD* ) + DRM_DEVICES_LIST=($(cd /dev/dri/ || exit ; ls renderD*)) # if two or more render nodes available, choose one based on the corresponding render device path: # devices/platform/vegm/...: virtual GEM device provided by Chrome OS, hardware acceleration may not available on this node. (should be avoided) # devices/pci*/...: linked to the actual graphics card device path, provided by graphics card driver. (preferred) # - if [[ "${#DRM_DEVICES_LIST[@]}" > 1 ]]; then - for dev in ${DRM_DEVICES_LIST[@]}; do - if [[ "$(coreutils --coreutils-prog=readlink -f "${dev}")" =~ devices/pci ]]; then + if [[ "${#DRM_DEVICES_LIST[@]}" -gt 1 ]]; then + for dev in "${DRM_DEVICES_LIST[@]}"; do + if [[ "$(coreutils --coreutils-prog=readlink -f "/sys/class/drm/${dev}/device/driver")" =~ (bus/pci|drm) ]]; then SOMMELIER_DRM_DEVICE="/dev/dri/${dev##*/}" echo -e "\e[1;33m""${#DRM_DEVICES_LIST[@]} DRM render nodes available, ${SOMMELIER_DRM_DEVICE} will be used.""\e[0m" break @@ -268,31 +261,20 @@ class Sommelier < Package # if only one node available, use it directly SOMMELIER_DRM_DEVICE="/dev/dri/${DRM_DEVICES_LIST[0]##*/}" fi - check_chromeos_milestone() { - # Check is passed milestone is greater than the current - # ChromeOS milestone. - milestone=$1 - version_good=$(grep CHROMEOS_RELEASE_CHROME_MILESTONE /etc/lsb-release | awk 'BEGIN{ FS="="}; - { if ($2 < '"${milestone}"') { print "N"; } - else { print "Y"; } - }') - - if [ "$version_good" = "N" ]; then - return 1 - fi + direct_scaling_possible() { + # Check if milestone is greater than 105. + milestone=$(grep CHROMEOS_RELEASE_CHROME_MILESTONE /etc/lsb-release | cut -d= -f2) + (( $milestone > 105 )) && return 0 + return 1 } # Not sure which milestone enables direct scale, so be # conservative. - if ! check_chromeos_milestone 106; then - SOMMELIER_DIRECT_SCALE= - else + SOMMELIER_DIRECT_SCALE= + if direct_scaling_possible; then echo -e "\e[1;33m""Sommelier can use direct scaling.""\e[0m" SOMMELIER_DIRECT_SCALE='--direct-scale' fi - source ~/.sommelier-default.env &>/dev/null - source ~/.sommelier.env &>/dev/null - set +a checksommelierwayland () { @@ -393,22 +375,39 @@ class Sommelier < Package def self.postinstall # all tasks are done by sommelier.env now - puts - puts 'Removing old sommelier env variable loading code in ~/.bashrc'.lightblue - system 'sed -i "/[sS]ommelier/d" -i.backup ~/.bashrc' - puts 'To complete the installation, execute the following:'.orange - puts 'source ~/.bashrc'.orange + now = Time.now.strftime('%Y%m%d%H%M') + FileUtils.cp "#{HOME}/.bashrc", "#{HOME}/.bashrc.#{now}" + system "sed -i '/[sS]ommelier/d' #{HOME}/.bashrc" + diff = `diff #{HOME}/.bashrc #{HOME}/.bashrc.#{now}`.chomp + if diff == '' + FileUtils.rm "#{HOME}/.bashrc.#{now}" + else + puts <<~EOT0.lightblue + + Removed old sommelier environment variables in ~/.bashrc. + A backup of the original is stored in ~/.bashrc.#{now}. + To complete the installation, execute the following: + source ~/.bashrc + EOT0 + end - puts FileUtils.touch "#{HOME}/.sommelier.env" unless File.exist? "#{HOME}/.sommelier.env" puts <<~EOT1.lightblue - To adjust sommelier environment variables, edit #{CREW_PREFIX}/etc/env.d/sommelier - Default values are in #{CREW_PREFIX}/etc/env.d/sommelier + + The default environment is stored in #{CREW_PREFIX}/etc/env.d/sommelier. + EOT1 + + puts <<~EOT2.orange + DO NOT EDIT THIS FILE SINCE UPDATES WILL OVERWRITE YOUR CHANGES. + EOT2 + puts <<~EOT1.lightblue + To override environment variables set above, edit ~/.sommelier.env instead. + Information about those environment variables may be found on the + Chromebrew wiki: https://github.com/chromebrew/chromebrew/wiki To start the sommelier daemon, run 'startsommelier' To stop the sommelier daemon, run 'stopsommelier' To restart the sommelier daemon, run 'restartsommelier' - EOT1 puts <<~EOT2.orange Please be aware that gui applications may not work without the @@ -419,6 +418,14 @@ class Sommelier < Package (If you are upgrading from an earlier version of sommelier, also run 'restartsommelier'.) + + Please open a github issue at + https://github.com/chromebrew/chromebrew/issues/new/choose + with the output of both + readlink -f "/sys/class/drm/renderD129/device/driver" + and + readlink -f "/sys/class/drm/renderD128/device/driver" + if sommelier does not start properly on your arm ChromeOS device. EOT2 end end