相変わらず、騷しいう~さん
桜

「旦那、このたびは隠し玉を持っていましたね?」
『そやねん、出来るかどうか分からんネットワークに挑戦やからな』

「長いパス」対応の組み込みコマンド (nanoShell Tools)

1. 指定されたフォルダまたはファイルを複写する
 int copy( <folder[/wildcard]>, <folder> [," [sync] [progress]"])
 int copy( <file>, <file | folder> )
・名前 / サイズ / 日時 が異なるファイルのみ差分コピーする
・"sync" オプションを指定すると更に出力側にのみ存在するファイルを削除する(同期コピー)
   このメッセージは標準エラーに出力する (本体のメッセージは標準出力)

・ワイルドカード判定は、*、?、| を含む場合、
   または最後が ’.’ (ファイル名規約違反のため識別子として利用) の場合にワイルドカードと判断する
・ワイルドカードは、*→.*、?→.、.→\. に変換し、正規表現マッチする (大小文字を区別しない)
   こんな指定も可能です "[baz]*.txt|*.log"

・出力が (新規)フォルダの場合は、"foo/" と指定する

2. 指定されたフォルダまたはファイルを移動する
 int move( <folder[/wildcard]>, <folder>) [," [progress]"])
 int move( <file>, <file | folder> )
・"move"は入力側空フォルダ(Time0以外)を削除します

3. 指定されたフォルダまたはファイルを削除する
 int remove( <folder [/wildcard]> [," [root] [progress]"])
 int remove( <file>)
・ルートフォルダを指定する場合は "root" オプションが必要
・"remove"は空フォルダ(Time0以外)を削除します

4. 指定されたフォルダをコンパクトなツリー表示する
 int tree( <folder[/wildcard]> [," [file]"])
・"file" を指定するとファイル名を表示する

5. ファイルを一覧表示する (listSegment)
 int ls( <folder[/wildcard]> [," [path] | [0 | , | k] [260 | no260]"])
・ファイル長、0: 編集なし、, : カンマ編集、K: 単位変換 (属性を表示するためにはいずれかを指定する)
・path: ファイル長の代わりに パス長を sort キーとし使用するための編集("%, 7d")をして表示する
・260: 長いパスを表示、no260: 短いパス、省略: 全て

・ls はシェル連携をを考慮してタブ区切りで出力しています (日時、長さ、パス)

6. フォルダをクリーンアップする
 int clean( [," [clean] [noTime]"])
・"clean" オプションは空のフォルダを削除する
・"noTime"、標準ではフォルダの更新日時を子要素の日時に設定する(空フォルダは Time0(日時 0))

7. シェル変数を設定する
 int set( [," [var=val] …"])
・MAX_PATH=260 パスの最大長を指定する (tree、ls: 260、no260 オプションで使用)
・DISPLAY_WIDTH=40 パスを画面に表示する幅
・オプションを省略すると一覧表示します

8. その他、共通オプションなど
 プログレス: progress
・"copy", "move", "remove" で使用する
 ・リダイレクトと共存可能

 リダイレクト: [12]>{1,2} path
・リダイレクトは ①後続オプションが存在する場合は、パスをシングルクオートで囲む仕様です >'path'
   これは後続の一般オプションを食ってしまうためで、②オプションの最後に指定または、
   ③リダイレクト達のみの単独指定でも回避できます
   すなわち "/*オプション*/ 1>foo 2>bar /*ここにオプションは書けない*/"

・後続オプション問題を回避する 3+1つの方法
   ①空白を含むパスはシングルクオートで囲む (エスケープは、<\ '>、<' '>)
   ②(空白を含む)パスと(空白を含まない)拡張子を指定する
   ③(空白を含まない)拡張子無しパスを指定する
   ④リダイレクト達のみの ”単独オプション” を指定する
   ①で失敗( ' 抜け 2>'foo)すると→②→③とアルゴリズムを切り替えます

・パスは、DISPLAY_WIDTH 桁に切り詰めますが、リダイレクトの場合はそのまま出力する

 リカーシブ: noRecursive
・オプションは大小文字を区別しないで前方一致で比較する (コマンド内でユニークなら良い)
   "foo", "bar" では煩雑になるため "foo bar" 形式を推奨する
   否定オプション noRecursive はマイナスオプション -r[ecursive] に短縮可能です

 Windows ネットワークパス: UNCパス【Universal Naming Convention】
・パスの形式: //サーバ名(IPアドレス)/共有名/フォルダ・ファイル名
   共有の設定: ドライブまたはフォルダで右ボタン→プロパティ→共有→詳細な共有→アクセス許可
   共有名の最後の文字を”$”にすると、エクスプローラーの共有一覧に名前が表示されなくなる(隠し共有)
   (Linuxからは見えてしまいます、何か設定が必要なのかな?)
※ これを使用すると Windowsネットワークだけでなく "Samba"(Linux)マシンにも乗り込めます
   OSレベルレベルでサポートしているためアプリが意識するする必要が無いのが強みです

 0: 正常、1: インフォーメーション、2: ワーニング(マゼンタ)、3: エラー(赤)
・重大エラーは、throw するためあまり意味を持た持たないため、警告に使用しています

10. 外部コマンド呼び出し
 int system("<command> [<args...>] [>redirect]")

11. PowerShell 呼び出し
 int system("PowerShell <command> [<args...>] [>redirect]")

12. コマンドプロンプト呼び出し
 int system("CMD /C <command> [<args...>] [>redirect]")

※ ソースコード: plus/io/NanoTools.java

CHANGELOG

  • 2022-12-28 sort コマンドを Android nanoShell から持って来た
  • 2022-12-28 CSV ツールにカラム削除(del)機能を追加した
  • 2023-01-01 ls コマンドに path オプションを追加した
  • 2023-01-05 set (シェル変数の設定)コマンドを追加した
  • 2023-01-09 コマンドラインのパスを切り詰めて表示するようにした
  • 2023-01-12 コマンドの実行時間を表示するようにした
  • 2023-01-19 clean コマンドを追加した
  • 2023-01-24 progress 機能を実装した
  • 2023-01-26 リファクタリング開始
  • 2023-01-28 async I/O を実装した
  • 2023-02-04 clean コマンドの誤植を修正
  • 2023-02-05 move コマンドに ATOMIC_MOVE 機能を実装
  • 2023-02-10 clean コマンドの不具合を修正
  • 2023-02-18 リダイレクトの仕様を見直した
            (正規表現が妙な動作をするため諦めてましたが前方参照で解決しました)
  • 2023-02-20 ネットワークパスに対応 (UNC: Universal Naming Convention)
  • 2023-03-01 Linux に "Samba" をインストール開始
  • 2023-03-26 ギガイーサを導入開始
  • 2023-04-05 ギガイーサ開通

ギガイーサネットの世界へ - Enter the world of Giga Ethernet

今回の構成によく似た図を拝借しました。実際の構成は Linuxも Wi-Fiに接続しています
有線LANを導入し"Samba"と高速(ギガ)接続しようという魂胆です
この構成ではクロスケーブルの利用が可能でコストセーブできます fig1
/設定 /ネットワークとインターネット /アダプターのオプションを変更する
br

ギガイーサケーブルの調達

カテゴリ6(1G)は固く無理に曲げるとノイズが入るといったことを学習し購入

サンワサプライ カテゴリ6 クロスケーブル ¥743

  • UTP: シールドされていないツイストペアをより合わせノイズに強くしたもの
  • 単線: ノイズに強いが取り回しが悪化
  • 十字介在: ケーブル同士の接触を防止する十字のパーツ
  • クロスケーブル: 3m (内 1mは取り回し用)

理論的にはケーブル 1本で接続できるはずなので接続テストを行いました

  • 結果は「ユーザ、パスワードエラー」
  • アプリはこれらを認識していないため Windowsが処理していると仮定
    ("Samba"なら別の方法を検討する必要がある)
  • ネットワークパス(宛先)は サーバ名(IPアドレス)に従って処理している
  • そこで考えたのは Wi-Fiアダプタ(これが HOSTの IPアドレスを持っている)を後ろ建てに、
    ブリッジまたはルーター接続してはどうかと言う事です
  • 試行錯誤※の結果、あっさりと成功しました
    (※ 生半可な知識で別セグメント化したのが原因でした ^^);

参考記事

「ブリッジ、Windowsと Linuxをブリッジ接続する」
「ブリッジ、無料でパソコンを Wi-Fi中継機器にする」
「ブリッジ、ブリッジ接続で PCをハブ代わりに」
「ルータ、インターネット接続の共有で PCをルータ代わりに」

※ トラブルシューティング
「識別されていないネットワークの原因と対処法 (←設定をやり直すのが一番)」

※ 学習中に仕入れたネタ
「ルーターとは?」
「LANケーブルでネットの速度は変わる?」
「複数のNICを持つサーバのhostsファイルについて」
「IPアドレスとサブネットマスクをまとめて表記する」
「Google Public DNS (Wiki)」

検証開始

  • Windows 10: MEM: 8G、外付けSSD(USB3.0、500GB)
  • Linux Mint 21.1: MEM: 4G、HDD: 300GB
    (足腰が弱いため足を引っぱらなければ良いですが ^^);
  • Samba 4.15.13
  • 検証データ: ミュージック、30曲(8フォルダ)、2.1GB (曲数は以前の記事より減らしました)
    一部のベンチマークは、1773曲(180フォルダ)、65.5GB を使用しています
  • Wi-Fi環境
    5GHz帯域を利用(CATV,メタル)のため速くないです
    スピードテストの結果は Fast.com:20, Google:20, USEN:21Mbps(bits per second)
  • 1G イーサ

1.1 ATOMIC-MOVE モード

moveコマンドは、同一デバイスへのI/Oは最高性能(フォルダの付け替え)で動作します
※2,3 はネットワーク超えでもデータ本体は移動しないため同じ性能です

No. パス スピード データの流れ 備考
※1 //princess7/share/  0sec Win ⟳ ローカル共有SSD  直I/O
※2 //princess6/share/  0~1sec Win→Samba ⟳ HDD  Winで制御,SambaでI/O
※3 //prince6/share/  0sec Win→Samba ⟳ HDD  ※2 をギガ化

※3 ギガ化は接続先のサーバ名(//prince6, 正確にはNIC名)が異なるだけです!

※ Samba チューニング

  1. socket options = TCP_NODELAY
    Windows TCP/IPスタックの TCP ACKの送出が遅い問題を解消
  2. aio read size = 16384
    16KB を超えるリードは非同期 I/O を使用する
  3. ログを出力しない(HDD対策)
    log level = 0
    syslog = 0
※2 はチューニングの結果(1., 3.) 1 → 0sec になりました
  ちなみにアプリは 1 (Main) + I/Oに4 (論理CPU数)スレドを割り当てて動作しています

1.2 スクリーンショット ※2

AX

1.3 タスクマネージャ ※2 - 中央の波形が制御パケット

WiFiAX

2. Copyコマンド

No. パス スピード データの流れ 備考
※1 /home/share/  1:06sec Linux ⟳ HDD直 Samba,NWを除く素のLinux機の性能
※2 D:/share/  08sec Win ⟳ SSD直 素のWin機性能 Linux機の8倍
※3 //princess7/share/  10sec Win ⟳ ローカル/SSD ローカル共有, パケットは飛ばない
※4 //princess6/share/  1:13-16sec Win→Samba ⟳ /HDD 制御パケットのみ飛ぶ
※5 //princess6/share/  約47min Samba/HDD→エクスプローラ→/SSD ※4 (2.1GB) Wi-Fi (遅い)
※6 //princess6/share/  35~37min Samba/HDD→Win/SSD  〃
※7 //prince6/share/  25~28sec Samba/HDD→Win/SSD  ※6 をギガ化
※8 //prince6/share/m/  15min Win/SSD→(mount)→Samba→Win/SSD  HDDを使用しない構成 (65.5GB)

※5,6 Sambaに「16KB を超える read は非同期 I/O を使用」オプションを適用し 8min改善済み
※6 エクスプローラと大差ないと言う事は策は限られている(ギガの導入)ということですね

2.1 スクリーンショット ※7

AC

※6 Wi-Fiの場合、データ(2.13GB x 8bit) ÷ (36min x 60sec) = 8Mbps
(スピードテスト(20M)との差がここまでとは、近隣は 5GHz帯を使用使用していないため干渉はないです)

※7 Gイーサの場合、データ(2.13GB x 8bit) ÷ (28sec) = 609Mbps
グラフを見るとまだ余裕がありそうで、Linux(MEM, HDD)が足を引っ張っているようです

※7 左はアクセス全体、右はピークを狙い撃ちしたものです。イーサは理論値(982M)まで出るんですね!

G802G801

ギガイーサネットの彼方へ - Beyond Giga Ethernet

2.2 追加検証

ここで、ギガイーサに負荷をかけたいと思い、

  1. アプリを 2本投入 (ヘッドシークのベンチマークになり、失敗)
  2. Windows SSD を”samba”共有フォルダにマウントしたが、空 (やり方が悪いのかな?)
  3. ”samba”ユーティリティにマウントコマンドが有るのを思い出し試した
    (Windows共有フォルダをネットワーク越しに”samba”共有フォルダにマウントする)
    ※8 Windows SSD → (マウント,読み込み) → ”samba”共有フォルダ → (書き込み) → Windows SSD
    これで HDDを使用しない構成で検証できます
  4. USB3.0 SSDベンチマーク(CrystalDiskMark) Read:453MByte/s Write:413 (SSDのせいでないことを確認)
  5. ※8 データ(65.5GB x 8bit) ÷ (900sec) = 582Mbps (Linux機にはこの辺りが限界のようです)
 sudo mount -t cifs -o username=$USER,password=$PASS $SERVER $MOUNT

※ cifs-utils 日本語マニュアル
「 mount.cifs — Common Internet File System (CIFS) を使用したマウント」

※ 左が従来のグラフ、右は今回のグラフで送受信同時に転送しています
グラフがシャープで無くなった分??、若干スループットが落ちたようです
足すと Gを超えるため不思議に思ってましたがケーブルが送受信に分かれているため当然ですね?

G804 G805

まとめ

憧れのギガイーサのテストを行いました
カテゴリ5e, 6 はクロスケーブルが存在する(売れ筋の)ため安価にネットワークを構築できます
上には上(光ケーブル)がありますが、ギガイーサは学習教材として最適です

「パチパチ、怖いもの知らずですね~」『ネットを制覇すれば一流やな』

オープンソース

検証環境

  • Windows 10
  • Windows Terminal (オープンソース)、Windows PowerShell (オープンソース)
  • GNU Make (オープンソース)
  • Java 20 (オープンソース)
  • AWK˜plus for Java (オープンソース)

インストール

  1. Java をダウンロード(環境を汚さない .zip 版を推奨、複数の Javaもインストールできます)「Java Downloads」
  2. AWK~plus をダウンロード「AWK~plus for Java」 (コマンドを添付しています)
  3. AWK~plus フォルダ中の makefile の JAVAHOME 変数に Javaホームパスを設定する。

実行

ターミナルを開き、AWK~plus フォルダをカレントディレクトリにして、と入力する。

「Table of contents」 2023.04.12