Development

aws-sdk-go-v2でGCSを叩いた際のSignatureDoesNotMatchに対処する

Google Cloud Storage は実は S3 互換の API が生えていて、既存の S3 を使うコードのオブジェクトの保存先を簡単に GCS に向けることができるようになっています。 理想的にはエンドポイントやトークンを差し替えれば移行できるのですが、他の S3 互換を謳うオブジェクトストレージと同じように単純にいかないことも多々あります。 最も一般的なエラーは S3 でサポートされているエンドポイントを互換オブジェクトストレージがサポートしていないという問題だと思いますが、 今回細かい部分の仕様の差異で AWS SDK で GCS のエンドポイントが叩けないという問題があったので、そのときにとった方法をメモしておきます。 雑な対処なので全く良い方法ではないですが。 起こったことと原因 aws-sdk-go-v2 で

Mastodonのフロントエンドをカスタマイズしてみよう

この記事は「Cybozu Frontend Advent Calendar 2023」 13 日目の記事です。 一家に一台 Mastodon とはよく言ったもので1、今や Mastodon のサーバは人々の生活に必要不可欠なものになっています。(そんなことはない) そして、自分で Mastodon のサーバを立てると、Mastodon 自体を改造する必要に迫られたり、細かい不便を解消するために手を入れたくなったりしてくるものです2。 この記事では、私が Mastodon のフロントエンドに手を入れた際の知見を共有します。 ちなみに業務ではフロントエンドとはかなり遠い領域を触っていて、フロントエンドは何も分かりません。 Mastodon とは? (↑分かりやすいらしい動画。kofuk は真面目に見たことがないですが) Mastodon はオープンソースの分散型 SNS です

ISUCONに出た

「初めて蟹を見た kofuk」というふざけた名前のチームで @uta8a と ISUCON13 に出ました。 当日のリポジトリも公開しています。 GitHub - uta8a/isucon13q-2023-11-25: ISUCON 13 https://github.com/uta8a/isucon13q-2023-11-25 ISUCON 13. Contribute to uta8a/isucon13q-2023-11-25 development by creating an account on GitHub. パフォーマンスに詳しくない人がほとんど準備せずに行くとこういう景色になるという感じで、結果は褒められたものではなかったです。 ただ ISUCON は人それぞれのレベルで頑張れるイベントで知識が薄くても暇になるということはないという感じで、良いイベントだなーと思いました。 めちゃくちゃ楽しかったです。 ちなみにチーム名はこれ↓が元ネタです。 蟹を初めて見た上田晋也みたいなツイートを見て電車で大笑いしていてマジで恥ずかしい — kofuk (@man_2_fork) April 14, 2023 uta8a が詳しくブログに書いてくれました。 ISUC

Linuxのreadとrecvは何が違うのか

man 2 recv [Enter]ターン The only difference between recv() and read(2) is the presence of flags. With a zero flags argument, recv() is generally equivalent to read(2) (but see NOTES). (適当な訳) recv() と read(2) の違いは flags の有無のみです。flags が 0 のとき、recv() はほとんどの場合 read(2) と等価になります。 おわり というのもアレなので Linux kernel のソースを読んでどうなっているのか見てみることにしました。 僕は Linux ニワカなので見当違いなことを言っている可能性もあるのでまあそういうつもりで読んでいただけると……。 Linux のソースコードはたまたま手元にあったやつなので超適当ですが、よく見たら 2020 年のやつでした(思ったより古かった) Linux のシステムコールは SYSCALL_DEFINEn みたいなマクロで定義するので、適当に grep します。 すると read は fs/read_write.c recv は net/compat.c にあることが分かりま

Mesonのコードを読む (1)

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

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

備忘録。 出てこないなーとか思ってたら普通に書いてあった。 単に -D で指定するときに subproject名:オプション名 というふうに指定すればいいだけだった。 例えば subproject hoge でだけ warning_level を 3 にしたい場合は $ meson configure -Dhoge:warning_level=3 のように指定すれば ok。 ちなみにモジュール (meson.build の中で import とかして使うやつ) ごとのオプションは . で区切る。 なので pkgconfig の relocatable を true にする場合とかは -Dpkgconfig.relocatable=true とかを指定すればいい。 参考 Built-in options

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

入ってるパッケージが諸々古すぎるので、周辺のライブラリのビルドから始める必要がある。 そのへんを自動でやってくれるようにシェルスクリプトにまとめた。 /tmp に tmpfs がいなかったり、ホームディレクトリが NFS だったりする環境のものなので、_build_dir 系の変数は変更して使ったほうがいいと思う。 ビルド手順 まず、標準で入っている GCC は LLVM をビルドするには古すぎるので、GCC のビルドから始める必要がある。 古い LLVM から徐々にバージョンアップしていく方法でもいいが、最新の GCC はビルドできるので。ついでに 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;

ELF ファイルを適当に編集する方法

patchelf を使うと一発。elfedit というコマンドが binutils にあるっぽかったが、使い方がイマイチ分からなかった。 RPATH の追加 $ORIGIN/../lib を追加する例。ちなみに $ORIGIN はファイルがあるディレクトリを指すので、絶対パスを使うより柔軟にパスの指定ができる。 $ patchelf --add-rpath '$ORIGIN/../lib' NEEDED の追加 $ patchelf --add-needed libhoge.so.0 RPATH と NEEDED を組み合わせると LD_PRELOAD 的なことが環境変数なしでできる 下みたいな内容で適当なライブラリを作る。 int puts(const char *s) { return 0; } で、下みたいな内容の実行ファイルに patchelf する。 #include <stdio.h> int main(void) { puts("hoge"); } $ ./hoge hoge $ patchelf --add-rpath '$ORIGIN/lib' $ patchelf --add-needed 'libhoge.so.0' $ ./hoge (何も出ない) 実用性があるかは謎。

QEMUで雑に作るArch Linux ARMビルド環境

QEMU で起動するのが楽な Alpine Linux で aarch64 な Linux 環境を作り、 その中でブートストラップした Arch Linux ARM に chroot して使ってやろうというもの。 Alpine も Arhc も小さいのでビルドしようとするものによるが、tmpfs だけで戦える可能性が十分ある。 bazel と mozc のビルドをやったが、16 GB メモリのマシンで tmpfs しか使わずに作業が終わった (ビルド後にいらなくなった一時ファイルを消したりはしたが)。 準備 aarch64 の仮想マシンの実行には qemu-arch-extra が必要なので事前に入れておく。 Alpine のイメージを公式サイトから落としておく。 多分どれでもいいが、今回は standard を使った。 UEFI を使うため、edk2-armvirt を入れる。 QEMU のイメージの準備 サイズとかは適当に。後で拡張したりできるので大袈裟に気にす