SCHEDULER — QosOrch SchedulerOrch コード由来デフォルト詳解¶
概要¶
orchagent の QosOrch::handleSchedulerTable() が CONFIG_DB SCHEDULER テーブルを処理する。各フィールドは存在する場合のみ SAI 属性リストに追加され、省略時は SAI 実装のベンダーデフォルトに委ねられる。YANG で宣言された default 値は qosorch が参照しない点が重要である1。
本ページは SCHEDULER テーブル の orchagent 処理詳解ページである。テーブル全体の概要・key 構造・フィールド一覧は SCHEDULER テーブル を参照。
データフロー¶
flowchart LR
CDB[("CONFIG_DB<br/>SCHEDULER")]
QO["orchagent<br/>QosOrch::handleSchedulerTable()"]
SAI["SAI<br/>sai_scheduler_api"]
ASIC["ASIC"]
CDB --> QO
QO -->|create_scheduler / set_scheduler_attribute| SAI
SAI --> ASIC
凡例
各フィールドは存在する場合のみ SAI 属性として送信される。省略フィールドは SAI ベンダーデフォルトになる。
コード由来のデフォルト・暗黙挙動 (Phase A)¶
調査根拠:
sonic-swss/orchagent/qosorch.cpphandleSchedulerTable()L1347–1509 全行精読 +qosorch.hL22, 44–53 定数定義確認 +sonic-scheduler.yang照合 (2026-05-15)
| フィールド | YANG default | qosorch 実装の実効デフォルト | 備考 |
|---|---|---|---|
type |
WRR |
SAI ベンダー依存(省略時 SAI 属性送信なし) | YANG default は qosorch 未参照 |
weight |
1 |
SAI ベンダー依存(省略時 SAI 属性送信なし) | (uint8_t)stoi() キャスト、YANG range "1..100" 未検証 |
priority |
なし | dead field — エントリ全破棄 | 処理分岐が存在しない。SET すると Unknown field:priority → task_invalid_entry で全フィールドが SAI 未反映 |
meter_type |
bytes |
SAI ベンダー依存(省略時); 不正値で orchagent クラッシュ | scheduler_meter_map.at() が std::out_of_range 未キャッチ |
cir / cbs / pir / pbs |
なし | 省略時 SAI デフォルト相当(0 = 無制限) | 存在時のみ設定。YANG must 制約はコード未検証 |
type フィールドの詳細¶
// qosorch.cpp L1378–1397
if (fvField(*i) == scheduler_algo_type_field_name) // "type"
{
attr.id = SAI_SCHEDULER_ATTR_SCHEDULING_TYPE;
if (fvValue(*i) == scheduler_algo_DWRR) attr.value.s32 = SAI_SCHEDULING_TYPE_DWRR;
else if (fvValue(*i) == scheduler_algo_WRR) attr.value.s32 = SAI_SCHEDULING_TYPE_WRR;
else if (fvValue(*i) == scheduler_algo_STRICT) attr.value.s32 = SAI_SCHEDULING_TYPE_STRICT;
else {
SWSS_LOG_ERROR("Unknown scheduler type value:%s", fvField(*i).c_str());
return task_process_status::task_invalid_entry; // エントリ全体が破棄される
}
sai_attr_list.push_back(attr);
}
- 省略時:
SAI_SCHEDULER_ATTR_SCHEDULING_TYPEは SAI attr リストに追加されない → SAI ベンダーデフォルト(保証なし) - 未知の値:
task_invalid_entryを返し、sai_attr_listに積まれた他フィールドの属性も SAI に反映されない
dead field 詳細: priority¶
sonic-scheduler.yang に leaf priority { type uint8 { range "0..9"; } } が定義されているが、qosorch.h には対応する定数が存在しない2:
// qosorch.h L44–53 に scheduler_priority_field_name 定数なし
const string scheduler_algo_type_field_name = "type";
const string scheduler_algo_DWRR = "DWRR";
const string scheduler_algo_WRR = "WRR";
const string scheduler_algo_STRICT = "STRICT";
const string scheduler_weight_field_name = "weight";
const string scheduler_meter_type_field_name = "meter_type";
const string scheduler_min_bandwidth_rate_field_name = "cir";
const string scheduler_min_bandwidth_burst_rate_field_name = "cbs";
const string scheduler_max_bandwidth_rate_field_name = "pir";
const string scheduler_max_bandwidth_burst_rate_field_name = "pbs";
// ← priority が存在しない
handleSchedulerTable の if-else チェーン (L1378–1438) に priority の処理分岐がなく、最後の else ブランチ (L1436–1439) にフォールスルーする:
// qosorch.cpp L1436–1439
else {
SWSS_LOG_ERROR("Unknown field:%s", fvField(*i).c_str());
return task_process_status::task_invalid_entry;
}
重要:
priorityフィールドを含む SCHEDULER エントリを CONFIG_DB に SET するとUnknown field:priorityエラーでtask_invalid_entryが返り、そのエントリのtype/weight/meter_type等を含む全フィールドが SAI に反映されない。回避策は CONFIG_DB からpriorityフィールドを除外すること。
meter_type クラッシュリスク¶
scheduler_meter_map は {"packets": SAI_METER_TYPE_PACKETS, "bytes": SAI_METER_TYPE_BYTES} のみ。"packets" / "bytes" 以外の値を渡すと std::map::at() が std::out_of_range 例外をスロー。例外はキャッチされておらず orchagent プロセスがクラッシュする。
type フィールドが graceful エラー処理 (task_invalid_entry を返す) をしているのと対照的な危険な挙動。YANG enum で 2 値のみが許可されているため通常経路では発生しないが、sonic-db-cli 等で直接 CONFIG_DB に書き込む際は要注意。
新規作成 vs 更新の挙動差異¶
| 状況 | SAI 呼び出し | 省略フィールドの扱い |
|---|---|---|
| 新規作成(SAI オブジェクトなし) | create_scheduler() に全属性まとめて渡す |
SAI 作成時のベンダーデフォルトが適用 |
| 既存更新(SAI オブジェクトあり) | set_scheduler_attribute() を属性ごとに個別呼び出し |
省略フィールドは現在の SAI 属性値を保持(変更なし) |
更新時の注意
既存オブジェクトを更新する場合、省略したフィールドは変更されない。type を WRR → STRICT に変更するだけであれば type フィールドのみ SET すれば足りるが、meter_type を意図せず変更したくない場合は省略で安全。
削除保護ロジック¶
// qosorch.cpp L1483–1488
if (gQosOrch->isObjectBeingReferenced(QosOrch::getTypeMap(), qos_map_type_name, qos_object_name))
{
SWSS_LOG_NOTICE("Can't remove object %s due to being referenced (%s)", ...);
(*(m_qos_maps[qos_map_type_name]))[qos_object_name].m_pendingRemove = true;
return task_process_status::task_need_retry;
}
QUEUE 等から参照中の SCHEDULER を削除しようとすると task_need_retry を返し m_pendingRemove = true にセット。参照が解除されると次回 retry 時に自動削除される。
YANG-実装 Discrepancy まとめ¶
| フィールド | YANG 定義 | qosorch 実装 | 分類 |
|---|---|---|---|
type |
default WRR |
省略時 SAI ベンダー依存 | YANG default 不適用 |
weight |
default 1; range "1..100" |
省略時 SAI ベンダー依存; range 未検証 | YANG default 不適用 + バリデーション欠如 |
priority |
uint8 { range "0..9"; } |
dead field(Unknown field → task_invalid_entry) | YANG 定義あり、実装なし — 重大乖離 |
meter_type |
default bytes |
省略時 SAI ベンダー依存; 不正値でクラッシュ | YANG default 不適用 + クラッシュリスク |
cir/cbs/pir/pbs |
must 制約あり |
存在時のみ設定; must 制約未検証 |
YANG 制約不適用(CONFIG_DB バリデーション層のみ) |
購読者¶
QosOrch:CFG_SCHEDULER_TABLE_NAMEをSubscriberStateTableで購読しhandleSchedulerTable()でハンドリング1
関連 CONFIG_DB / YANG / CLI¶
- 関連 CONFIG_DB:
QUEUE(schedulerleafref)、PORT_QOS_MAP - 関連 CLI: なし(
config qos reload経由のバルク投入のみ) - 関連 YANG:
sonic-scheduler
関連リファレンス¶
引用元¶
運用ヒント¶
priority フィールドに関する注意¶
YANG スキーマに priority リーフが定義されているため、設定ツールが自動生成するエントリに priority が含まれる場合がある。この場合 QosOrch は Unknown field:priority エラーでエントリ全体を破棄する。sonic-db-cli CONFIG_DB hgetall 'SCHEDULER|<name>' で既存エントリを確認し、priority フィールドが存在する場合は hdel で削除した後に再設定する。
確認コマンド¶
# SCHEDULER エントリ一覧
sonic-db-cli CONFIG_DB keys 'SCHEDULER|*'
# 特定エントリの確認(priority フィールドの有無を確認)
sonic-db-cli CONFIG_DB hgetall 'SCHEDULER|scheduler.0'
# orchagent のエラーログ確認
sudo grep -i "Unknown field\|scheduler" /var/log/swss/orchagent.log | tail -20
-
QosOrch 実装
handleSchedulerTable():sonic-swss/orchagent/qosorch.cpp. https://github.com/sonic-net/sonic-swss/blob/4305596156d70e9797e8a881b3d19b46de0bce0d/orchagent/qosorch.cpp ↩↩ -
フィールド名定数定義
qosorch.h:sonic-swss/orchagent/qosorch.h. https://github.com/sonic-net/sonic-swss/blob/4305596156d70e9797e8a881b3d19b46de0bce0d/orchagent/qosorch.h ↩