お腹.ヘッタ。

関数型とかセキュリティとか勉強したい。進捗つらぽよ

関連と依存の違い関するメモ

これはJAISTの試験勉強をしててUMLを書いていた際に何が違うんだこれ?となったことのメモです。

ざっくり

参照関係と依存関係の違い

  • 参照関係: 具体的なクラスのインスタンスをフィールドや変数として保持し、そのインスタンスのメソッドやプロパティにアクセスする関係を指します。この場合、クラスAはクラスBを「参照」していると言います。
  • 依存関係: クラスAがクラスBの存在に依存しているが、そのインスタンスを直接保持していない場合を含みます。依存関係は、インターフェースの使用や一時的なオブジェクト生成など、より広い範囲の関係を指します。 上が依存、下が参照の例 http://yuml.me/diagram/scruffy/class/%2F%2F%20Sweet%20Class%20Diagram,%20%2F%2F%20-------------------,%20,%20%2F%2F%20Chain%20elements%20like%20this,%20%5BClient%5D-.-%3E%5BService%5D,%20%5BLibrary%5D-%3E%5BBook%5D.svg

くわしく

依存関係が描かれるケース

  1. Interfaceの利用:

    • : クラスAがクラスBのインターフェースを利用する場合、クラスAはクラスBのインターフェースに依存していると見なされます。インターフェースが変更されると、それを利用するクラスも変更を余儀なくされる可能性があるため、依存関係として描かれます。
     public class Client {
         private Service service;
    
         public Client(Service service) {
             this.service = service;
         }
    
         public void doSomething() {
             service.performTask();
         }
     }
    
  2. 一時オブジェクトの生成:

    • : クラスが他のクラスのオブジェクトを直接生成して利用する場合(new キーワードを使用)、依存関係が生じます。このケースでは、生成されるオブジェクトのクラスが変更されると、生成元のクラスにも影響を及ぼすため、依存関係として描かれます。
     public class OrderProcessor {
         public void processOrder() {
             PaymentService paymentService = new PaymentService();
             paymentService.processPayment();
         }
     }
    
  3. メソッドの引数として他のクラスを受け取る場合:

    • : クラスがメソッドの引数として他のクラスのインスタンスを受け取る場合も依存関係が描かれます。引数として受け取ったクラスが変更されると、そのメソッドを持つクラスにも影響が出る可能性があるためです。
     public class ReportGenerator {
         public void generateReport(DataFetcher dataFetcher) {
             dataFetcher.fetchData();
             // レポート生成ロジック
         }
     }
    
  4. 戻り値として他のクラスを返す場合:

    • : メソッドが他のクラスのインスタンスを返す場合も依存関係が生じます。呼び出し元のクラスがその戻り値に依存するためです。
     public class ServiceFactory {
         public Service createService() {
             return new ConcreteService();
         }
     }
    
  5. フィールドとして他のクラスを保持する場合:

    • : クラスが他のクラスのインスタンスをフィールドとして保持する場合も依存関係が発生します。この場合、フィールドの型やインスタンスのクラスが変更されると、そのクラスにも影響を与えるため、依存関係として描かれます。
    • ただし、これは参照関係でもあります。
      • クラスAがクラスBのインスタンスをフィールドとして保持している場合、クラスAはクラスBを参照していると言います。この参照関係は、クラスAがクラスBの具体的なインスタンスに直接依存し、そのインスタンスのメソッドやプロパティを利用するために使われます。
     public class Controller {
         private Repository repository;
    
         public Controller(Repository repository) {
             this.repository = repository;
         }
     }
    
  6. 例外処理:

    • : クラスが特定の例外クラスをキャッチまたはスローする場合、そのクラスは例外クラスに依存していると見なされます。例外クラスが変更された場合、依存関係を持つクラスにも影響が出る可能性があります。
     public void loadData() throws DataNotFoundException {
         // 処理
     }
    

まとめ

依存関係が描かれるケースは、インターフェースの利用や一時的なオブジェクトの生成に限られません。以下のようなケースでも依存関係が発生し、それがUML図に描かれます。

  • メソッドの引数や戻り値として他のクラスを使用する場合
  • 他のクラスをフィールドとして保持する場合
  • 特定の例外クラスをキャッチまたはスローする場合

依存関係は、クラスが他のクラスやインターフェース、例外、ライブラリなどに影響されるあらゆる状況で発生し、設計上重要な要素となりえるわけです。

Linuxカーネルへのパッチの出し方メモ

これは三ヶ月放っておいたら出し方忘れてしまって、えらく叱られてしまったのでそのためにメモしなおしたものです。とてもつらかった。。。。困ったらChatGPTを使いましょう。破茶滅茶な英文が幾分マシになります。なんか僕が失敗するたびにこのページは勝手に増えます。

最初に読むべきモノたち

チートシート

カーネルの修正

基本的には頑張ってコードを読む以外はなさそう。あたりを付けて書き換えるとかビルドするとか。 とりあえずbuildの仕方とかは載せておこうじゃないか。 基本的にはfullbuildは初回とか、rebaseしたりした時にいる感じ。

git clone git@github.com:takehaya/linux.git
cd linux
git checkout support_rss_gtp
# ubuntu case
sudo apt install linux-image-6.1.0-1008-oem linux-headers-6.1.0-1008-oem linux-modules-6.1.0-1008-oem
sudo sed -i 's/# deb-src/deb-src/' /etc/apt/sources.list
sudo apt update
sudo apt build-dep -y linux
sudo apt install libncurses-dev
mkdir ../build
make olddefconfig O=../build
cd ../build
make localmodconfig
make menuconfig

# build
# CONFIG_SYSTEM_REVOCATION_KEYS のキー情報を消し飛ばしておく
# ICEのコンフィグを有効にして行おう
# cf. https://qiita.com/MNT_QU/items/4b86e56731320f033c3e#config%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
make -j64 LOCALVERSION=-rss-custom-01
make modules -j64 LOCALVERSION=-rss-custom-01

# package
make bindeb-pkg -j64 LOCALVERSION=-rss-custom-01

# local install
# sudo make modules_install
# sudo make install
sudo apt install ../*.deb

debugのためにビルドして再度適用するときはこちら

make modules -j64 LOCALVERSION=-rss-custom-01
sudo cp drivers/net/ethernet/intel/ice/ice.ko /lib/modules/6.3.0-rc6-rss-custom-01/kernel/drivers/net/ethernet/intel/ice/ice.ko 

sudo modprobe -r irdma
sudo modprobe -r ice
sudo depmod -a
sudo modprobe ice

強いて言うならばこれが参考になるかもしれないですね(古いけど!) https://knqyf263.hatenablog.com/entry/2019/07/01/152643

パッチの送信方法

送るための前準備

# patchのコードスタイルが合っているかどうかを見る
# これが何も出なくなるまで頑張る。
git diff HEAD^ | scripts/checkpatch.pl

# singoff by と言うのをすることでコードに対して署名をする
git config format.signOff yes

# sendemailをするときの対象者を設定する
# (これは特定のgit管理されてるリポジトリで行う)
# に実態が置かれてる
git config sendemail.to "$(git diff HEAD^ | ./scripts/get_maintainer.pl --separator , --nokeywords --nogit --nogit-fallback --norolestats --nol)"
git config sendemail.cc "$(git diff HEAD^ | ./scripts/get_maintainer.pl --separator , --nokeywords --nogit --nogit-fallback --norolestats --nom)"
# ちなみにさらにメールを明示的に追加するならこんな感じである
# git config sendemail.cc "$(git diff HEAD^ | ./scripts/get_maintainer.pl --separator , --nokeywords --nogit --nogit-fallback --norolestats --nom) mailhol.vincent@wanadoo.fr vladimir.oltean@nxp.com"

# smtpの設定などを.gitconfigに入れておく
# 80文字で折り返すようにしておくといいが、実際には手動でぽちぽちやることになるのでなくてもいい。
~/private/linux$ vim ~/.gitconfig 
[sendemail]
       smtpserver = smtp.gmail.com
       smtpuser = hayatake396@gmail.com
       smtpencryption = tls
       smtpserverport = 587
       smtpPass = aaaaaa
       annotate = yes
[format]
        wrap = 80

実際に送りつける

# 単一のちょっとしたパッチはこれで送りつけて大丈夫
# パッチのバージョンに合わせてv6とかv7,v8...に上げていく必要がある
git send-email --annotate -v6 --subject-prefix='PATCH net-next' HEAD

# 意味が変わるようなパッチであれば二つに分割したりする必要がある。例えばuapiとそれに基づいて作られるdriveの機能とか(ethtool.hとiceドライバに関する機能)とかね
# 以下のコマンドで二つのパッチを同時に出せる
git send-email --annotate -v6 --subject-prefix='PATCH net-next' -2 HEAD

# パッチを同時に二つコマンドを実行すると以下のように出てくる。同時に二つ出すのは明示的にパッチシリーズであると言うことにするためだ。
# ここには見えてないがcommit messageとパッチの画面が出てくるのでそこでeditをしよう。
# ちなみに本当にパッチが二つになってるか知りたい場合は、以下に見える /tmp/hoge/v[0-9]-000~が2個あるかどうかで確認しよう。
~/private/linux$ git send-email --annotate -v7 --subject-prefix='PATCH net-next' -2 HEAD
/tmp/B_FPb86TTd/v7-0001-ethtool-Add-GTP-RSS-hash-options-to-ethtool.h.patch
/tmp/B_FPb86TTd/v7-0002-ice-Implement-RSS-settings-for-GTP-using-ethtool.patch
2 files to edit
(mbox) Adding cc: Takeru Hayasaka <hayatake396@gmail.com> from line 'From: Takeru Hayasaka <hayatake396@gmail.com>'
(body) Adding cc: Takeru Hayasaka <hayatake396@gmail.com> from line 'Signed-off-by: Takeru Hayasaka <hayatake396@gmail.com>'

From: Takeru Hayasaka <hayatake396@gmail.com>
To: Jesse Brandeburg <jesse.brandeburg@intel.com>,
        Tony Nguyen <anthony.l.nguyen@intel.com>,
        "David S. Miller" <davem@davemloft.net>,
        Eric Dumazet <edumazet@google.com>,
        Jakub Kicinski <kuba@kernel.org>,
        Paolo Abeni <pabeni@redhat.com>,
        Jonathan Corbet <corbet@lwn.net>
Cc: intel-wired-lan@lists.osuosl.org,
        netdev@vger.kernel.org,
        linux-doc@vger.kernel.org,
        linux-kernel@vger.kernel.org,
        mailhol.vincent@wanadoo.fr,
        vladimir.oltean@nxp.com,
        laforge@gnumonks.org,
        Takeru Hayasaka <hayatake396@gmail.com>
Subject: [PATCH net-next v7 1/2] ethtool: Add GTP RSS hash options to ethtool.h
Date: Thu,  1 Feb 2024 03:33:09 +0000
Message-Id: <20240201033310.1028154-1-hayatake396@gmail.com>
X-Mailer: git-send-email 2.34.1
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

    The Cc list above has been expanded by additional
    addresses found in the patch commit message. By default
    send-email prompts before sending whenever this occurs.
    This behavior is controlled by the sendemail.confirm
    configuration setting.

    For additional information, run 'git send-email --help'.
    To retain the current behavior, but squelch this message,
    run 'git config --global sendemail.confirm auto'.

Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): y

# この時、yを押すと一つずつパッチが送られる。aを押すと全部送ってくれる感じである

気をつけた方がいいこと

コミットメッセージは80文字で切る

注意点としては文章の区切りで改行を入れるのではなく、コンテキストが続くものは連続で書くべきである。 例えば以下が正しい例である

commit 739a0aac9d26ce2b51bb5ec2da46c8db91129b58 (HEAD)
Author: Takeru Hayasaka <hayatake396@gmail.com>
Date:   Thu Feb 1 03:11:04 2024 +0000

    ice: Implement RSS settings for GTP using ethtool
    
    Following the addition of new GTP RSS hash options to ethtool.h, this patch
    implements the corresponding RSS settings for GTP packets in the Intel ice
    driver. It enables users to configure RSS for GTP-U and GTP-C traffic over IPv4
    and IPv6, utilizing the newly defined hash options.
    
    The implementation covers the handling of gtpu(4|6), gtpc(4|6), gtpc(4|6)t,
    gtpu(4|6)e, gtpu(4|6)u, and gtpu(4|6)d traffic, providing enhanced load
    distribution for GTP traffic across multiple processing units.
    
    Signed-off-by: Takeru Hayasaka <hayatake396@gmail.com>

これを悪くしてみよう。例えば怒られた例だとなるべく句読点で改行したり、適当なはちゃめチヤなところで切ってるやつである。これは正しくするならば、80行ギリギリになる単語で切る。同じ文章のまとまりで初めて改行を入れるべきである。本来であれば二つの塊で問題ないのに、3つの塊にしてたり、80文字までまだまだ単語が入るのに変な位置で切っていると言うのが問題である。

commit 739a0aac9d26ce2b51bb5ec2da46c8db91129b58 (HEAD)
Author: Takeru Hayasaka <hayatake396@gmail.com>
Date:   Thu Feb 1 03:11:04 2024 +0000

    ice: Implement RSS settings for GTP using ethtool
    
Following the addition of new GTP RSS hash options to ethtool.h,
this patch implements the corresponding RSS settings for
GTP packets in the Intel ice driver. 

It enables users to configure RSS for GTP-U and GTP-C traffic 
over IPv4 and IPv6, utilizing the newly defined hash options.

The implementation covers the handling of gtpu(4|6), gtpc(4|6), 
gtpc(4|6)t, gtpu(4|6)e, gtpu(4|6)u, and gtpu(4|6)d traffic, 
providing enhanced load distribution for GTP traffic across 
multiple processing units.
    
    Signed-off-by: Takeru Hayasaka <hayatake396@gmail.com>

正しく空白行を入れる

引用形式の文を書く

レビューをしてくれた人からメールが来るだろう。 その時には相手の文章に対して返信を書くことになるはず。

> 相手の文章

自分の意見

> 相手の文章

自分の意見

と言った感じで書くことがいい ちなみにだが、gmailとかでメールを返信するときは Content-Type: text/plain; にしなくてはいけないので注意。 この辺が参考になりそうです。 https://www.kernel.org/doc/html/next/process/email-clients.html https://nekomatu.blogspot.com/2014/05/howto-send-patch-to-linux.html

パッチの revisionをするとき

こんな感じでrevisionをするときにv1,v2とかの差分をここに書いてあげると親切らしい。

Signed-off-by: Takeru Hayasaka <hayatake396@gmail.com>
---
v2->v3: Based on Harald-san's review, I added documentation and comments to
ethtool.h and ice.rst.
v3->v4: Based on Marcin-san's review, I added the missing code for GTPC and
GTPC_TEID, and revised the documentation and comments.
v4->v5: Based on Marcin-san's review, I fixed rename and wrong code regarding
GTPC
v5->v6: Based on Marcin-san's review, Undoing the addition of unnecessary
blank lines.Minor fixes.
v6->v7 Based on Jakub-san's review, Split the patch.
 include/uapi/linux/ethtool.h | 48 ++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

CIが落ちたりしたので再度叩き込む時

中身は大きく変わるわけではないが、CIが落ちたりしたので再度叩き込む時に必要だったりする。 RESENDをつけることでレビュワーの混乱を防げる。

git send-email --annotate -v7 --subject-prefix='PATCH net-next RESEND' HEAD^

自分のパッチの送付を確認するとき

https://patchwork.kernel.org/project/netdevbpf/list/?submitter=210976 とかpatchworkを見るのが良い。

https://lore.kernel.org/all/20240201033310.1028154-2-hayatake396@gmail.com/ とかでメーリングリストにタイトルを入れるのも良い。

PyCon APAC 2023で発表してきました

Why

今後もいろんなところでCfPを出していくぞ!というメモ書きとして書き残すためにこれを書きます。

What

PyCon JP 2023はPyCon APAC 2023として開催されました。APACが日本で行われるのは10年ぶりの開催だそうです。

どうせ参加するなら発表したいなーと思ってプロポーザルを出したところ、採択していただけたのでスピーカーとして参加しました。

発表内容について

今年の私のトークタイトルは 「自作パケット処理系の性能測定と可視化&改善のPDCAを回して最強のパケット処理系の作り方を学ぼう」 でした。

speakerdeck.com

実は初参加でした。PyConJP自体は存じ上げてたのですが、今まで地方に(今も?)住んでいるので参加には大変敷居が高かったというのがあり初参加・初スピーカーという感じでドキドキでした。

PyConと言いつつ少しPython感は薄い感じになりましたが転職して戻ってきて一年でちゃんと対外発表できる感じでだったのでよかったです。

CfPを練るにあたっての所感

発表内容については実は合計二本出していて、「ExaBGPにSRv6MUPを入れた話」と今回の「PGW-Uに対して負荷計測を行った話」を出していました。

前者はIETFのネームバリューとかOSSに初めて新機能入れました!みたいなセンセーショナルさで攻めてみたCfP、後者は学びや再現性がある話を売りにして攻めてみたCfPで書いました。結果としては後者に関して拾ってもらえてよかったです。

自分はこのように大きいところで話すのは初めてだったのでおすすめタイトルは何かを調べました。

speakerdeck.com

次にトラックの選び方の話とかプロポーザルの参考例を眺めてやりました。

あとはプロポーザルの選択基準が明確に出されてたのでこのように書き出して強みってなんだろー?と思いながら書き出してました。

## どういう話にするか&どういう強みがあるか
### Python 初心者にとって自らの知見を広げる内容か
~なさそう~ ネットワークの処理系に関しても使えるんだぞ!という分野自体を伝えれるかも

### Python が社会で活用されている具体的なイメージを描けるか
SDNやNFVと言われているサービスというのは自分たちの手で実装可能なことが知られているが、どのように品質を担保するかはあまり知られていない。ネットワーク製品を良くするために使われてるというイメージを持ってもらえる

### 内容に独自性・新規性はあるか
Trexでどのようにしてデータを持ってくるとか細かい実装レベルについては書いてないので、そういうのを書いてもいいかも

### トークの発表が明確にイメージできるほど構成は詳細に書かれているか
本文の詳細を見てイメージできるように書き出してみる
- 背景とモチベ
  - 弊社ではフルMVNO事業をやっており、その中のPGW-Uと呼ばれるインターネットに出るための自作パケット処理系の通信効率の性能を上げることが求められていました
  - そのためにpython製のツールとライブラリを駆使して計測し高速化をしました
- 話す内容
  - 私たちは、XDPと呼ばれるeBPFを使った高速パケット処理技術を使って実装しています
  - 性能試験を通した改善プロセスでは、負荷試験のパケット生成・テスト結果の記録・メトリックの分析など多くの場面で Python を活用しています
  - それぞれの場面での活用事例を紹介します
    - scapy で TRex のパケット生成にモバイル網で使うプロトコルのパケットを追加しました
    - 性能試験のテスト完了後、性能指標を TRex から取得し Pushgateway で記録しました
    - Jupyter Lab 上で Grafana 経由の CSV ファイルを pandas.DataFrame に加工し、可視化や評価を行いました
  - 性能試験を通じた改善例
    - 大容量のエントリを流した際にメモリ使用量が大きくなるとコケる問題を発見して修正した事例
    - パケットのcheck sumの処理で遅くなったので処理性能を向上させるためにchecksum機能をoptoutする機能を追加した事例
    - 特定のパケットに対してマルチコア対応がされていないことを発見して、IntelのNICドライバに機能を追加してマルチコア対応させた。その結果$(nproc| CPUコア数)倍の効率アップができた事例

### コミュニティの国際交流に寄与するか
わからん。。。

### Python を使う「楽しさ・熱意」をアピールできるか
ぶっちゃけscapyがすごいんだけど、pythonで好きなパケットをホイホイ投げれるのは良い

### 聴衆が具体的に持ち帰ることができる知識や技術の利用方法・工夫があるか
自社のネットワーク製品を検証できるフレームワークやコードを提供できる

その他の雑感

参加について

スピーカーは本会議前日に特別招待されたイベントに参加できました。 が、普段のネットワークの人たちは全くいないので知り合いがいなくてそれなりにぼっちで辛かったです(かなりクラスタが違うし、コミュ障には厳しい)

IETFとかみたいに始めまして参加者限定パーティーとかそういうのがあったら嬉しかったなーと思いました

発表聴講に関して色々クラスタを見てると体感3-4割ぐらいがMLっぽい人が多いなーとか思いました。 NetworkX!?ネットワークの人がいる〜!と思ってノコノコ行ったらニューラルネットワークのネットワークでorzとなりました。

ただMemrayの発表とかはなるほどーとなって面白かったです。スレッド間の話とかをしてなかったのでもうちょい深い話を聞きたかったんですが色々聞いた感じ発表内容的にはオーバービューみたいな発表が好まれるのだなーと思いました。Qiitaとかにあるチュートリアルやってみました。こんなこともできるらしいです!ぐらいの感じが一番ウケそうだなぁと思いました。

実際自分が登壇する時はクラスタ的に全然きてくれないかも・・と不安で参加前についてはTwitterで極力宣伝しまくりました。結果としては30人ちょいぐらいは来てくれてたので0人じゃなくてよかったのかなと思います。宣伝後も登壇した資料を公開してそれなりにPVしてもらうことはできました。きっとJANOGとかIWならもう少し来てくれる人が居たかもなーと思ったりしましたがこれも学びです😇

ちなみに懇親会でとあるプログラム委員と話したところ、投稿してる人が少ない分野でちゃんと描いてると通りやすいんだよねーという話を聞きました。なので今回ネットワークプログラミングに関するトラックで選択して投稿したのはよかったなと思います。

発表方法について

発表練習は個人で行い、スピーカーノートにはある程度文章でスクリプトを描きました。発表資料・言語は日本語なので緊張はしましたが話が飛んでしまうということはなかったかなと思います。

反省点として自分の発表は本当にLTみたいな早口詰め込み発表でしたので要点を絞る訓練をした方がいいと思いました。また資料に不必要な図の引用をしてたので社の先輩に指摘されてしまったというのがあり、ある程度フォーマルな場所での発表の仕方というのを身につけた方がいいなと思いました。詰め込んだことに関しては、スライドの狙いとして後から見返して嬉しくなるようにしたので仕方ないんですが果たしてここの発表でそれは適切だったのかは悩ましいです。その点で唯一良かった点は初め20-30秒QRコードを出してスライドをぜひお手元でご覧ください!という話をしたのは直前で追加した動きでしたが良かったです。

そろそろ若手社員という枠じゃ無くなりそう(今3年目😇)なので何とか身につけたいです。。。

早口なものだった話は、多少言い訳すると30分の発表で募集されてたので30分まるまる使えるものだと思っていました。

が、実際発表する時に初めて25分で残り5分は質疑と書かれており・・・この辺は登壇時に気をつけることという旨の資料上で事前アナウンスされてなかったので大変焦りました。この辺はあらかじめちゃんと確認しておくと良いなと思いました(反省)

発表後に気がついたんですが、発表に関しても pyconの運営の人たちがノウハウを出してくれてたので見ておくとよかったなーと思いました。 (全然見つけれなかったのでいろんなところでこういう資料を宣伝して欲しかったw)

tv.pycon.jp

linux kernel をbuildしてinstallしたら立ち上がらなくなった時のメモ

言ってる通り立ち上がらなくなった。 とてもつらい気持ちになったのでそれをどうやって解決しましたか?というメモです。

こういうのがネットに転がってるとマジでありがたいので感謝の意を込めて晒しておきます。

前提として

  • grubすら上がらない設定にしてしまった
  • idracとかから busybox のshellに対して書き込みができなくて終わってしまった
    • なんで idracから触れないのか... :innocent:
  • kernel build して make install したら死んだ

こんな感じの顔をして死んでた。linuxさんの色々なアヘ顔って感じです

Gave up waiting for root device. Common problems:
  — Boot args (cat /proc/cmdline)
    — Check rootdelay= (did the system wait long enough?)
    — Check root= (did the system wait for the right device?)
  — Missing modules (cat /proc/modules; ls /dev)
ALERT! /dev/mapper/ubuntu--vg-root does not exist. Dropping to a shell! 

BusyBox v.1.21.1 (Ubuntu 1:1.21.1-1ubuntu1) built-in shell (ash)   
Enter 'help' for list of built-in commands.  

(initramfs)

直し方

  • 雑にUSBライブブートをなんかでします。ubuntuとかでも良いです。
  • ライブブートからshellを触れる様にします。
  • とりあえず何も考えず ubuntu server のイメージを使いました。
# shellが触れてたら fdiskで対象のジャーナルを探す
fdisk -l 

# 雑に dev を見たら色々あるのでそれっぽいのをmountする
# sda1がefi, sda2がboot, sda3 が lvという感じ
mount /dev/ubuntu-vg/ubuntu-lv /mnt
mount /dev/sda2 /mnt/boot

# 後から chroot をするときに触りたい環境情報があるものをマウントして使える様にしておきます。これがないとFSとか触れなくて困る。
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys

# chroot いわゆるコンテナ化みたいなやつです。(雑
# これで自分の壊したSSDとかのデータにログインするみたいなことができる
chroot /mnt /bin/bash

# 起動のオプションとかインストールが失敗してるだろうからこれで入れ直し
# カーネルのバージョンは /boot/ とかに転がってるファームから分かる。
# /etc/default/grub とかに設定があるからそれを書き換えたりも出来る
grub-install /dev/sda 
update-initramfs -u -k [カーネルのバージョン]

# 後片付け
exit
umount /mnt/dev
umount /mnt/proc
umount /mnt/sys
umount /mnt/boot
umount /mnt

sudo reboot 

これで戻ってくるのを信じてもう一度トライ。 これで治らなかったらもっと頑張りましょう(完

もし無理なら /mnt が出来る時点で /home/user/ が手に入るのでそこにあるものをZIPしてどこかに投げつけるとかでレスキューしてOS入れ直しとかをすると良いと思います。

参考

VPP上の開発・デバッグ方法テクニック

ビルド方法やテストの実行テクニックに関してはVPPにSRv6 MUP Plugin APIを追加している話開発方法とパッチを出すときの Tips に書いたりしてるわけですが、もう少しフォローアップする話があってもいいかなー(書いとくと後で思い出すのに便利)と思い記事を書きました。

この記事は自分が便利だと思った物を追記してくスタイルなのでサイレントで更新されたりします。

プログラムのデバッグ方法

ここでは printf ではもう辛くなった人向けです。たとえばCに慣れてなくて初期化されてなくて困ってるとかそういう人が便利に使う想定です。

AddressSanitizer

アドレスサニタイザーってやつです。VPPはマルチスレッドな感じでvalgrindが使えない環境なので使うと便利だったというやつです。 詳しくはここを見ると良さそう。

s3-docs.fd.io

make build VPP_EXTRA_CMAKE_ARGS=-DVPP_ENABLE_SANITIZE_ADDR=ON

GDB

gdbなので使い方はググってくれ

世の中にはいい記事がいっぱいあります。 https://uguisu.skr.jp/Windows/gdb.html

make debug

Trace

コードレベルではなく、設定や構成レベルのデバッグに有用です。

# VMのNICがある部分からパケットを受け取るときはここを見る
trace add dpdk-input 10
show trace
clear trace

# VTAPなどの部分からパケットを受け取るときはここを見る
trace add virtio-input 100
show trace
clear trace

# それぞれの処理nodeへの着信カウンターを見ることでどの処理が多く動いてるかがわかる
show runtime

packet trace

https://vps3-docs.fd.io/vpp/23.06/cli-reference/clis/clicmd_src_plugins_dispatch-trace.html

# pcap をtx側のものを全て取得する
pcap trace tx on

# 取得したものを書き出し(/tmp/tx.pcapに書き込まれる。 txをrxに置き換えても成り立つ仕様)
pcap trace tx off

pluginの有効化と Linux-CPの利用法

confの中に以下のように入れることで pluginが有効化されます

plugins {
  plugin linux_cp_plugin.so { enable }
}

linux-cp設定例

tap(つまりただのL2の分岐機能です)を使うことで hostのlinuxに入れれて便利という話があったりしますが、これはそれはうまいことlinux側と協調動作するというわけではないです。

そこでlinux-cpを利用するとVPPとLinuxが協調動作します。つまりVPPを普通のlinuxっぽく利用できます。 詳しくはこの一連の記事を見るのがおすすめです。

これを利用することでLinuxでVPP+FRRを動作させてBGPを話すサーバーとして使うことができます。

ipng.ch

(ちなみに、以前はvppsbの中にrouterプラグインがあって、それは特定プロトコルだけ分離してcplaneに投げてくれるいわゆるtap-inject機能がありましたが、それはもう古いのでlinuxcpを使いましょう)

# lcp use netlink
cat << EOF > /etc/sysctl.d/81-vpp-Netlink.conf 
# Increase Netlink to 64M
net.core.rmem_default=67108864
net.core.wmem_default=67108864
net.core.rmem_max=67108864
net.core.wmem_max=67108864
EOF
sudo sysctl -p

VPP

set interface state eth1 up
set interface ip address eth1 172.0.1.2/24
set interface state eth2 up 
set interface ip address eth2 fc00:12::1/64

loopback create-interface
set interface state loop0 up
set interface ip address loop0 fc00:1::1/64

lcp lcp-sync on
lcp lcp-auto-subint on
lcp create eth1 host-if eth1
lcp create eth2 host-if eth2

linux

sudo ip link set eth1 up
sudo ip addr add 172.0.1.2/24 dev eth1
sudo ip link set eth2 up
sudo ip addr add fc00:12::1/64 dev eth2

ExaBGPにSRv6 MUPを実装をした時のメモ

Why

exaBGPに MUP-BGP を追加しました。パッチを出すのにちょくちょく困ってたのでメモを公開しておきます。

当該パッチはこちら github.com

使い方はこちらgobgpとの相互接続例をこのリンクで示してます。

追記: CML2で遊べるように cloudinitファイルを書いてみました。宜しければどうぞー

設計に関しての勘所

大きくわけて設定のためのパーサーとパケットのパーサーを書くというのが、BGPに機能を実装するということです。

具体的には前者のあたりはsrc/exabgp/configuration/を中心としたコード、後者は src/exabgp/bgp/message/update/を中心としたコードに手を加えることになります。

例えば前者のコードで announce セクションで動作するには 例えば@ParseAnnounce.register('mup', 'extend-name', 'ipv4') といったデコレーターをつけた上でパーサーコードを作り、先ほどの後者で記述されるTypeに合わせた設定を返します。

詳しくはPRにあるコードを見てください。

デバッグとtest方法

これはpythonなのでデバッグには import pdb;pdb.set_trace() を使うのが一番便利です。実質ブレークポイントなのでこれを入れて保存して実行してあげるのが良い感じです。 また、パケットの構造がミスってるかどうかを知りたい場合は受け取る方を行う方がわかりやすいです。理由としては受け取り側はstack traceが出るようになっていて尚且つ Notificationメッセージなどでわかるケースがあるからです。

他にもこのようにログとしてもヒントが出てきたりします。13:22:02 1656739 outgoing-13 >> NOTIFICATION (3,0,“invalid ipv4 mup next-hop length 16 expected 4”)

パースの方だと先ほどのような stack trace が出てこないので気をつける必要があります。

デバッグを通じて完成した場合はテストを書いてあげることもしたくなるはずです。 etc/exabgp/<confname>.conf (合わせてqa/ci/<confname>.ci<confname>.confと書いてあげる必要があります)に設定を書いてあげる必要があります。 これは実装物の設定例になる物です。

詳しくはPRを参照すると良いですが、肝は neighbor 127.0.0.1 にした上でコンフィグを設定し、exabgp -d <confname>.conf-d オプションを追加した上でログからupdateメッセージを取得して qa/ci/<confname>.msgに加筆する必要があります。

以下にgobgpの設定とexabgpの設定、先に示したようなgistに書いたネットワークを変形させたnetnsを示します。

#!/bin/bash

set -eu

if [[ $(id -u) -ne 0 ]] ; then
    echo "Please run with sudo"
    exit 1
fi

run () {
    echo "$@"
    "$@" || exit 1
}

destroy_network () {
    run ip netns del red
    run ip netns del blue
}

stop () {
    destroy_network
}

trap stop 0 1 2 3 13 14 15

# exec functions
run ip link add veth-red-blue type veth peer name veth-blue-red

run ip netns add red
run ip link set veth-red-blue netns red
run ip netns exec red ip link set up lo
run ip netns exec red ip link set up veth-red-blue 
run ip netns exec red ip addr add 10.0.0.1/24 dev veth-red-blue

status=0; $SHELL || status=$?
exit $status

gobgp.toml

[global.config]
    as = 65000
    router-id = "127.0.0.1"

[[neighbors]]
    [neighbors.config]
        peer-as = 65000
        local-as = 65000
        neighbor-address = "127.0.0.1"
    [[neighbors.afi-safis]]
        [neighbors.afi-safis.config]
            afi-safi-name = "ipv4-mup"
    [[neighbors.afi-safis]]
        [neighbors.afi-safis.config]
            afi-safi-name = "ipv6-mup"

exabgp.conf

neighbor 127.0.0.1 {
    router-id 10.0.0.1;
    local-address 127.0.0.1;
    local-as 65000;
    peer-as 65000;

    family {
            ipv4 mup;
            ipv6 mup;
    }
    announce {
        // gistを参考に所望のannouceを記述する
    }
}

これらの設定コンフィグを保存した後は以下のようにして実行します。

# red
sudo ip netns exec blue gobgpd -f ./gobgp.toml

# separate terminal exec
sudo ip netns exec red \
    /home/ubuntu/exabgp/sbin/exabgp \
    -d -v\
    ./exabgp.conf

以下のように update messageがログに流れるはずです。

23:19:14 1720215 rib             insert mup:t1st::100:100:2001:db8:1:1::1/128:12345:9:128:2001::1 extended-community target:10:10                                                    [733/1918]
23:19:14 1720215 rib             insert mup:t2st::100:100:12345:128:2001::1 extended-community target:10:10                                                                                    
23:19:14 1720215 outgoing-1      sending TCP payload ( 128) FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 0080 0200 0000 6940 0101 0040 0200 4005 0400 0000 64C0 1008 0002 000A 0000 000A C028 2505 0022 0001 001E 0020 010D B800 0100 0100 0000 0000 0000 0000 0048 0001 0006 4018 1000 0000 800E 2500 0155 1020 0100 0000 0000 0000 0000 0000 0000 0100 0100 010C 0000 0064 0000 0064 180A 0001
(中略)
23:19:14 1720215 outgoing-1      >> 8 UPDATE(s) 

そしたらこの outgoing-1 のバイナリ列がupdate messageになっているのでそれを取得して整形します

整形する形は以下のようにします

1:raw:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:0080:02:000000694001010040020040050400000064C010080002000A0000000AC028250500220001001E0020010DB800010001000000000000000000004800010006401810000000800E250001551020010000000000000000000000000001000100010C0000006400000064180A0001

肝としては、接頭子にルールナンバーとtype,あとは取得したログの空白行を消して、初めのFの連続までをコロン、0080をコロン、02をコロンにして記述します。 ざっくり中身を説明すると

  • F~F: marker
  • 0080: lenght
  • 02: update message type

あとは以下のコマンドを実行して testが動作するかを見ます。これの作業を加えることで機能のテストが無事完了します。

./qa/bin/functional encoding

追記(2023/3/20)

もっと便利な方法があったのでメモしておく。 (ついでに引っかかりポイントも) まず引っかかりポイントとして何かしらの原因で test processが動いてるゆえにテストがゾンビ化してそちらにテスト実行時に繋がってしまい大変困るケースがある。遠慮なく pkill -f python3 とかで殺しておこう。

で、テストの時にnetnsとかはだるいと思うのでどうするかというとupdate messageを見るのではなくて、テストのunexpect エラーから取ってくると楽。具体的には以下のようなイメージ。この時の B は区別されてる列記としたラベルで以下のように list オプションで確認できる。

./qa/bin/functional encoding --list

./qa/bin/functional encoding --server B

./qa/bin/functional encoding --client B

こんな感じで出てくる。エラー自体のタイミングでクライアントの接続を切断されるので、そこではupdate messageと合わせて突き合わせれば良い。

new session:                                                                                                                                                                  
open recv   FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:0047:01:04FDE800B40A0000012A02060104000100010206010400010055020641040000FDE8020C400A80B4000101800001558002020600                 
open sent   FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:0047:01:04FDE800B40A0000022A02060104000100010206010400010055020641040000FDE8020C400A80B4000101800001558002020600                 
msg  recv   FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:0013:04:                                                                                                                         
msg  recv   FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:0017:02:00000000                                                                                                                 
msg  recv   FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:001E:02:00000007900F0003000155                                                                                                   
msg  recv   FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:0030:02:00000015400101004002004003040A0001FE400504000000C8180A0001                                                               
msg  recv   FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:0080:02:000000694001010040020040050400000064C010080002000A0000000AC028250500220001001E0020010DB8000100010000000000000000000048000
10006401810000000800E250001551020010000000000000000000000000001000100010C0000006400000064180A0001                                                                             
msg  recv   FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:001B:02:0004180A00010000                                                                                                         
                                                                                                                                                                              
unexpected message:                                                                                                                                                           
received    FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:001B:02:0004180A00010000      

終わりに

ドキュメントやコードは見やすいように整備されてて、迅速なレビューが素晴らしいですがciとmake fmtのルールが異なったり長い間使われてるOSSなので多少レガシーであることは事実でコードのメンテナンスは難しいなぁと思いました。

一方初めてBGPの機能実装を行いましたが比較的簡単に実装できるOSSというのは良い作品だと思ったのでぜひ今後も機会があればコントリビュートしていきたいと思いました。

EdgeRouterXが息をしてない時にやるやつ

要約

  • edgerouterx が上がってこない時は多分kernel panicを起こしてるのでリカバリーが必要。
  • USB TTL が必要になる

突然の死

なんか上がってこない

なおしかた

この記事を見て(完) yaaamaaaguuu.hatenablog.com

にならなかったので今回は書いています。

上の記事を見てもダメだった時に参考にしてください。

自分の場合はこのようなエラーが出てて、要はFSごと死んでたという話でした。この場合だと上記のような手順では復活できなくて困りました。

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

ググるとこんなのが出てきて Edgerouter X wiki points to not working .BIN and other thingies - #14 by zett - Installing and Using OpenWrt - OpenWrt Forum

どうやら公式のマニュアルがあるようです。 https://help.ui.com/hc/en-us/articles/360018189493-EdgeRouter-Manual-TFTP-Recovery#3

公式で出ているイメージ ER-e50.recovery.v2.0.6.5208541.190708.0508.16de5fdde.imgER-X-SFP / ER-X / EP-R6 / ER-10X (e50) をクリックして持ってきて記事通り焼くだけ。

同じように困ってしまった人は参考にしてください。