LinuxのLVMに入門したのでいろいろメモ

LVMというのは抽象化したレイヤーを通して物理的なストレージにアクセスするというやつ(適当)。 物理的なストレージを直接使うよりもいろいろ変なことができるので嬉しいらしい。

雑に概念を説明

LVM には PV(Physical Volume)、VG(Volume Group)、LV(Logical Volume) という概念がある。

まず、PV というのは物理的なストレージに一対一で対応する概念で、SATA 接続のストレージだと /dev/sda1 で一個、 /dev/sda2 で一個みたいになる。 SSD をパーティションで区切っていない場合は /dev/sda で一個の PV とか。

次に、VG というのは、普通にストレージを使っているときは 1 個のストレージデバイスに対応する概念(のような気がする)で、 1 個以上の PV をまとめて 1 個のボリュームにできるというもの。 普通のストレージと違うのは、複数のデバイスとかパーティションにまたがっていてもいいという点。

Ubuntuの/tmpをtmpfsにする方法

systemd のデフォルトでは /tmp は tmpfs でマウントされるようになっている。 でも Ubuntu では /tmp で tmpfs を使わないようにしてある。何度か /tmp を tmpfs にする試みはあったらしい1が……。

まあどうでもいいといえばどうでもいいが、Ubuntu の /tmp を tmpfs にする方法。

$ sudo systemctl enable /usr/share/systemd/tmp.mount
$ sudo reboot

これだけ。

通常、systemd では /tmp は tmp.mount でマウントされる。 Ubuntu でもこのファイルは /usr/share/systemd にインストールされるようになっていて、ユーザの好みに合わせて使える。 ただし、ここはユニットファイルの検索パスに入っていないので普通に指定すると有効化できない。 というわけで、フルパスを指定して mount unit を有効化することで、直接使えるようにしている。

Emacsのマグカップを買った

FSF のショップにある Emacs のマグカップを買ってみました。

テカテカで映り込みそうなのであんまり写真は上げていないんですが、なかなか良いです。 ロゴの色は FSF のページの写真よりちょっと青っぽいですね。これは個体差なんでしょうか。

これを注文したのは 11/29 とかだったのですが、届いたのは年が明けて 1/25 とかでした。 箱に何故か中国郵政のステッカーが貼ってあったので、誤配送で中国を経由してしまった説はあります。 (一番安い配送オプションを選んだせいもあると思います。)
1 ヶ月後に控えた引っ越しに間に合うかとビクビクしていたんですが、何もメールが来なかったのは FSF に登録しているメールアドレスを 更新し忘れていたせいだと後で気づきました。

Mesonのコードを読む (1)

お久しぶりです。 どうでもいいことを気軽に書けるように(ブログサービスではなく)自分のブログを作っているのに、あんまり気軽に書けてないなと感じている今日この頃です。 で、普段からどうでもいいことを書いていないとどうでもいいことも書きづらくなってしまうな(?)と思ったわけで、質にはこだわらずにどうでもいい記事をぽんぽん出していこうと 思ったわけですね。でも書くからには何かネタがないと厳しいなというわけで、適当にそのへんの OSS のコードを読んでそれを記事にするというのをひとまず続けてみようと思っています。 コード読んで解説くらいだったらそんなに負荷も高くないので続けられそうという希望的観測もあります。 あと他人のコード読むといろいろ学べるところもありますしね。

Meson で subproject のオプションを指定する方法

備忘録。 出てこないなーとか思ってたら普通に書いてあった。

単に -D で指定するときに subproject名:オプション名 というふうに指定すればいいだけだった。

例えば subproject hoge でだけ warning_level を 3 にしたい場合は

$ meson configure -Dhoge:warning_level=3

のように指定すれば ok。

ちなみにモジュール (meson.build の中で import とかして使うやつ) ごとのオプションは . で区切る。

なので pkgconfigrelocatabletrue にする場合とかは -Dpkgconfig.relocatable=true とかを指定すればいい。

参考

FSF が送ってくるニュースレター(郵便物)を止める方法

Free Software Foundation に寄付すると毎年(?頻度は忘れた)GNU Bulletin という冊子を送ってくるようになる。 しかもアメリカから送ってくるのでこの送料も馬鹿にならないのではないだろうか…。

てことでいらないので止めてもらった。

ここ の Donations のところに メール送ったらオプトアウトできると書いてあるので、適当にメールを送る。

僕は

I’d like to opt-out from print version of newsletters. My FSF username is “kofuk”.

というような怪しい英語のメールを送った。 今見直すと “opt-out from” は明らかに “opt-out of” と書くべきだったとかいろいろあるが、僕は外国人なので仕方ない(適当)

Windowsのエクスプローラーでフォルダを開くたびに新しいウィンドウが開いてしまうのを直す

Windows 11 のエクスプローラーにタブ機能がついたというので、 QTTabBar を無理矢理消したら、 フォルダをひらくたびにエクスプローラーのウィンドウが増殖する問題に悩まされた。

レジストリをいじれば一発で直る。 HKEY_CLASSES_ROOT\Folder\shell にある「(既定)」というやつに値が入っていたら、それを消せばいい。

HKEY_CLASSES_ROOT というのはファイルタイプの開き方を保存しているらしい。 Windows のことはよく知らないので雰囲気で書いているが、新しいウィンドウが開いてしまうのはフォルダを開いたときに QTTabBar のルーチンが呼び出されるように設定されていることが原因のようだ。 QTTabBar はアンインストールされているので実際にはこの呼び出しは失敗するが、 そのフォールバックでエクスプローラーで開く(explorer フォルダ というコマンドを実行する)という動作になっているので、 毎回新しいウィンドウが開かれてしまっていたということのような気がする。

YubiKeyのセットアップ on ArchLinux

完全にメモなので全く纏まっていないです。

インストール

GUI でポチポチやりたかったので yubikey-manager-qt をインストール。 コマンドでやりたい場合は yubikey-manager を入れればいいが、なんとなくこっちの情報は少ないような気がしている。

SSH で使いたい場合は opensc パッケージもインストールする。

pcscd.socket の有効化

これを有効化しないと “Failed connecting to YubiKey” と言われてしまう。

$ sudo systemctl enable --now pcscd.socket

適当にこのエラーメッセージで調べても書いていないことが多くて、ちょっと手間取ったけど、 CLI の方で出てきたエラーで検索したらこれが出てきて、解消した。

PIN を設定したり…

yubikey-manager の Applications から PIV を選ぶと PIN の設定をしたり Certificate を追加したりするオプションが出てくる。

CentOS 7 (rootなし) でLLVM 15をビルドする方法

入ってるパッケージが諸々古すぎるので、周辺のライブラリのビルドから始める必要がある。

そのへんを自動でやってくれるようにシェルスクリプトにまとめた。 /tmp に tmpfs がいなかったり、ホームディレクトリが NFS だったりする環境のものなので、_build_dir 系の変数は変更して使ったほうがいいと思う。

ビルド手順

まず、標準で入っている GCC は LLVM をビルドするには古すぎるので、GCC のビルドから始める必要がある。 古い LLVM から徐々にバージョンアップしていく方法でもいいが、最新の GCC はビルドできるので。ついでに GCC も最新にしてやる方が首尾が良いと思う。

mallocをフックしてメモリ使用量を測る

いろいろと怪しいけどこれでフックすれば取れるはず。 まあ malloc をフックしている時点で怪しいので細かいことを気にしてはいけない (?)

#define _GNU_SOURCE
#include <dlfcn.h>
#include <string.h>
#include <stdio.h>

static size_t max_usage;
static size_t cur_usage;

static void *(*orig_malloc)(size_t);
static void (*orig_free)(void *);
static void *(*orig_realloc)(void *, size_t);

__attribute__((constructor)) void initialize(void) {
    orig_malloc = dlsym(RTLD_NEXT, "malloc");
    orig_free = dlsym(RTLD_NEXT, "free");
    orig_realloc = dlsym(RTLD_NEXT, "realloc");
}

extern char *__progname;

__attribute__((destructor)) void print_stat(void) {
    size_t result = max_usage;
    fprintf(stderr, "%s: max memory usage: %zu\n", __progname, result);
}

void *malloc(size_t size) {
    void *ptr = orig_malloc(size + sizeof(size_t));
    if (ptr == NULL) {
        return NULL;
    }
    memcpy(ptr, &size, sizeof(size_t));
    cur_usage += size;
    if (cur_usage > max_usage) {
        max_usage = cur_usage;
    }
    return (void *)((unsigned char *)ptr + sizeof(size_t));
}

void *calloc(size_t nmemb, size_t size) {
    void *ptr = malloc(nmemb * size);
    if (ptr != NULL) {
        memset(ptr, 0, size * nmemb);
    }
    return ptr;
}

void free(void *ptr) {
    if (ptr == NULL) {
        return;
    }
    void *head = (void *)((unsigned char *)ptr - sizeof(size_t));
    size_t size;
    memcpy(&size, head, sizeof(size_t));
    cur_usage -= size;
    orig_free(head);
}

void *realloc(void *ptr, size_t size) {
    size_t old_size = 0;
    void *result;
    if (ptr != NULL) {
        void *head = (void *)((unsigned char *)ptr - sizeof(size_t));
        memcpy(&old_size, head, sizeof(size_t));
        result = orig_realloc(head, size + sizeof(size_t));
    } else {
        result = orig_realloc(ptr, size + sizeof(size_t));
    }
    if (result != NULL) {
        cur_usage -= old_size;
        cur_usage += size;
        if (cur_usage > max_usage) {
            max_usage = cur_usage;
        }
        memcpy(result, &size, sizeof(size));
        return (void *)((unsigned char *)result + sizeof(size_t));
    }
    return NULL;
}

void *reallocarray(void *ptr, size_t nmemb, size_t size) {
    return realloc(ptr, nmemb * size);
}