VRChatをLinux (Fedora 43)で動作させるのに手こずった話
LinuxでVRChatを実行していたが、ホームワールドに設定していたkotatsumuriワールドのYamaPlayerが動作しないことが分かった。
これは軽く調べるとproton-ge-rtspを利用すれば良いということが分かったので、インストールしてみた。
proton-ge-rtspについては https://note.com/ced0180/n/n5e5c429ba674 や 本家リポジトリ https://github.com/SpookySkeletons/proton-ge-rtsp を参照のこと
https://github.com/SpookySkeletons/proton-ge-rtsp を利用してYamaPlayerに対応させようとしたら、今度はVRChat自体が起動しなくなった。
このためgithub copilotの支援をもらいトラブルシューティングを行った。
用語
DXVK
Windowsゲームが使うDirect3Dの命令をLinuxのVulkanで動くように変換するソフトウェア。
ICD
Installable Client Driverの略。vulkanが利用するGPUによって利用するドライバを差し替えることが可能になる仕組み。
VulkanはICDファイル(jsonファイル: /usr/share/vulkan/icd.d/nvidia_icd.x86_64.jsonなどに配置 )を読み込むことでドライバの実体をロードしている。
結論から書くと
Proton(DXVK/Vulkan)起動時に Intel iGPU の Vulkan ICD が"なぜか"選択され、Swapchain 作成が"なぜか"失敗してゲームが落ちるということだった。
この2つの"なぜか"の点については調べ途中。
まあ要するにNVIDIA ICDを指定することで解決したというつまらない話だった。
が、せっかくcopilotとやりとりして知見が深まったのでひとまず記録に残すためブログに記していく。
生じていた事象について
VRChatをデフォルトの設定(PROTON_LOG=1を起動オプション二追加)で起動すると、
Failed to create Vulkan swapchain: VK_ERROR_INITIALIZATION_FAILEDというエラーログが生じて画面が真っ白の状態になっていた。
Text
err: Presenter: Failed to create Vulkan swapchain: VK_ERROR_INITIALIZATION_FAILED info: Presenter: Actual swapchain properties: info: Format: VK_FORMAT_B8G8R8A8_UNORM info: Color space: VK_COLOR_SPACE_SRGB_NONLINEAR_KHR info: Present mode: VK_PRESENT_MODE_IMMEDIATE_KHR (dynamic: yes) info: Buffer size: 1920x1080 info: Image count: 4
ちなみに、ここで起動オプションにPROTON_USE_WINED3D=1 %command%を追加するとゲームは起動する。
単にゲームを動かす状態にしたいのであればこれで終了で構わないが、もう少し掘り下げることにした。
調査にあたり取得した情報
1) Proton / DXVK の詳細ログ取得
- 追加した起動オプション:
PROTON_LOG=1 DXVK_LOG_LEVEL=info %command%
- 目的:
- 「どの Vulkan デバイスが選ばれているか」「どこで落ちるか」をログで確認
- 得られた情報:
Found device: Intel...が出ており Intel iGPU が選ばれていた
2) NVIDIA ICD の強制(最初の試行)
- 追加した起動オプション:
VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.x86_64.json PROTON_LOG=1 DXVK_LOG_LEVEL=info %command%
- 目的:
- Vulkan ICD を NVIDIA に固定して Intel を回避
- 結果:
- 逆に ゲームが即落ち、
Found device:すら出ない(Vulkan 初期化のさらに手前で失敗)
- 逆に ゲームが即落ち、
3) Vulkan loader の挙動確認(原因特定の決め手)
- 追加した起動オプション:
VK_LOADER_DEBUG=all ... %command%(上の ICD 固定と併用)
- 目的:
- Vulkan loader が「どのドライバ(ICD)を読み、なぜ無視/失敗しているか」を確定
- 得られた決定的ログ:
VK_ICD_FILENAMESで指定したnvidia_icd.x86_64.jsonが VK_LOADER_DRIVERS_SELECT により “選択されていない” として無視され、- 結果的に
vkCreateInstance: Found no drivers!になっていた
Text
[Vulkan Loader] WARNING | DRIVER: Driver "nvidia_icd.x86_64.json" ignored because not selected by env var 'VK_LOADER_DRIVERS_SELECT' [Vulkan Loader] ERROR | DRIVER: vkCreateInstance: Found no drivers!
4) 解決策(Steam起動オプションでNVIDIAドライバを選択)
- 追加した起動オプション(解決):
VK_LOADER_DRIVERS_SELECT=nvidia_icd.x86_64.json VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.x86_64.json PROTON_LOG=1 DXVK_LOG_LEVEL=info %command%
- 結果:
- ゲームが起動
YamaPlayerで動画が再生されることを確認

結論
- Steam/Proton 実行環境では Vulkan loader 側で
VK_LOADER_DRIVERS_SELECTによるドライバ選別が働いており、これにより NVIDIA の ICD が選ばれない状況が発生していた。- そのため DXVK は Intel iGPU を使ってしまいswapchain 作成に失敗して落ちた??
ここでIntel GPUだとなぜ落ちるのかはまだ腑に落ちていない。
が、おそらくモニター自体はNVIDIAグラボから出ているのに、Vulkanの描画ドライバとしてIntelのドライバが選ばれた結果モニター側に描画されず画面が真っ白という状態になっていたのだと思われる。
VK_LOADER_DRIVERS_SELECTとVK_ICD_FILENAMESを明示して NVIDIA ICD を選択させることで、Vulkan/DXVK 経路が正常化し起動できた。
Stream Deckでswitchbotをいじりたかったので操作するためのサーバを実装してみた
Stream Deck購入
少し前にStream Deckというものを購入した。
社内SNSでこれを使って遊んでる人のつぶやき記事を見つけたので、クレカのポイントも余ってるので購入してみた。
買ったのはElgato Stream Deck Neoというもの。
Stream Deckとしてはかなり小型の部類で安価なので、ちょっとしたおもちゃとして遊ぶのはちょうどよい。
購入してからDiscordのミュート解除とか、音量調整とかで利用しており、かなり便利に利用している。
ページ機能があり、1ページ1ページでボタンの操作対象を変更することができる。
例えば1ページ目ではDiscord操作用ボタンとして機能し、2ページ目では音量、再生等操作の方に切り替わるといった具合だ。


Switchbot pluginにおける問題点
さて、このようにボタンで操作できると便利になるものはほかにもあって、それが我が家の場合はswitchbotでの照明操作、エアコン操作となる。
どうやら同じように考えていた同志がいたらしく、Stream Deck Plugin StoreにはSwitchbot用のプラグインがあった。
https://marketplace.elgato.com/product/switchbot-b0f7f3c2-9a44-448c-bdf1-a00ae99f68ff
しかし、悲しいことにSwitchBot APIの認証トークンの処理が変更され、本プラグインは動作しなくなっていた。
Switchbot APIの認証関係の変更箇所は以下を参照すること。
ざっくり説明すると今まではトークンと秘密鍵さえあればよかったが、今はそれらをもとに認証に必要な情報 (nonce) を生成してSwitchbot APIにリクエストを送って検証してもらう必要がある。
GitHub - OpenWonderLabs/SwitchBotAPI: SwitchBot Open API Documents
このような変更のせいで旧APIにしか対応してないプラグインでは動作しなくなっている。
対応方針
Stream DeckにはAPI Ninjaというpluginがあり、これでGET, POST, PUT, DELETEというようなリクエストを投げることができる。
このため何かしらのREST APIを持つサーバを作成して、そこに対してリクエストを投げると、Switchbot APIに操作を中継するというふうにすればよい。
https://marketplace.elgato.com/product/api-ninja-fd59edeb-e7e5-412f-91ef-304c3e03f035
認証トークン取得方法は上記リンク先に取得方法のコードがあるのでそれに基づいて取得する。
成果物
ということでできたのが以下のプログラム。
自宅にKubernetesがあるのでそれの上で動くようにhelm chart等に固めたり、トークン系はHashicorp Vault上から取得するようにとじゃっかん特殊なことをやっているが、バイナリをビルドして必要な環境変数を設定さえすればKubernetesがなくても簡単に動かすことができる。
ローカルでの動かし方はhttps://github.com/ABC10946/switchbot-middleware/tree/main/app/exampleを参照してほしい。
Kubernetes上のConfigMapで操作対象や操作するためのAPIを変更したかったためyamlファイルで設定をできるようにしている。
以下のように設定するとexample.com/light/turnonとするとライトが点灯するように設定できる。
独自操作としてtoggleというものを実装したが、これはこのAPIを叩くとOn, Off切り替えをしてくれるというもの。
ボタン一つでOn, Offさせたいというときに重宝するだろうということで実装してある。
switchbot-configuration: - name: "light-turnon" path: "/light/turnon" type: "turnOn" deviceIds: - "01-202304012328-87495896" - name: "light-turnoff" path: "/light/turnoff" type: "turnOff" deviceIds: - "01-202304012328-87495896" - name: "light-toggle" path: "/light/toggle" type: "toggle" deviceIds: - "01-202304012328-87495896" - name: allon path: "/all/turnon" type: "turnOn" deviceIds: - "01-202210180121-38128280" - "01-202304012328-87495896" - "70041D7EEE6A" - name: alloff path: "/all/turnoff" type: "turnOff" deviceIds: - "01-202210180121-38128280" - "01-202304012328-87495896" - "70041D7EEE6A" - name: aircon-toggle path: "/aircon/toggle" type: "toggle" deviceIds: - "01-202210180121-38128280"
操作している動画は以下
分かりづらいが部屋のライトが点灯したり、消灯したりしているのが見える。
gRPC学習レポート new-learning-1
1週間(2024/09/22 ~ 2024/09/29):gRPCについて学習したのでそのレポート的なものを記述する。
参考文献
スターティングgRPC | インプレス NextPublishing
gRPCとは?
RPC (Remote Procedure Call)を実現するための実装の一つ。googleが開発した。
RPCとは
リモートの機能を呼び出すための技術。似たようなものにRESTなどが挙げられる。
RESTとの違い
- HTTP/2による高速通信
- バイナリによる通信のため通信帯域が少なめ
- ストリーミング通信
- インターセプタによるgRPCのメイン処理前後への処理埋め込み (認証や入力検証に用いる)
利用手順
protocol buffers スキーマファイルの作成 (RESTでいうところのopenapiと似たようなものという認識)
各サーバ、クライアントの実装
protocol buffersスキーマファイルをまず作成、これをコンパイルすることで各サーバ、クライアント用のライブラリが作成される。
実装
ひとまずシンプルにクライアント、サーバを作ってクライアントからサーバ側にある関数を呼び出すことができるか確認をする。
そのためのシナリオとして以下のようなものを検討。
サーバ側で検索用関数を実装、クライアント側からその関数を呼び出してデータベースを検索し結果を取得する。データベースには名前、年齢、メールアドレスが記載されているということにする。
データベースと記載したが本記事では文字列である名前をキーにして詳細な情報が入っているmap[string]Personという型の変数をデータの参照元とする。
Personは以下のような型 (goのPerson型作成はprotocが自動的に行うためわざわざこの型を用意する必要はない。)
type Person struct { Name string Age int32 Email string }
実装したサンプルは以下のリポジトリを参照のこと。
記事投稿当時のcommitへのリンク
https://github.com/ABC10946/grpc-learning/tree/d3111a1297c23c2f401f0837bd5401579f94d565
スキーマ作成
まずはスキーマを作成する。
SearchでSearchRequestを飛ばすとSearchResponseが返ってくるサービスを作成。
SearchRequestには文字列型query、SearchResponseにはプロフィール情報が入るPerson型と発見したか否かを示すbool型変数が定義される。
ここで注意したいことは、このprotobufファイルで記述したものは単なるインターフェイスに過ぎないというもので、このインターフェイスをやり取りするためのライブラリがprotocにより自動生成される。
実際に行いたい処理は人間が実装していく必要がある。(例えばここではSearch関数を実装する必要がある。)
syntax = "proto3";
option go_package = "gen/api";
package simple.maker;
service SimpleSearchService {
rpc Search(SearchRequest) returns (SearchResponse) {};
}
message SearchRequest {
string query = 1;
}
message SearchResponse {
bool is_found = 1;
Person person = 2;
}
message Person {
string name = 1;
int32 age = 2;
string email = 3;
}
コンパイル
protoc --proto_path=. --go_out=. proto/simple.proto --go-grpc_out=.
サーバの実装
重要な部分のみを抜粋したコードが以下。
api.RegisterSimpleSearchServiceServer(s, &server{})でserverという構造体を指定しており、このserver構造体にSearch関数を実装している。
Register.*ServiceServerというものがprotocにより自動生成された関数であり、これの第二引数にはSearch関数がある構造体のinterfaceが指定されている。
このSearch関数こそが今回RPCされる対象の関数である。
このSearch関数自体もinterfaceのみ自動生成されており、これを満たすように内部を実装していく。
今回はSearchRequestを受け取ってそこからqueryを取得、そのquery文字列をキーにmap[string]Personから該当の人間のプロフィールを検索するというふうに実装する。
もちろんインターフェイス以外は、内部実装は自由にいじれるので他PostgreSQLなどとやりとりするORMを利用しても良い。
func (s *server) Search(ctx context.Context, req *api.SearchRequest) (*api.SearchResponse, error) { query := req.GetQuery() log.Printf("Query: %s", query) if data[query].Name != "" { person := data[query] return &api.SearchResponse{Person: &person, IsFound: true}, nil } return &api.SearchResponse{IsFound: false}, nil } func main() { port := 50051 lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() api.RegisterSimpleSearchServiceServer(s, &server{}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }
クライアントの実装
クライアント側ではgrpcのclientを初期化すればSearch関数を呼び出すことができる。
まるで別のライブラリを呼び出しているかのようにリモートサーバ上にある関数を呼び出すことができる。
func main() { flag.Parse() conn, err := grpc.NewClient("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { log.Fatalf("failed to connect: %v", err) } defer conn.Close() c := api.NewSimpleSearchServiceClient(conn) r, err := c.Search(context.Background(), &api.SearchRequest{Query: *name}) if err != nil { log.Fatalf("failed to search: %v", err) } if r.GetIsFound() { log.Printf("Person found: %v", r.GetPerson()) return } else { log.Printf("Person not found") return } }
実行結果
実行してみるとjohnというユーザを検索してそのレスポンスが返ってくることが確認できる。
$ https://github.com/ABC10946/grpc-learning $ cd grpc-learning/simple $ cd server $ go run . -------別ターミナル $ cd grpc-learning/simple $ cd client $ go run . 2024/09/29 13:22:14 Person found: name:"john" age:20 email:"john@local" $ go run . -name jane 2024/09/29 13:22:18 Person found: name:"jane" age:20 email:"jane@local"
calicoの設定はサボるな
TL;DR
NetworkManagerとの競合を防ぐためNetworkManagerで一部インターフェイスはマネジメントしないように設定する。
calico daemonsetsのIP_AUTODETECTION_METHODをfirst-foundからcidrsに切り替えることでちゃんと通信先のNICを指定する。
タイトルの通り。
kubernetesクラスタを構築する際にcalicoの設定をサボった結果あとから痛い目に遭遇したのでそれの共有でもしていきます。
我が家のkubernetesはCNIにcalicoを使っており、特別な設定をせずにQuick Startそのまんまでデプロイしていた。
しばらくはそれでPodにちゃんとIPアドレスが割り当てられていたし、Ingressを設定しても問題なく疎通があった。
さて、しばらくはそんな感じでいくつかのPodを上げては壊しを繰り返しいろいろ実験していました。
そうするとやはりというかなんというか、リソース不足に陥るわけです。
特にメモリが不足しており、OOM Killが走り他のノードに割り当て直されそこでもOOM Killが走り・・・ということが起きていました。
というわけで普段踏み台としてしか使っていないそれなりにスペックのあるミニPCと普段はゲームくらいでしか酷使されないメインマシンをKubernetesクラスタに突っ込んでしまうことにしました。
普段踏み台とかメインとして使っているホストをKubernetesのノードとして動かす試みというのはあまりないわけですので、まあいろいろ面倒は出てきます。
その最たる例はcalicoでした。
calicoはCNI Container Network Interface Pluginと呼ばれるものでコンテナ間のネットワークを司るKubernetesのネットワークプラグインです。
このcalicoが例の新しく追加しようとしたノード上ではうまく動きませんでした。
その原因は以下2つです。
NetworkManagerとの競合
Interfaceの疎通不可能NICを自動選択したことによる疎通不可能状態
NetworkManagerとの競合
これはかなり有名なお話のようでcalicoの公式ドキュメントのTrouble Shootingのところに記載あるのでこちらを参照してもらえればなと思います。
https://docs.tigera.io/calico/latest/operations/troubleshoot/troubleshooting
NetworkManagerがcalicoのルーティングテーブルと競合した結果、calicoのルーティングの方を優先させようとしたと思われますがデフォルトゲートウェイのmetricがものすごい大きい数が割り当てられており、あらゆる通信がcalicoの方に流れるという問題が生じました。
その結果ホスト自体の通信が落ちてしまいSSHもつながらないとひどい状態に陥りました。
というわけで、そうならないようにNetworkManager側にはそれを是正するような設定を記載しました。
[keyfile] unmanaged-devices=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:vxlan-v6.calico;interface-name:wireguard.cali;interface-name:wg-v6.cali
ひとまずNetworkManager関連の競合問題はこれで解決しました。
Interfaceの疎通不可能NICを自動選択したことによる疎通不可能状態
こちらは仕事の忙しさも相まってかなり長い期間悩まされてきましたが、昨日ようやく解決に至ったのでご報告いたします。
この問題はまず最初稀にIngressの疎通ができないな〜という問題から始まりました。
そのときは稀に通信ができない程度だったのでDNSが原因だろうかとcorednsの設定を見たりなんやらしていた記憶があります。
Pod自体の問題かとか、Serviceリソースの設定がなにかおかしいのかとかかなり的外れなことを調べていましたが、
なんだかんだいろいろ試していくうちに新しく追加したミニPCとメインマシンへのPodのみ通信ができなくなるということが分かりました。
その頃は、まあいろいろあって一部システムを止めていたこともあったので一旦ノードをcordonしてどう解決していこうか検討していこうということでお茶を濁しました。
その結果、いろいろ仕事が忙しかったり、なんか6月病みたいなものになって休日も何もできない日々がずーっと続いていたので放置していました。
k8s自体も放置していましたし、まだモニタリングシステムもなんの整備もしていないのでアラートが鳴るということもなかったわけです。
そうこう過ごしてるうちに、またおうちk8sをいじりたいという気持ちが昂ぶり、さあいじるか〜 -> あれリソース足らねえ -> あ、cordonしてたわ〜と長い間放置していた前の記憶を掘り起こし、重い腰上げて根本原因調査するか〜とはじめました。
お仕事でもKubernetesクラスタのメンテナンスや障害対応をしていたため、だいぶ見るべきところが見えてきて数ヶ月前になんとな〜く公式ドキュメント通りにデプロイしたcalicoが怪しいな〜とたどりつきました。
見てみると、なんと一部ホストでcalico-node-***というPodがちゃんと動いていないと
$ k get pods -n calico-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-558b7d9cf4-rslz8 1/1 Running 313 (22h ago) 227d calico-node-28xr4 1/1 Running 23 (7h2m ago) 227d calico-node-45xkr 1/1 Running 0 10d calico-node-5qrz5 1/1 Running 16 (10d ago) 226d calico-node-6xjgq 1/1 Running 0 10d calico-node-fkf9d 1/1 Running 16 (10d ago) 227d calico-node-k62hq 1/1 Running 22 (8d ago) 76d calico-node-nnjkr 1/1 Running 25 (44d ago) 227d calico-node-smxkd 0/1 Running 0 38m calico-node-snq2d 1/1 Running 25 227d calico-typha-996fb9cc7-fgtms 1/1 Running 21 (44d ago) 227d calico-typha-996fb9cc7-m8ftm 1/1 Running 27 (10d ago) 227d calico-typha-996fb9cc7-tdg8k 1/1 Running 20 (44d ago) 227d csi-node-driver-4c62z 2/2 Running 42 (8d ago) 81d csi-node-driver-6blck 2/2 Running 26 (44d ago) 227d csi-node-driver-7rqxd 2/2 Running 0 10d csi-node-driver-cnzcp 2/2 Running 32 (10d ago) 226d csi-node-driver-d5mss 2/2 Running 27 (44d ago) 227d csi-node-driver-fldqr 2/2 Running 0 38d csi-node-driver-s2jpt 2/2 Running 32 (10d ago) 227d csi-node-driver-t6f4z 2/2 Running 0 10d csi-node-driver-xd8vc 2/2 Running 26 (44d ago) 227d
で、そのPodをdescribeしてみるとなーんかBIRDのconnectionがうまくいってないことが分かります。
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 41m default-scheduler Successfully assigned calico-system/calico-node-smxkd to einsteinium Normal Pulled 41m kubelet Container image "docker.io/calico/pod2daemon-flexvol:v3.26.1" already present on machine Normal Created 41m kubelet Created container flexvol-driver Normal Started 41m kubelet Started container flexvol-driver Normal Pulled 41m kubelet Container image "docker.io/calico/cni:v3.26.1" already present on machine Normal Created 41m kubelet Created container install-cni Normal Started 41m kubelet Started container install-cni Normal Pulled 41m kubelet Container image "docker.io/calico/node:v3.26.1" already present on machine Normal Created 41m kubelet Created container calico-node Normal Started 41m kubelet Started container calico-node Warning Unhealthy 41m kubelet Readiness probe failed: calico/node is not ready: BIRD is not ready: Error querying BIRD: unable to connect to BIRDv4 socket: dial unix /var/run/calico/bird.ctl: connect: connection refused W0626 11:17:59.370689 24 feature_gate.go:241] Setting GA feature gate ServiceInternalTrafficPolicy=true. It will be removed in a future release. Warning Unhealthy 41m kubelet Readiness probe failed: calico/node is not ready: BIRD is not ready: Error querying BIRD: unable to connect to BIRDv4 socket: dial unix /var/run/calico/bird.ctl: connect: connection refused W0626 11:18:00.347606 62 feature_gate.go:241] Setting GA feature gate ServiceInternalTrafficPolicy=true. It will be removed in a future release. Warning Unhealthy 41m kubelet Readiness probe failed: 2024-06-26 11:18:07.119 [INFO][365] confd/health.go 180: Number of node(s) with BGP peering established = 0
さて、ここでまずはこのBIRDが使うであろうポート179が空いてるかなぁと見ていきますが案の定繋がりはするわけです。
https://docs.tigera.io/calico/latest/getting-started/kubernetes/requirements
$ curl *****:179 つながりはするけどホストのサービス側(calico)から落とされる $ telnet *****:179 上と同様
となると179ポート自体は閉じていない。
もちろんufw自体も停止しているので阻むものは何もありませんでした。
そうこうして調べていくうちに以下のstackoverflowにたどり着き、どうやらIP_AUTODETECTION_METHODを設定する必要があるということが分かりました。
jenkins - Kubernetes - Calico-Nodes 0/1 Ready - Stack Overflow
で、calicoインストール時にデプロイしたオペレータのコードを見ていくとnodeAddressAutoDetectionV4には他にもいくつか設定できる項目があり、その中にCIDRを設定できるということが分かりました。
https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/tigera-operator.yaml
お、これは勝利の予感。
というわけでcalicoのDaemonSetのnodeAddressAutoDetectionV4をホスト間通信用のNICが使っているCIDRにしてデプロイし直してようやく解決しました。
gnome-terminalのレスポンスが非常に遅くなる問題への対処方法
gnome-terminalのレスポンスが遅くなる問題にここ2ヶ月くらい悩まされていましたが、それがようやく解決できたので共有程度に記事を書きました。
issueやコミュニティフォーラムなどを調査すると、NVIDIAグラフィックボードが搭載されたPC上でUbuntu 22.04を動かしかつWindow ManagerにMutterを使っている場合に生じるということが分かりました。
https://askubuntu.com/questions/1509058/input-delay-on-terminal-ubuntu-22-04-4
原因
mutterのSyncオブジェクトの実装が不足していたようです。
journalctlでブートID 0のログを参照してみるとMetaSyncRingのアラートが出ていることが分かります。
$ journalctl -b0 | grep MetaSyncRing May 26 03:31:34 oxygen gnome-shell[293854]: Window manager warning: MetaSyncRing: Sync object is not ready -- were events handled properly?
ソースコードの変更部分を見るとmeta_sync_ring_insert_waitという関数内でring->current_sync->stateがMETA_SYNC_STATE_READYでない場合はwarningを出し、meta_sync_ring_rebootをかけています。
おそらくこのmeta_sync_ring_rebootで最インスタンス化などをしており、そのせいでレスポンスが遅くなっていたと思われます。
今回の変更ではMETA_SYNC_STATE_WAITINGの場合、gpu_fenceというものを0にしてMETA_SYNC_STATE_READYをstateに入れ込んでいますが、ここらへんは追いきれていないです。
(gpu_fenceとかはなんだろうカーネルとかx11の実装とかを見ておけばよいのでしょうか?)
gpu_fenceについてはあまりよく分かりませんでしたが、とにかくこれが原因で、すでに修正コミットがMutterのメインブランチにマージされていますのでリリースを気長に待ちましょう。
といってもUbuntuの公式リポジトリに入るのはだいぶ先ですので、この不具合の修正コミットをあてたmutterを開発者の方がPPAで公開(https://bugs.launchpad.net/ubuntu/+source/mutter/+bug/2059847/comments/25)しているのでこちらをインストールして凌ぐことにしましょう。
対処方法
sudo add-apt-repository ppa:vanvugt/mutter sudo apt update sudo apt upgrade sudo apt-get install gir1.2-mutter-10=42.9-0ubuntu7vv1 mutter-common=42.9-0ubuntu7vv1 libmutter-10-0=42.9-0ubuntu7vv1
一部コンポーネントは古いバージョンのものとなっているため、apt updateで更新されてしまいます。
このため以下のコマンドで更新を抑制しておきます。
sudo apt-mark hold gir1.2-mutter-10 libmutter-10-0 mutter-common
DeepCool AK620-DIGITALとAORUS ELITE AX-WのLED周りをUbuntu上でいい感じにする方法
メインマシンを新しくしたのでUbuntuをインストールした。
その際にできればLED周りをWindowsと同様に設定したいと思いゴニョゴニョ調べたら出てきたのでやってみた。
GitHub - raghulkrishna/deepcool-ak620-digital-linux
DeepCool AK620-DIGITAL
参考リンクのdeepcool-ak620-digital-linuxを使う。
中身は単純にPythonスクリプトとsystemd用のserviceファイル、あとインストール用のスクリプトが入っている。
Pythonスクリプトの中身を見るとCPUの温度、使用率を取得してハードウェアにwriteしているだけのように見える。
インストール用スクリプトで書かれているインストール先がなんか気持ち悪いので変更。
以下フォークリポジトリにpushした。
動作する。
マザボ(AORUS ELITE AX-W)のLED
これはOpenRGBを使う。
普通に入れようとするといらないudevルールも入るのでlsusbで該当のデバイスのベンダーID、プロダクトIDを取得して、そのudevルールを抽出。
これを/etc/udev/rules.d/60-openrgb.rulesに入れ込む。
AppImageを起動すると普通に使えるのでよしなに設定する。
devcontainerでssh-addやgit configが引っ張ってこれない問題 on WSL2 windows11
自分は普段wsl2上で作業しているのですが、会社の先輩からdevcontainerはいいぞと教えていただいたので試してみました。
しかし、git pushはおろかgit commitすらもできない状況で困っていました。
結論は、wsl2上のssh-agentやgit configを引っ張ってくるにはdevcontainerの設定をしないといけないということでした。
- Dev>Containers:Execute In WSLを有効化
- Dev>Containers:Execute In WSLDistroでディストリビューションを指定します。

これでOKです。