openSUSEデスクトップ環境設定Etc

久しぶりにopenSUSEのほうをいじったら動かなくなったので色々動かなくなっていたので設定し直した時の備忘録

KDEでIBusが起動しない

~/.config/autostart/にibus-autostart.desktopなどで以下を作成

[Desktop Entry]
Comment[ja_JP]=Start IBus daemon
Comment=Start IBus daemon
Exec=/usr/bin/ibus-daemon -rxR --panel=/usr/libexec/kimpanel-ibus-panel
GenericName[ja_JP]=IBus Daemon
GenericName=IBus Daemon
Icon=ibus-setup
MimeType=
Name[ja_JP]=IBus
Name=IBus
Path=
StartupNotify=false
Terminal=false
TerminalOptions=
Type=Application
Version=1.0
X-DBUS-ServiceName=
X-DBUS-StartupType=
X-GNOME-Autostart-Delay=10
X-KDE-StartupNotify=false
X-KDE-SubstituteUID=false
X-KDE-Username=
X-KDE-autostart-after=panel

手癖で/usr/bin/ibus-daemon -drxRとしていたけど、それはコマンドラインから起動させる場合であってautostartでは”-d”はいらない。

PulseAudioじゃなくてPipeWireを使う

ヘッドホンのこーディックがHFPでしかつながらなくて音質が耐えられなかったので後にょ後にょしてたら、最近はPulseAudioじゃ無くてPipeWireを使うらしい。というわけで以下を実行

Remove: pulseaudio pulseaudio-lang pulseaudio-module-* alsa-plugins-pulse mpg123-pulse pulseaudio-bash-completion pulseaudio-setup pulseaudio-zsh-completion system-user-pulse pulseaudio-utils

Install: pipewire pipewire-moudles-*  pipewire-alsa pipewire-pulseaudio  bluez-auto-enable-devices libdac2 libpulse0 libsbc1 gstreamer-plugin-pipewire

そんでもって一応以下のコマンドを実行

sudo mkdir -p /etc/pipewire/media-session.d/ && sudo touch /etc/pipewire/media-session.d/with-pulseaudio

再起動すると結構豊富にコーディックプロファイルが選べるようになっていた。

アセンブリでラベルを関数として認識させる

OS自作などでアセンブリでなにかの処理を書いた後に、これをCやRustなどから呼び出すことがあると思います。
このようなことをしている時に稀にリンカが超巨大エラーメッセージを吐いてズッコケることがありませんか?私はあります。
さて、このエラーをチンタラ解読するとアセンブリで書いた関数が再配置で呼び出し元の関数と離れすぎて相対ジャンプできないんだけど、みたいなことが書いてあります。例えば以下のようなエラーを吐いている場合などです。

relocation R_X86_64_PLT32 out of range: -549755221402 is not in [-2147483648, 2147483647]

「じゃあアセンブリの関数を呼び出し元の近くに配置してくれればええやんけ…」と思ってもやってくれないので、どうにかするしかないわけです。

手始めにstripなどされてないバイナリをobjdump -xでアセンブリのラベルがどう認識されているかを調べてみます。
アセンブリで

.section .text
hoge: 
        mov rax, rdi
        mul rdi
        ret

などと書いたとします。
すると、objdump -xでは
ffffff8000100000 l .text 0000000000 hoge
などと表示されます。
ここでCやRustで書かれた関数を見ると
ffffff8000200000 l F .text 000000003f foo
という感じの表示になっています。

さて、違いを見比べるとアセンブリで書いた関数は「Fのマークがない」「サイズが0」という点が異なるとわかります。特にサイズが0だと言うことはリロケーションができそうになさそうです。これで関数の再配置ができなくてリンカがコケるのではないかと思うわけです。
ここでアセンブリのラベルを高級言語での関数と同等の表示がされるようにしてみます。

まずは、「F」のマークをつけたいと思います。おそらく「Function」の略でしょうが、これは単に.textセクションに置くだけではつかないようです。
ここでELF形式で出力する場合は、.typeという擬似命令を使用できます。hogeの上に.typeを追加してみます。

.section .text
.type    hoge, %function
hoge: 
        mov rax, rdi
        mul rdi
        ret

これで再度objdumpの結果を見てみると
ffffff8000100000 l F .text 0000000000 hoge
などと表示されているはずです。ひとまずは関数として認識させられたようです。

問題は関数のサイズをどう認識させるかです。これがないと、どこまでがhogeなのかがリンカからわかりません。
ネットを探し回っていると.sizeという擬似命令を見つけました。
これは
.size label_name, size
label_nameのサイズをsizeであると指定する命令のようです。
これでsizeにhogeのretまでのバイト数を明記すれば良さそうです。
ただ、毎度計算するのは面倒なので”.“を使って、楽をします。

.section .text
.type    hoge, %function
hoge: 
        mov rax, rdi
        mul rdi
        ret
.size   hoge, . - hoge

.“は現在のアドレスを示すので、関数の先頭のアドレスを示すラベルとの引き算で関数のサイズが計算できます。

これでビルドしてobjdumpの結果を見ると、
ffffff8000100000 l F .text 0000000007 hoge
というふうにサイズもしっかり記載されてます。
これでhogeがリロケーションされ呼び出し元の近くに配置してリンカのエラーがなくなることもあります。(別のことが原因の場合もある)

この記事の元ツイート: https://twitter.com/PG_MANA_/status/1550674356929724416

感情と理性と死生観と精神薬

たまにはポエムチックなことを書いておこうと思います。

近況としまして、6月の第2週に自殺未遂をして死への恐怖に勝てずグタグタしている間に助けが来て病院に行った次第です。
現状は抗うつ剤などの精神薬により、どうにか安定を取り戻し暮らしてますが、過去最悪の精神崩壊だったため完全復活には時間がまだかかるだろうなと言う感じです。

本来はその始末を詳細に書こうと思ったんですが、ある人にそれはやめたほうが良いと言われたので別のことを書くことにしました。

抗うつ剤に頼ってフラフラ生きている時に、ネットで見かける様々な鬱に対する発言に色々思うことがあったので(普段は言語化しないが)抗うつ剤で気分がいいので、これまた適当に書いておこうと思う次第です。
先に断っておきますと、ここに書いたことは一個人(それも壊れかけ)の発言なので、似たようなことをしている全員には適用出来ないはずなのでお気をつけください。


まず、「世間話で死生観について語ってしまう」という発言に対して。
自分は気持ちはわかるし、本心では割としたいのだが理性で抑えてることが多いです。

死生観についてついて気軽に語ってしまいがちなのは、当人にとって死生観は「本当に身近な話題」だからと思うのです、というか自分がそう。

かれこれ20年以上生きているわけですが、他人が生きているのが「なぜ」なのかはよく気になっています。それで、ふと雑談などしていると聞いてみたくなる気持ちがあるのです。

そこで発生する認識のズレとして「生きる」という状態の違いです。
恐らく一般の人間(?)にとって、「生きる」というのは”Continuance”なことであって、生きている、生きていたいというのはデフォルトなわけです。そして「なぜ生きているのか」と問われれば「家庭があるから」「今の生活が楽しいから」など自分に大切なことを答えてくれます。
一方で自分にとって「生きる」というのは”Maintenance”することであって、生きている、生きていたいという方向に常に意識的に持っていかなければならないわけです。

例えば、行動原理のメータがあるとすれば一般は生きるという状態に針があって、これにストレスや嫌なことがあって、死という方向に錘で引っ張られる、という感じなのだと思います。
一方自分は、メータの針のデフォルトが生と死の境目、もしくは死に傾いていて、これを責任や目標という錘を持ってして、生の方向に持っていこうとします。これは別にストレスからくるものではなく(ストレスはまた別に死の方向への錘となっている)、漠然とした考えでそういう感じになってしまっているのです。このため、メータを生きるという方向に持っていくために常に錘が必要となります。この錘を常に他人を参考にしながら作ろうと思うわけです。

こんなズレがあるので、死生観の雑談もうまく行かないことが多いのです。
例えば、「なぜ生きているのか」という問いに対し、向こうが「家庭だ」と答えたとします。
それに対し、「では家庭がなくなればどうなるか?」と問いたくなります。
この時、相手は(ひどい質問だと思いながらも)「家庭がなくなることへのショックや悲しみ」という錘が与える影響について考えます。
一方でこちらは「『家庭』という生きる目標を失えば、やはり心は死に傾くのだろうか」という事を聞きたいわけです。
そして相手から「死にたくもなるだろう…」と帰ってくれば、やはりこの人を生に傾けているのは家庭というものなのか、と思うわけです。
ところが、追加で「でも…なんとか心の整理をつけて、立ち直っていきたい」などと回答が帰ってくると途端に混乱するわけです。
相手としては「メータのショックという錘の糸をなんとか断ち切ってデフォルトに戻したい」という思いで言っているのに、こちらとしては「せっかくデフォルトに戻ったはずなのに何か新しい錘が出てきて、生に傾けようとしているのか、それは何か」と気になったり、「なぜまた新しい錘が出てくるのか」と疑問に思うわけです。それで話がだんだんとこじれていきます。

昔は、これをやらかして揉めてたりしてたわけですが、最近はようやくこれを理解したので人に聞かなくなりました。

何故、メータの針が死に近い方向にあるかは人それぞれだと思います。自尊心をメッタメタに壊すことがあっただとか、長らくストレスを受け続けてそれから開放されても戻らなくなったとか、色々あります。自分は例に上げた両方です。
そんでもって、何故生きているかは死ぬのがどうしても怖いから、だったりします。でも、それは死の手前で後一歩が超えられない、というあまり生きた心地がないものです。


さて次に思うのが、「XXな気持ちになったときは、こう思いましょう!!」という感じの啓発です。
恐らく助かる人はいるでしょうし、特に発言自体が悪だと思わないのですが、それを実践しすぎるのも辛いよな、という感情があります。

「XXな気持ちになる」というのは、たいてい(原因の有無を問わず)自然にそうなります。「自分のものが壊された、悲しいと思わなきゃ、悲しいな」と意識的にやっている人はなかなかいないと思います(実を言うと自分は一部これ似たことをやってたりするんだが)。
それに対し、「こう思うようにしよう」というのは意識的にする必要があります。感情を意識し、それに対し感情に理性面から「こういう風に思え」と言う司令をかけます。
ある程度慣れれば無意識に出来ますが、それが衝動的であるほど意識的にやらないといけないわけです。

さて、これが単独の感情に対する処置ならうまく行くと思うのですが、複数の感情に対する制御となると困難になります。
自分は生まれつきの脳の障害と家庭環境による後天的なショックによって、あらゆるものに対する感情が複数発生し、感情同士・理性が衝突するという事がよくあります。喜怒哀楽に感情の衝突がよくあり、何かに対する怒りは「それはお前のワガママだ」「相手にも事情がある」「その怒りは生産的か?論理的か?」という感情(というかこれはどちらかというと理性)が起きます。良く言えばアンガーマネジメントなんて言いますが、結局脳内がパニックになってややずれた方向の怒りが飛び出してしまうこともよくあります。

よく高校時代にあったのが、何かに不満に思ったり怒りを覚えたことを口からこぼすと親に「文句を言うな、嫌なら高校をやめて働いて出ていけ、親が扶養する義務を負うのは義務教育までだ」と言われて、とっさに反感を抱くのと、努力を認めてもらえなかったことや突き放されたことへの悲しみを持つわけですが、これが衝突してしまうため、理性面で調停するわけです。その際に親の言うことに論理的には間違いはなく、法に照らし合わせて生活保護条件のうちの扶養義務を基軸に反論の材料にしようか、冷静に返そうか、となるわけです。ただ、仮にこれを反論したところで労働意欲のない人間の扶養義務やら、「生存は権利であって義務ではない」などとまあ色々帰ってくるわけですし、元に世の中には中卒で立派にも働いておられる方がいてその人たちとの違いについて論じても仕方ないな、と言うことで怒りと悲しみを論理で収めます。逆に相手方は味をしめて繰り返しこの返しをしてくるので、この処理を繰り返すことになり、無意識のうちに怒り・悲しみを理性で調停しようと試みます、最終的に愚痴をこぼす原因となった不満などに対して自己批判が発生するようになります。まあ、人間(の脳)は感情が先で理性が後に出来てますから、この処理をやりすぎると色々壊れるものも出てきます。(ちなみにこの処理自体は口論の収束に効果的であることもあり、自分は親の口論の調停に駆り出されてました、まあそれで更に色々ぶっ壊れたわけですが)

また、自分は医師よりグレーゾーン(よりやや上の)ASDという診断を現在受けているのですが、これに起因するか否か、達成しないといけない物事を柔軟に変更するのが苦手で、変更を強いられることやそれによる後始末をさせられることに拒否感を覚えたり、怒りを覚えます。しかし、日常生活を行うためにそれをぐっとこらえて、許容の方向へ持っていこうと理性で踏ん張ります。その他にも承認欲求があるのに、いざ認められると突発的な拒否感を抱いたり、楽をすることへの恐怖など割とシッチャカメッチャカな感情が飛び出します。これを全て理性面で調停し、自分にとって安定するような方向へと持っていきます。
他にもやる気があっても物事にどうしても集中できない時は過去の恐怖を意図的に思い出すことで脳を震え上がらせ、集中するというような毒をもって毒を制すみたいなことをしていました。

まあ、要するに感情のコントロールを山ほどすると、頭がそれでパンクして、色々な感情が脳内で爆発したり調停されたりします。これはとても疲れるんですが、起床から就寝まで絶えずやっているとまあなんとか生きることは出来ます。

このような事を常々やっていると、体にも異常をきたし脈拍がおかしくなったり、意味もないのに咳をしたり、誰かに見られている気がしたり、手が震えたり、発狂しそうな気がしたり、もう色々なことが起きます、これはパニック発作と言うものらしいです。これも抑えれば抑えられるのですが、常に心身不調で「きついな…」と声に出てしまうこともあります。自分はそれを親に怒られて更に悪化するなどを繰り返していたりもしました。ついでに、激しい感情を持つとその後に多少なりとも体に現れるというのも昔からありました。

さて、そんなメンタル面で対応しようとしても限界があるし辛いものがあります。自分はそれをなんとか抑え込んでいたんですが、今回諸般の事情によりやらかしましてこの制御ができなくなった結果、一気にぶっ壊れました。もう心身ともにぶっ壊れて体は痙攣するわ、泡吹くわ、感情は暴走して自己批判やらそれの調停にかられて頭は回らんわ、わけのわからないことを言うわ、普段と違う発言をするわで、完全に壊れるわけには行かないのはわかっていたので必死に制御しても傍から見たらぶっ壊れた人間だったと思います。
まあ要するに、感情に紐つけて制御するのは程々にすべきだ、ということを言いたいわけです。


そこで最後の話題に入るのですが、最近の精神薬はすごいぞ、ということです。
今回、病院に行って複数のお薬もらったんですが、体のパニック発作はそれ専用の薬でほぼ全て消滅・軽減しました。感情の衝突もいくつか(主に自己批判と恐怖)が消え去り、多少感情がふらついても安定に持っていくまでが短くなりました。
前回やらかしたときにも抗うつ剤をもらったのですが、三環系抗うつ薬のノリトレンというもので、暗い気持ちをバーーーンと持ち上げる感じの薬で、双極性やパニック発作がある自分には反動が大きかったのでやめてしまいました。ただ今回病状を(一人で病院にいけたことも有って)詳細に話したところ複数の適切な治療薬を頂いてコントロールが楽になりました。副作用もある程度きつく、眠気と甘い物が食べたいという衝動があるのですが、それに見合うだけの効果はありました。
残念ながら全ての症状は消え失せないですが、今後も薬を変えながらうまく行くものを探したいと思います。
というわけで、お薬に頼るのもわるかあねぇよ、という感じのことが言いたかったわけです。



皆さん、いろいろなバックグラウンドをお持ちかと思いますが、うまく頼るものを見つけて助け合ってご自愛ください。(自分はご自愛できないので、したつもりになってごまかして生きてます、ハヒー)



抗うつ剤効かなくなってきたので追記していいですか?

人間、感情が壊れる云々は人それぞれ色々あると思うのですが、喜怒哀楽が恐怖感情に全て変わるってなかなか辛くないですか?
「人生山あり谷あり」って長い人生で見たらそういうこともあるという意味らしいんですが、自分は山あったら即座に谷があるので”山 exists Then 谷 exists”って意味と思ってました。さっきまで楽しかったのにそれが途切れたらそれを失った感情で恐怖がやってきて辛いんですね。

まあ双極性障害って言ってしまえば終わりなんですが、なんでこうなったかなぁ〜と思うとですね、やっぱり人生今までの全てなんだな〜と思うのですよね。
我が家、ひどかった時は一家無職で両親どっちも鬱でしかも攻撃的になるタイプで、唐突にものは壊され、「お前がいなければ」と言われ、毎日人知れず布団の中で静かに泣きながら寝て。
その時に心の何かが壊れたのはわかるけど、それが何かはわからなくて。
そして一時期は親の片方が本当に出ていって、「本当に捨てられるかも」という感情が抜けなくなってしまって。

幸い家庭は回復したものの親から今度は生存権を人質に成績やら仕事やら何かを要求されて、失う恐怖が勝って自分を追い込んで生きてたら、段々と崩壊が進んでいってしまいました。
何かがほしい時、助けてほしい時、親は良く「出来ない」ではなくて、「したくない」で返してきて、そのたびに「自己の価値のなさ」を実感しては口を紡ぐをやっていました。「いざという時の病院代を取っておけ」だの「働いて遊ぶ金があるなら返せ」だの「なんでお前にそれをする必要があるのか」と言われるたびに口を紡いで、そんでもって想定していたとおり自分が壊れた時に慌てて駆けつけて泣いて許しを請われて、こちとら自分のことで精一杯なのに、親の願う通りに動かないといけないくてあの時更に壊れて、壊れるたびに何かを失っていってます。
あの時伝えた言葉も反故にされて今回も壊れました。
そういうわけで感情コントロールが壊れると自己批判と前回までの記憶が呼び起こされて助けを呼ぶことすらできなくなりました。

↑を今まで語らずに生きてきたのは、語っても面白くないしどうにかしてコントロール出来ていたためです。ただ、今回ので流石にコントロール仕切れなくなったので書いておきます。

こんなグルグル感情、なんと週に3日以上処理してて、いつも月に5回程度は泣きながら寝てます。よく考えりゃ人知れず勝手に泣くなんて立派な病気なわけですよ、ハイ。

皆さん、大切なものを失う前に病院行ってくださいね。手遅れないうちに。


追記: 情緒不安定に ブロマゼパム錠 と オランザピン はかなり効いている(個人的なメモ)(皆さんはお医者さんの処方に従ってください)

Mini Web ServerをC言語で書いた

自作OSでopenとかreadのSystemCallを実装していましたが、何か面白いものを作りたくなったので、最近の自作OSでは一つの目標(?)とされているWebサーバを動かすことを目標とすることにしました。
とりあえず使用するシステムコールを探るためにC言語で超簡易版のWeb Serverを書いてみました。

使用するSystemCallを最小限にするためにfopenやmallocなどは使用せず、open/readなどのSystemCallに近い関数のみ使用するようにしました。本当はmallocは既にOS側でメモリ管理ができているので使いたかったのですがこの世のLinux向けのlibc実装はメモリを確保する際にbrkやmprotectを使用するらしく、現在の自分のOSでは紆余曲折あってLinux ABI互換で、これらの実装がやや面倒だったので(頑張ればできないことはないが)、とりあえず端折ることにしました。

コードは以下のとおりです。

#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

//#define DEBUG

#ifdef DEBUG
#include <arpa/inet.h>
#endif

#define HTTP_VERSION "HTTP/1.1"
#define GET_METHOD "GET"
#define SERVER_HEADER_ENTRY "Server: Mini Web Server"
#define HTTP_200 HTTP_VERSION " 200 OK"
#define HTTP_404 HTTP_VERSION " 404 Not Found"
#define HTTP_500 HTTP_VERSION " 500 Internal Server Error"

int main() {
  puts("Mini Web Server");

  int receive_socket = socket(AF_INET, SOCK_STREAM, 0);
  if (receive_socket < 0) {
    fprintf(stderr, "Failed to open the socket(ret: %d)\n", receive_socket);
    return 1;
  }

  struct sockaddr_in host;
  host.sin_family = AF_INET;
  host.sin_port = htons(8080);
  host.sin_addr.s_addr = INADDR_ANY;
  if (bind(receive_socket, (struct sockaddr *)&host, sizeof(host)) < 0) {
    fprintf(stderr, "Failed to bind\n");
    return 1;
  }

  if (listen(receive_socket, 10) < 0) {
    fprintf(stderr, "Failed to listen the socket.\n");
    return 1;
  }

  while (1) {
    struct sockaddr_in client_address;
    socklen_t client_address_length;
    int client_socket =
        accept(receive_socket, (struct sockaddr *)&client_address,
               &client_address_length);
#ifdef DEBUG
    printf("Client: {\"Address\": \"%s\", \"Port\": %d}\n",
           inet_ntoa(client_address.sin_addr), client_address.sin_port);
#endif
    char buffer[0x1000];
    buffer[sizeof(buffer) - 1] = '\0';

    int received = recv(client_socket, buffer, sizeof(buffer), 0);
    if (received < 0) {
      fprintf(stderr, "Failed to receive data(ret: %d)\n", received);
      return 1;
    }

    /* Check method */
    if (received <= (sizeof(GET_METHOD) - 1) ||
        strncmp(buffer, GET_METHOD, sizeof(GET_METHOD) - 1) != 0) {
      close(client_socket);
      continue;
    }
    size_t pointer = sizeof(GET_METHOD) - 1;

    if (buffer[pointer] != ' ' || buffer[pointer + 1] != '/') {
      close(client_socket);
      continue;
    }
    pointer += 1;
    /* remove "/"(root) */
    pointer += 1;
    char *file_name = buffer + pointer;
    size_t file_name_size = 0;
    for (; (pointer + file_name_size) < received &&
           buffer[pointer + file_name_size] != ' ';
         file_name_size++)
      ;
    pointer += file_name_size + 1;

    if (received <= (pointer + sizeof(HTTP_VERSION) - 1) ||
        strncmp(buffer + pointer, HTTP_VERSION, sizeof(HTTP_VERSION) - 1) !=
            0) {
      close(client_socket);
      continue;
    }
    if (file_name_size == 0) {
      const char index_name[] = "index.htm";
      strcpy(file_name, index_name);
      file_name_size = sizeof(index_name) - 1;
    }
    file_name[file_name_size] = '\0';
#ifdef DEBUG
    printf("URL: %s\n", file_name);
#endif
    /* Create Response */
    int fd = open(file_name, O_RDONLY);
    if (fd < 0) {
      const char not_found_text[] =
          HTTP_404 "\r\n" SERVER_HEADER_ENTRY "\r\n\r\nFile is not found.";
      send(client_socket, not_found_text, sizeof(not_found_text) - 1, 0);
    } else {
      size_t size = lseek(fd, 0, SEEK_END);
      lseek(fd, 0, SEEK_SET);
      if (size > sizeof(buffer)) {
        const char error_text[] =
            HTTP_500 "\r\n" SERVER_HEADER_ENTRY
                     "\r\n\r\nFile size is exceeded the buffer size.";
        send(client_socket, error_text, sizeof(error_text) - 1, 0);
      } else {
        sprintf(buffer,
                HTTP_200 "\r\n" SERVER_HEADER_ENTRY
                         "\r\nContent-Length: %zu\r\n\r\n",
                size);
        send(client_socket, buffer, strlen(buffer), 0);
        read(fd, buffer, size);
        send(client_socket, buffer, size, 0);
      }
    }
    close(client_socket);
  }
  return 0;
}

straceで呼ばれているシステムコールを確認すると起動処理以外では、

  • wrtiev(puts, fprintf)
  • socket
  • bind
  • listen
  • accept
  • recvfrom
  • open
  • lseek
  • sendto
  • read
  • close

のみとなってます。

とりあえずLinuxでビルドしたところまあまあ動いているようのなのでこれが動くように頑張ります。

と言っても、まずはネットワークデバイスのドライバ書くところから始めないといけないのですが…

追記: 一応動きました。 https://twitter.com/PG_MANA_/status/1533812030582292481

MouseProのLTEモジュール(Telit LN940)をLinuxで使う(ATコマンド編)

旅先や出先で大活躍のLTEモジュール付きノートパソコンですが、妙に電波のつかみが悪いので更に調査していたところ別の方法で認識させることができたので記録しておきます。

環境

  • MousePro-NB510HL
  • openSUSE Tumbleweed
  • KDE Plasma Desktop

注意

前回の方法(MouseProのLTEモジュール(Telit LN940)をLinuxで使う)をすでに適用されている場合は一旦取り消して再起動してください。
具体的には以下のコマンドを実行してください。

sudo rm /etc/udev/rules.d/15-lte.rules
sudo systemctl disable wwan-sleep-hook
sudo rm /etc/systemd/system/wwan-sleep-hook.service

また今回の方法はモジュールのファームウェアの設定を変更します。そのため場合によってはモジュールが動作不能になる恐れがあります。以下の内容は全て自己責任で行ってください。

手順

まずはlibqmiやmodemmanagerをインストールします。
ModemManagerは起動させずに停止させたままにします。
(sudo systemctl stop ModemManager)

次に/dev/ttyUSB2に接続します。(screenコマンドがない場合はインストールしてください)

sudo screen /dev/ttyUSB2 115200

接続したらATE1と入力し改行します。(アルファベットは大文字で)、リターンキーを押すまでエコーバックはないのでお気をつけください。この作業でエコーバックを有効にします。成功すればOKと返ってきます。

(ATE1と入力し改行)
OK

次にATIと入力し改行してみます。成功すれば各情報とOKが返ってきます。(改行)はリターンキーのことを指します。

ATI(改行)

Manufacturer: QUALCOMM INCORPORATED
Model: 4105
Revision: (ファームウェアのリビジョン番号)
+GCAP: +CGSM

OK

モデルが4105であることを確認し次の作業に進みます。
AT^SETMODE?で現在のファームウェアの状態を確認します。成功すれば現在のファームウェアのモードとOKが返ってきます。マニュアルによれば0がNormal Mode、1がExtension Mode、2がLegacy Modeだそうです。

AT^SETMODE?(改行)
^SETMODE: 0

OK

次にモードを1(Extension Mode)に変更します。
AT^SETMODE=1でモードを変更します。成功すればOKが返ってきます。

AT^SETMODE=1
OK

ここまで来たらCtrl+a, k, yの順に入力しscreenを終了し、最後に再起動します。


再起動後ModemManagerを起動するとKDEのネットワーク設定でLTEモジュールを認識していることを確認します。
あとはMouseProのLTEモジュール(Telit LN940)をLinuxで使うを参考にKDEの設定を行ってください。
まれに接続が成功してもDNSの名前解決ができない場合があります。(curl https://1.1.1.1/ は接続できるけど curl http://example.com はできないなど)
この際は、resolv.confにPublic DNSを追記してやると接続できるようになる場合があります。

sudo sh -c "echo nameserver 1.1.1.1 >> /etc/resolv.conf"

以上の方法でusb_switchを使う場合よりより安定してつながるようになりました。
もし、不具合が発生した場合は上記の手順をAT^SETMODE=0に変更して行えば元に戻るはずです。

あけましておめでとうございます

今年もあけてしまったらしいです。新型コロナウイルス感染症もあってか2020から時の進みが速い気がします。

去年は東京に戻って引っ越しをしたり、またまた実家に帰ったり、お仕事を頂いたり、本の謝辞に載せていただいたりと色々なことがありました。とても貴重な体験でした。それでもオフラインの勉強会やイベントに参加することはかないませんでしたが…

初日の出を見て写真を撮り、飛行機で東京に戻るところです。元旦は妙に飛行機が安くて助かります(?)

年越しはOS自作をやっておりました。今年少しずつ進めていければと思います。

今年もよろしくおねがいします。

Linuxディストリビューションの比較

なかなかWordPressが完璧に動かないで悩んでいたら、いつの間にか動くようになっていて気がついたら、8月が終わってしまいました。
何かあるたびにログ見て悩むのはめんどくさいですが楽しくもありますよね。

今回はとりあえず、今まで扱ってきたことのあるLinuxディストリビューションについてざっと特徴をまとめてみたいと思います。
注意してもらいたいことは、Linuxディストリビューションとデスクトップ環境(GNOMEやKDE)というのは別物であり、それぞれのディストリビューションで対応していたりしていなかったりするのでご注意ください。
2021/04/06 追記: 最近アクセス数が増えておりますが、内容はあくまで個人的な意見ということをご留意ください。

2017/09/30:編集
2018/09/07:編集
2020/01/31:編集
2020/10/25:編集
2021/04/06:編集

Debian系

Debian

これはUbutnuを使用する前後とラズベリーパイ(Raspbian)で使っていたのですが、GNUの精神の完全自由を目指すコミュニティベースのディストロです。

昔からあるディストリビューションですので、情報はかなり豊富です。パッケージリポジトリにあるパッケージ(aptなどでインストールできるソフトウェア)も豊富でわざわざビルドしなくて良いことが多いです。
ただし、自由の定義が他のディストロより厳格でオープンソースであってもDebian Projectが自由でないと判断したソフトはNon-Freeリポジトリに取り入れられる、名称が変わるなどされるため、混乱することがあるかもしれません。(FirefoxとIceweaselの関係がよく知られた例です。)デスクトップ環境環境はGNOME3やKDE Plasma Desktopなどおおよそのものは揃っています。
安定版のパッケージリポジトリから降ってくるソフトウェアのバージョンは古いです。バージョンが古いのが気になる方は、安定版ではなくtesting(次期リリース予定)か、”sid”と呼ばれる不安定版を利用されると良いと思います。この場合はバグに遭遇する可能性はありますが、testingはそんなに困る状況に陥ることは少ないと思います。パッケージメンテナーの方には日本人も多くいらっしゃり、OSCなどでお会いして話すこともあるため、そこで情報交換ができるかもしれません。

Ubuntu

Debianから派生した大規模なディストロです。Linux入門としてWindowsからの乗り換え先として有名で、以前はWindowsのサポートが切れると「Ubuntuへの乗り換える方法」なんて本が出ていました。

Unityというちょっと(名前と動作が)ややこしいUIを持っています。Windowsから来た人がこのUIに慣れるかでその後のLinux人生が決まる…かもしれませんGNOME3に移行しました。

ネットを漁れば情報は山ほど出てきます。初心者に優しく、GUIツールが充実しているのでCUIを知らなくてもなんとかなると思います。
パッケージのバージョンはそこそこ古いですが、Debianのsidと同じバージョンのパッケージが多いです。Debian同様安定性重視だと思われるので、問題が発生するのを極力避けたい場合には最適です。すぐに新しいパッケージが使いたい場合は開発版を使うか他のディストリビューションを利用しましょう。
デスクトップ環境はGNOME3以外にもLXDEやKDE Plasma Desktop、MATEなどをサポートしたフレーバーが存在しており、Kubuntuなどの名前がついています。
初心者の方にはおおよそおすすめできますが、チューニングが必要なPC・環境などでは別のディストリビューションを利用したほうが良いでしょう。

Linux Mint

Ubuntuに不満がある人が駆け込んでるイメージがあるディストリビューションです(個人の感想です)。上記2つのディストロより、非オープンソースに対して寛大で一部の音声コーディックなどが標準で入っています。標準デスクトップ環境のCinnamonは、GNOME3と違ってWindowsライクなUIで安心する人が多いようです。日本語環境も昔よりかなり充実しており、初心者の方も戸惑うことなく安心して使えると思います。GUIツールも豊富で大抵の設定はできると思います。おおよその知識はUbuntuやDebianの技術を流用できると思いますし、Linux Mint Japanのフォーラムもあるので、そこで質問しながら勉強していくと良いと思います。

Zorin OS

WindowsとそっくりのUIとMacとそっくりのUIを持つディストリビューションです。爽やかなUIが好感が持てます。ただし、有料版があるので、無料版に若干の機能制限がかかってます。日本語対応はバージョン9でかなり良くなりました。隠れたLinux入門の道と言うところでしょうか。
最近は使ってないのでもしかしたら変わっているかもしれませんが、Wine(Windowsアプリケーションを動かすためのライブラリ群)の調整がうまく行っており、3Dゲームも一発で動くことが多いです。

Red Hat系

CentOS

CentOS 8まではRHEL(有料)のソースコードから商標や商用パッケージが削除されたものを使用しているディストリビューションです(クローンではなく、CentOS独自の変更も存在します)。サーバー用途で使用されることが多く感じますがデスクトップ環境も利用できます。Linuxでサーバを構築したい場合には、サーバ関係の情報がネットに落ちているこのディストリビューションがやりやすいのではないでしょうか。
前述のディストリビューション同様安定重視ですが、バージョンはそれほど古くなく各アプリケーションのメインバージョンに近いものが降ってきます。
個人的な感想ではデスクトップ利用者はこちらより後述のFedoraの方が人気である感じがします。一方で大学などのラボではこれが使われている所を見ます。
2020年に方針転換があり、CentOSはCentOS StreamとなりFedoraとRHELの中間に位置する扱いになりました。サーバ用途では長期間の安定性を求める場合は別のディストリビューションに移行する必要があるかもしれません。

Fedora

かつて存在していたRed Hat Linux(現在はRHEL)の後継のような存在です。Red Hat社の支援を受けたコミュニティが開発しており、かなり活発に開発されています。パッケージ管理システムもDebian系列のdpkgと違いRPMを用いています。個人的にはUbuntuとFedoraがLinuxディストリビューションの双璧を成している感じがします。6ヶ月ごとにメジャーアップデートが行われ、パッケージのバージョンも新しいのが多いです。ここで変更によって得られた改善などがRHELに還元されることもあります。仕様変更も発生し、最近ではパッケージマネージャーがyumからDNFに変更されました。昔使っていたときより安定性が高くなってると聞きますが最近使ってないのでわかりません。昔自分が使っていた時、パッケージ依存関係がぶっ壊れたり起動しなくなったりと苦い思い出があるディストリビューションですが、パッケージマネージャも置き換えられましたし、ユーザも増えたので現在はかなり良くなっていると思います。通常のリリースに対してRawhideという不安定版があります。ただしこれは名前の通り結構な不安定で仮想マシンで動かしていたときは不具合が発生することもありました。Linuxの最新が知りたいという人には良いディストロだと思いますし、ある程度の知識が身についた後に長く愛用するディストリビューションとしては最適かもしれません。

Vine Linux

国産のディストリビューションであり、これが好感されることも多いです。フォーラムでも気軽に日本語で質問できますし、日本語環境はしっかり整っています。ただし、すべてのエラーメッセージが日本語であることではなく、もちろん英語のエラーメッセージも存在します。パッケージマネージャはAPT-RPMというdpkgのフロントエンドとして用いられるAPTをFedoraで使われているRPMに移植したものを使っています。開発はかなりゆっくりでメジャーアップデートも多くないのですが、最近は特に開発が停滞しているような気がします。Firefoxのバージョンも古いのでセキュリティ的な不安は残ります。
かつては人に勧めていましたが、今は勧めづらいです。

Berry Linux

軽量なディストリビューションです。描画が綺麗で、起動時の猫の写真はかわいく映ります。あまりつかったことがないので詳しい事はわかりませんが、シンプルで良さそうです。

Slackware系

openSUSE

現在サーバで使用しているディストリビューションです。
公式リポから降ってくるソフトは少し古いですがDebianほどではありません。
日本ではシェアが少ないですが、海外では多いため有名なソフトではopenSUSEでのインストール方法が書かれています。SlackやChromeなどのrpmパッケージはおおよそ流用できますが、Fedoraなどとパッケージ命名が違うこともあるので依存パッケージが多いと依存関係を手動で解決する必要があります。
Arch Linuxと同じくローリングリリースのTumbleweedがあり、最新のパッケージが落ちてきます。最新と言っても不安定版が降ってくることはあまりないのでおおよそ安定して使うことができます。デスクトップ環境は初期インストールではGNOME3かKDE Plasma Desktopの二択ですが、あとで他のデスクトップ環境に切り替えられます。デスクトップではTumbleweedで新しいパッケージを、サーバーは安定したLeapを使い、openSUSEで固めることでディストロ間の設定の仕方の違いで悩むことをなくすこともできます。

Yastがコントロールパネルのように強くまとまっています。
弱点としては上記の通り日本でのシェアが低いため、情報が見つけにくい、Slackwareの血を引いているので設定が若干難しい、などが挙げられます。
時期によってはパッケージの更新が滞っていたり、削除される(nginx-modulesとandorid-toolsが消えたのは痛かったです)などがあり、自分でビルドすることも多々あります。特にVLCの公式ページに置かれているopenSUSE用のパッケージが長らく更新されない時期がありました。
日本のコミュニティもありOSCなどにも参加されているので連携しながら対応していくのも手かと思います。
2021/04現在このサーバーはopenSUSEで動いてますが、特に問題はないです。

Puppy Linux(Ver.5以前)

起動時にワンワンと大音量でなってびっくりした思い出があるディストリビューションです。バージョン5以降はいろいろあってubuntu系になったそうですが、使っていないのでここでは述べません。
メモリ128MBでも動く軽さです。XP時代のPCでもなんなく動かすことができ、CDから起動するときは起動時にファイルをRAMに転送するようなので起動後にCDを取り出しても作業を続行することができます。ただし、最新のデバイスには対応していないので、そのような状況下では正常動作しません。自分はデータ救出用として重宝しています。

独立系

Arch Linux

Linuxについて調べていると必ず遭遇するArch Wikiでよく知られているディストリビューションです。組み立て型OSというべきディストリビューションでデベロッパーフレンドリーを掲げています。インストールはGUIインストーラが存在せず、CUI環境下で行います。インストール作業はそこまで難解ではなくむしろ自由で、インストール時に特殊なドライバーを入れたい場合はとても柔軟に行えます。ローリングリリースモデルを採用しているのでメジャーアップデートがありません。GUIだけで全てが完結することはまずないと思いますので、コマンドあたりの知識は必須となります。公式リポジトリも最新版のパッケージが利用されています。一週間使用しないと1000件のアップデートが溜まっていることもしばしばあります。

デスクトップ環境もおおよそのものは用意されています。Xorg環境の整備に若干戸惑うことはあるかもしれませんが、良い勉強になるでしょう。AURという非公式のパッケージ群もありそこからChromeなども手に入ります。(余談ですが、知識が古いのでyaourtがなくなってyayが主流になっていたことを知らなかったです、と書いていたらyayも古くなったとか…)

デベロッパーフレンドリーを掲げているために細かい微調整が必要になる部分があるため、環境構築にはじっくり時間をかける必要がありますが、自分好みに調整しやすいでしょう。

Solus Linux

よくSolarisと聞き間違えられますが、「ソーラス」です。デスクトップ環境専用ディストリビューションとして開発されており、かなりすっきりにまとまっています。重複したパッケージを導入しないという目標を掲げているようですが、様々な選択肢があるのがLinuxエコシステムの特徴とも言えるので、これに関しては微妙な気持ちになっています。
日本で常用している人はほとんど見かけません(自分は現在メインで使っていますが)。パッケージ管理システムはeopkgという独自のシステムですが、GUIのパッケージマネージャーを使うことでChromeやSlackは導入できます。落ちてくるパッケージは概ね最新版で不満はない程度ですがopenSSLなど一部古いものもあります。Budgieというデスクトップ環境を開発しており、モダンなデザインで扱いやすいものになっています(Budgie自体は他のディストリビューションでも利用できます)。

ibus-mozcが公式リポジトリに存在しないため、スクリプトを書いてパッケージリクエストを行いましたが途中で返信がなくなっているためリポジトリには取り込まれていません。そのため日本語環境は整っているとは言い難いです。しかしながらGNOME3やKDE Plasma Desktop自体は日本語化は十分なされているので普段使いで困ることはないと思います。
追記(2020/10/25):mozcが追加されました。

(Pear OS)

今はなきディストリビューションで林檎じゃなくて梨です。要は林檎のそっくりデザインさんでして林檎社に食われて死んだという噂が流れています。軽くて快適でしたがアプリが案外少なかったと思います。ネットに情報が少なくどこの部類に入るか悩みますが、リポジトリがUbutnuのものだった気がするのでDebian系であると思います。消滅したディストリビューションですのでここでは一番下においてます。今でもインストールDVDは持っているのですが、UI部分のアップデートがなく不具合が起きそうなので使用しておりません。似たようなデザインのディストリビューションとして、elementary OSがあるので、使ってみてはいかがでしょうか。自分はelementary OSを使ったことがないのでここでは紹介しません。

まとめ

初心者におすすめしたいと思うのはLinux Mint、Ubuntuあたりです。
多くのOSでは安定志向が強いので古いパッケージが降ってきますが最初のうちはこだわらない限り気にならないでしょう。
紹介の中でパッケージが古いことを挙げていますが、安定して動くことを目的としており逆に最新パッケージを利用しているディストリビューションでは再起動すると起動してこなくなった…なんてこともありますので、利用者の方針に沿って利用してください。
なお、この記事は個人の意見なのであくまで参考程度で利用してください。
ほとんどのディストリビューションは無料ですので、慣れてきたら別のディストリビューションに挑戦するのも良いでしょう。

新サーバーとIPv6/IPv4ネットワーク構成とNginx暴走

この度引越しに伴い、実家で「引越し先で光回線使えるならこのクソデカサーバーとUPS持っていけ」と言われたのでサーバー機は高校同期に譲渡し(ついでにLinux沼に沈めて)、新しく作ることにしました。
念願のRyzenを使い、更にベアボーンキットを使って小型化しつつ、NVMeなSSD2つ使ってRAID1で組みました。
実家はBBIQだったのでIPv4環境だったわけですが、こちらではフレッツ光パワーでIPv6環境が手に入りました。
さてIPv6な環境が手に入った瞬間、「IPv4なんて知らねーウォォォォ」とIPv6以外でアクセスできないサーバを構築しそうになったわけですが、残念ながらそういうわけには行かないわけです。
別にIPv6でもPPPoEで通信すればグローバルなIPv6/IPv4アドレスが降ってくるわけですが、新しい物好きでネットは速いほうがいいのでIPoEで通信したくてIPv4 over IPv6してほしいわけです。この方式だとIPv6は半固定なグローバルIPアドレスが降ってくるのですが、IPv4の方はIPアドレスが共有されてしまい、ウェルノウンポートが使えなくなります。
CDNや中間サーバを挟んでポートフォワーディングしてやる方法も考えたのですが、スイッチングハブを間に挟みルータの外にサーバーを出してやることで解決しました。
この構成にするとサーバーでPPPoEを張らなければならず、rp-pppoeを導入しました。
pppoe-setupコマンドを叩いてIDとパスワードを入力し、ファイアーウォールはNONEを選択します。(後でfirewalldで設定します)
設定が終わると、/etc/sysconfig/network/ifcfg-ppp0 ができているはずなのでこれに
LINUX_PLUGIN=/usr/lib64/pppd/2.4.7/rp-pppoe.so
を追記します。
設定が終わった後に
sudo systemctl start pppoe
とでもしてあげれば接続が開始されppp0ができています。ファイアーウォールで適宜ポート開放して動くことが確認できたらenableで起動時に自動接続するようにします。
NginxやDovecotでppp0をlistenするようにしてDDNSにはIPv6アドレスとPPPで得られたIPv4アドレスを通知するようにします。

さて、このように設定してついでにマストドンのサーバも移行し「夜も遅いし、サーバー移動も終わったし、寝るかぁ」と最後にRyzenパワーを見ようとhtopを開いていくつかのページを閲覧したところ…

htopコマンドの様子

これを見て眠れるわけがない、顔面真っ青案件が広がってました。
最初はマストドンのSidekiqあたりが再試行で暴走しているのかと思って確認画面を見たが特に暴走している様子もなく、nginxが常に上に張り付きだし、そうこうしてたらswapperが出てきて忙しく動き出したので慌ててNginxを止めることになりました…。
NAXSIとマストドンの組み合わせが怪しいと考え、拡張機能をすべて切り離し、再現する条件を探していって結局、NAXSIではなくBrotliプラグインとproxy_passの組み合わせで再現することが判明しました。BrotliをOFFにして無事平穏を取り戻しました…
原因解明と行きたいですが、疲れたのでそれはまたの機会にします。

というわけでRyzen3 PROなCPUを搭載した新サーバーとIPv6環境でもアクセスできる新環境になりました。

ゼロからのOS自作入門の献本を頂いた

最近引っ越しましたPG_MANAです、家賃は25kです。
さて、その引っ越し作業中に人生初の献本をいただきました。
その名も「ゼロからのOS自作入門」です。

入れ替わりが激しいIT書の本棚に長らく重鎮として並んでいた「30日でできる! OS自作入門」の流れを汲んだ最新のPCで動くOSの自作本です。
というのも、「30日でできる! OS自作入門」(以後、30日OS自作本と呼ばせていただきます)の内容は古く、PS/2 マウス・キーボードや32bitプロテクトモードなど現在では使われてない機器や機能について取り扱っています。
これらの中にはすでに最新のPCでは搭載されてない機能も存在しており、本の内容を実機で試そうにも動かないなんてこともあります。それでも長く本棚に並んでいたのはプログラミング初心者にも分かりやすく、OSのことだけでなくプログラミングのエッセイも学べる大変優れた良書であるからだと思いますが、続編が出ていないのもまた事実でした。「作って理解するOS」という、これまた良書も出たのですが、やはりレガシーな内容を多く含んでいます。
話を戻すと「ゼロからのOS自作入門」の献本をいただいたのですが、実はこの本のテスト読者として参加しておりました。思い出せば一昨年の話ですが、著者のuchanさんからテスト読者としてのお誘いをいただきました。「OS自作本のテスト読者」というワードで二つ返事で了承したわけですが、その時に「献本がほしい」と言ったことを覚えています。そんな待ち望んだ献本を頂いたのですが、引っ越し作業の忙しさや本をもらった直後(約10分後)の祖父との最後のビデオ通話をして、その夜の訃報の哀愁感などで部屋の片隅でプチプチシートにくるまれて放置されており3日経ってやっとまじまじと見たところです。

ゼロからのOS自作入門の献本


表紙は30日OS自作本を想起させる緑色をベースとし、MikanOS(「ミカノス」と呼ぶようです)の「未完」と「蜜柑」をかけ合わせたことがわかる蜜柑の断面がデザインされております。
ちなみに、果汁飲料のパッケージでは果汁100%でないと果物の断面のイメージを使用してはいけないと公正取引委員会の規約で定められています。このことを踏まえるとこの表紙から「この本はMikan100%だよ!!つまり未完成率100%、本を読んでOSを作り上げ、完成させるのは君自身だ!!」という著者の熱い思いが読み取れますね(と深読みをしたつもりで得意げになってるPG_MANAであった。未完成率ってなんだろう)。
さらに「Intel 64モード」「UEFI BIOS起動」「USB3.0 ドライバ」などという現代の規格を表すワードが並んでいます。これはワクワクです。背表紙を見ると30日OS自作本の著者である川合さんからのメッセージや東工大教授である権藤先生のコメント、ツイッターg…吟遊詩人のヴァネロピさんのコメントがあり、どれも素晴らしいコメントです。

内容面では、この本はC++を使って記述されています。そのためクラスやnew演算子といったC言語にない用語が出てきます。C++をガチガチに理解していないとこの本を読み進めることはできない、ということでは決してありませんが完全の無知では少々厳しいかなと思います。C言語など手続き型言語しか触ったことがない、またはプログラミング初心者の方はC++の入門書やサイトで予習したり必要に応じて参照したりすれば良いでしょう。Javaなどの他言語でオブジェクト指向をなんとなくでも触った方は「C++ではこう書くのか」程度で対応できると思います。いずれにせよ、できる限りのフォローアップはされていますのでそれを読んで理解できないようでしたら適宜検索するか「そいうものもあるのか」と読み飛ばしても構わないと思います。
大変分厚い本ですが、1章から丁寧にステップアップ方式で書かれています。ここは30日OS自作本と同じで、これまたこの本も30日で読めるようになっています。とはいえ、30日で読み切る必要もなく自分のペースで読んで構わないと思います。
最初の数日はEDK2(UEFIの開発環境です)を用いてブートローダを作成しています。この部分はC言語で作成されています。ここではOS本体のELFのヘッダーを解析してメモリ上に展開しております。30日OS自作本ではフロッピーディスクのセクタ数を指定して読み込んでいたのでOSを改造して大きなバイナリを内蔵すると不具合が出てましたが、そのような心配はもうありません。
そこからはフレームバッファに縞模様を書き込んだりmakeを導入したりと30日OS自作本を読んだことがある方は懐かしく感じるような内容を実践していきます。
この後も30日OS自作本の流れを大まかに汲んだ進行となっています。後半になるとページングを用いたデマンドページングやコピーオンライトなど30日OS自作本にはない内容が出てきます。このような内容の濃い本となっておりますが、ステップアップで書かれているので一つ一つ丁寧に理解できると思います。

テスト読者として執筆途中の原稿を読んだとき、「もう完璧じゃん…」と思ったのを覚えております。しかし30日OS自作本を読んだときの記憶を思い出し、できる限りのレビューをさせていただきました。思い出せば、30日OS自作本を読んでいたときはちょうどLinuxインストールなどにも手を出したところでBIOSの設定をいじり起動しなくなったことがあり、OS自作ではなるべくQEMUを使うようになったなどの覚えがあります。OS自作初心者の段階で自作OS用PCの購入はやはり躊躇するでしょうし、普段使いのPCのBIOSの設定は慎重に行うように促したほうが良いのではないか、という意見をさせていただいたところ恐縮にも原稿に反映してくださりました。すごく嬉しい。さらに謝辞にも載せていただきました、本当に光栄です。

長々と書きましたが、要約するとすっごい良書です。一ヶ月も読める本が4kで買えます。家賃5日分で30日分の本が買えます、これはお買い得です。
ぜひお手にとっていただければと思います。

Solus Linuxでカーネルのアップデートが適用されない

Solus Linuxを使っていてある時からカーネルのアップデートが適用されなくなり、VirtualBoxなどが動作しなくなり困ったことになりました。
一回修正しようと適当に/boot以下をいじったら無事起動しなくなりLiveUSBのお世話になったので、今回はよく調べてから対応することに。

Solus LinuxではブートシステムとしてClearLinuxのclr-boot-managerというのを使っており、UEFI環境下ではバックエンドとしてsystemd-bootを利用しているらしいです。
というわけでまずはsystemd-bootの状態を確認するために
bootctl statusを実行すると

$ bootctl status
System:
     Firmware: UEFI 2.50 (American Megatrends 5.12)
  Secure Boot: disabled
   Setup Mode: user
 Boot into FW: supported

Current Boot Loader:
      Product: systemd-boot 246
     Features: ✓ Boot counting
               ✓ Menu timeout control
               ✓ One-shot menu timeout control
               ✓ Default entry control
               ✓ One-shot entry control
               ✓ Support for XBOOTLDR partition
               ✓ Support for passing random seed to OS
               ✓ Boot loader sets ESP partition information
          ESP: /dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b
         File: └─/EFI/SYSTEMD/SYSTEMD-BOOTX64.EFI

Random Seed:
 Passed to OS: yes
 System Token: set
       Exists: yes

Available Boot Loaders on ESP:
          ESP: /boot/efi (/dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b)
         File: └─/EFI/systemd/systemd-bootx64.efi (systemd-boot 246)
         File: └─/EFI/BOOT/BOOTX64.EFI (systemd-boot 246)

Boot Loaders Listed in EFI Variables:
        Title: Linux Boot Manager
           ID: 0x0002
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b
         File: └─/EFI/systemd/systemd-bootx64.efi

        Title: Linux Boot Manager
           ID: 0x0000
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b
         File: └─/EFI/SYSTEMD/SYSTEMD-BOOTX64.EFI

        Title: UEFI OS
           ID: 0x0001
       Status: inactive, boot-order
    Partition: /dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b
         File: └─/EFI/BOOT/BOOTX64.EFI

Boot Loader Entries:
        $BOOT: /boot/efi (/dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b)

Default Boot Loader Entry:
        title: Solus 4.1 Fortitude
           id: Solus-current-5.10.9-169.conf
       source: /boot/efi/loader/entries/Solus-current-5.10.9-169.conf
        linux: /EFI/com.solus-project/kernel-com.solus-project.current.5.10.9-169
       initrd: /EFI/com.solus-project/initrd-com.solus-project.current.5.10.9-169
      options: root=PARTUUID=782cda64-d615-4b92-b362-7580b073ca62 quiet loglevel=3 ...

これを見るとESP(UEFIの起動パーティション)は/boot/efiになっており、「Default Boot Loader Entry」はLinux 5.10.9-169が選択されています。
続いて、clr-boot-managerの様子を見てみます。

$ sudo clr-boot-manager list-kernels
* com.solus-project.current.5.10.12-171
  com.solus-project.current.5.10.9-169

Linux 5.10.12-171が既定のカーネルとして設定されています。
どうやら、clr-boot-managerとsystem-bootの連携がうまくいってないみたいです。
次に/boot以下を見ると、efiディレクトリとloaderディレクトリがあり、efiディレクトリの中にはこれまたloaderディレクトリがあり、中の構成もそっくりです。もしやと思い/boot/loaderを削除してclr-boot-manager updateを叩いてみると

$ sudo rm -rf /boot/loader/
$ sudo clr-boot-manager update
[FATAL] cbm (../src/bootloaders/systemd-class.c:L290): Failed to create loader entry for: ///usr/lib/kernel/com.solus-project.current.5.10.9-169 [No such file or directory]
[ERROR] cbm (../src/bootman/update.c:L218): Failed to repair running kernel
[FATAL] cbm (../src/bootloaders/systemd-class.c:L290): Failed to create loader entry for: ///usr/lib/kernel/com.solus-project.current.5.10.12-171 [No such file or directory]
[FATAL] cbm (../src/bootman/update.c:L250): Failed to install default-current kernel: ///usr/lib/kernel/com.solus-project.current.5.10.12-17

どうやらclr-boot-managerはESPの場所を確認せず/bootに書き込んでいるようで、結果実際に使用されている/boot/efi/loader/loader.confが更新されず、昔のカーネルが起動されるみたいです。

特に/boot/efiにこだわってはいないのでESPの位置を/bootに変更することにしました。
一旦/boot/efiをumountし、/etc/fstabを編集して/boot/efiを/bootに変更します。

$ sudo umount /boot/efi
$ sudo rm -rf /boot/loader/ # すでに実行した場合は不要
$ sudo vi /etc/fstab # /boot/efiを/boot/に変更
$ sudo mount /boot

これでbootctl installとclr-boot-manager updateを叩くと

$ sudo bootctl install
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/EFI/systemd/systemd-bootx64.efi".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/EFI/BOOT/BOOTX64.EFI".
Random seed file /boot/loader/random-seed successfully written (512 bytes).
Created EFI boot entry "Linux Boot Manager".
$ sudo clr-boot-manager update
[FATAL] cbm (../src/bootman/kernel.c:L646): Failed to install kernel /boot/EFI/com.solus-project/kernel-com.solus-project.current.5.10.9-169: No such file or directory
[ERROR] cbm (../src/bootman/update.c:L218): Failed to repair running kernel
[FATAL] cbm (../src/bootman/kernel.c:L646): Failed to install kernel /boot/EFI/com.solus-project/kernel-com.solus-project.current.5.10.12-171: No such file or directory
[FATAL] cbm (../src/bootman/update.c:L250): Failed to install default-current kernel: ///usr/lib/kernel/com.solus-project.current.5.10.12-171
[ERROR] cbm (../src/bootman/bootman.c:L942): Error opening /boot//EFI/com.solus-project: No such file or directory
[ERROR] cbm (../src/bootman/update.c:L371): Failed to remove old freestanding initrd

とエラーが出てるので、とりあえず

$ sudo mkdir /boot/EFI/com.solus-project
$ sudo clr-boot-manager update

でうまくいったので良しとします…
再度bootctl statusを見ると

$ bootctl status
System:
     Firmware: UEFI 2.50 (American Megatrends 5.12)
  Secure Boot: disabled
   Setup Mode: user
 Boot into FW: supported

Current Boot Loader:
      Product: systemd-boot 246
     Features: ✓ Boot counting
               ✓ Menu timeout control
               ✓ One-shot menu timeout control
               ✓ Default entry control
               ✓ One-shot entry control
               ✓ Support for XBOOTLDR partition
               ✓ Support for passing random seed to OS
               ✓ Boot loader sets ESP partition information
          ESP: /dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b
         File: └─/EFI/SYSTEMD/SYSTEMD-BOOTX64.EFI

Random Seed:
 Passed to OS: yes
 System Token: set
       Exists: yes

Available Boot Loaders on ESP:
          ESP: /boot (/dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b)
         File: └─/EFI/systemd/systemd-bootx64.efi (systemd-boot 246)
         File: └─/EFI/BOOT/BOOTX64.EFI (systemd-boot 246)

Boot Loaders Listed in EFI Variables:
        Title: Linux Boot Manager
           ID: 0x0002
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b
         File: └─/EFI/systemd/systemd-bootx64.efi

        Title: Linux Boot Manager
           ID: 0x0000
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b
         File: └─/EFI/SYSTEMD/SYSTEMD-BOOTX64.EFI

        Title: UEFI OS
           ID: 0x0001
       Status: inactive, boot-order
    Partition: /dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b
         File: └─/EFI/BOOT/BOOTX64.EFI

Boot Loader Entries:
        $BOOT: /boot (/dev/disk/by-partuuid/1026dfb7-66be-40ae-96d0-7de4a03c1d0b)

Default Boot Loader Entry:
        title: Solus 4.1 Fortitude (Solus-current-5.10.12-171.conf)
           id: Solus-current-5.10.12-171.conf
       source: /boot/loader/entries/Solus-current-5.10.12-171.conf
        linux: /EFI/com.solus-project/kernel-com.solus-project.current.5.10.12-171
       initrd: /EFI/com.solus-project/initrd-com.solus-project.current.5.10.12-171
      options: root=PARTUUID=782cda64-d615-4b92-b362-7580b073ca62 quiet loglevel=3 ...

無事更新されていているみたいなので完了です。