摘要
active、notInService、notReady是代理能够返回的现状;createAndGo、createAndWait、destroy则是管理器提交的动作,读取时永远不会作为行的状态出现。- 管理器负责提出索引和值,MIB 负责定义条件,代理负责判断转换能否成立。因此,一行可以先存在而未就绪,也可以已经就绪却仍未投入服务。
早期的“表”,并不是数据库承诺
在 MIB 中,对象标识符加上实例索引,很自然地形成表格外观。管理器可以逐列读写,工具也可以把结果画成一行。但 RFC 1212 特意称它们为“概念表”和“概念行”:列之间的关系是一种应用约定,并不是 SNMP 自带的关系数据库机制。
当时的 MIB 可以用一个整数状态表示删除,也可以允许 SetRequest 指向尚不存在的实例,由代理决定接受创建还是拒绝。DEFVAL 还能为未提交的列提供默认值。问题在于,每个 MIB 都要自行解释:什么时候算创建成功,缺少哪些字段仍可保留,设备什么时候可以真正使用这行配置。
如果只有设备自己生成只读数据,含糊尚且可控。一旦多个管理站都能创建动态配置,索引归谁、半成品是否可见、第二个管理器能否接手,就变成了协议协作问题。
RMON 先把“正在创建”写进状态
RFC 1271 的远程网络监测 MIB 提供了直接前身。EntryStatus 包含 createRequest、underCreation、valid 和 invalid。管理器先取得某个索引,逐步补全,再把条目设为有效;多个管理器争用同一索引时,只有第一个成功创建者能够取得它,后来的请求会报错。
RMON 还定义了 OwnerString,帮助协作中的管理站识别条目创建者、避免无意冲突。不过 RFC 明确说明,它不是访问控制。一个不合作的管理器仍可能修改或删除别人的条目。署名提供来源线索,却没有产生排他权。
这个限制很重要。状态机可以把意图和现状说清楚,但它不能替代认证、授权和组织纪律。
六个值,其实分成两类
RFC 1443 在 SNMPv2 中标准化了 RowStatus;RFC 2579 保存了现行定义。它有六个数值,但不是六个性质相同的状态。
读取一行时,代理只会返回三种结果。active(1) 表示该行可供受管设备使用。notInService(2) 表示行已经存在而且暂不使用,代理也已有足够信息去尝试激活;但它不保证内部一致、资源充足或激活必然成功。notReady(3) 表示行虽存在,却仍缺少投入服务所必需的列实例。
另外三个是写入动作。createAndGo(4) 请求创建后立即激活;createAndWait(5) 请求先创建但不投入服务;destroy(6) 请求删除属于该概念行的全部实例。
GET 不会返回后三个值,管理器也不能把一行写成 notReady。notReady 是代理对缺失信息的判断。于是,同一列在写入方向承载请求,在读取方向返回事实,命令与证据没有被伪装成同一件事。
createAndGo 不是“先存个草稿”
一次性创建时,管理器选择尚未使用的实例标识,在同一个 SetRequest 中提交所需列和值为 createAndGo 的状态列。代理可以用实现默认值补充其余内容。
若信息足够,代理创建该行,随后可读状态直接是 active。若缺少必要信息,操作以 inconsistentValue 失败,而且不会创建概念行。管理器不能假定失败后留下了可继续编辑的半成品。它必须找出要求,重新发送完整请求,或者改用代理支持的分阶段创建。
这种严格性使“一次完成”有清楚含义:创建和激活共同成功,或者两者都不成立。
createAndWait 允许半成品存在,但不允许它假装在服务
分阶段模式的第一步是写入 createAndWait。如果代理接受,该行已经存在,却不会供设备使用。缺少必要列时,读取结果是 notReady;把缺失列补上后,代理可自动把状态推进到 notInService。此时信息足以尝试激活,但还没有服务事实。
管理器随后写入 active。代理可以接受,也可以因值、资源或设备当前状态不一致而返回 inconsistentValue。就绪只是申请激活的条件,不是激活结果。
而且,代理可以不支持 createAndWait,以 wrongValue 拒绝并要求一次性完整创建。它也可能拒绝把正在使用的行退出服务,或拒绝立即删除。通用状态机并没有夺走本地实现与具体 MIB 的边界。
未投入服务的行仍会占用资源。RFC 2579 要求代理发现长时间停留在 notReady 或 notInService 的行并予以清理。状态列的 DESCRIPTION 应说明“异常长”的期限;如果没有说明,RFC 建议约五分钟,以容纳人的思考时间。这是默认建议,不是对所有产品计时器的实测结论。
真正的细则仍写在 MIB 描述里
RowStatus 没有统一决定 active 状态下能否修改其他列。有些表允许在线修改,有些表要求先退出服务。哪些字段必须在激活前有效、哪些字段能在 active 时改变,都必须由状态列或对应列的 DESCRIPTION 说清楚。
RFC 4181 后来把这些要求整理为 MIB 编写规范:支持管理应用动态创建和删除时,通常应有一个 read-create 的 RowStatus 列;还要说明重启后的持久性或 StorageType、代理自身何时创建或删除行,以及激活和在线修改的精确条件。
标准化的是状态语法,不是所有设备的配置政策。正因为具体规则仍需公开描述,共同语法才不会变成空洞标签。
“仿佛同时发生”只属于一个请求
创建行时,若干列和值为 RowStatus 的变量绑定往往放在同一个 SetRequest 中。RFC 3416 把处理概念上分成两阶段:先验证所有变量绑定;全部通过后才修改。该请求内的各项赋值,相对于彼此应当像同时发生一样。
如果修改阶段失败,实体尝试撤销其他修改并返回 commitFailed;若无法全部撤销,则返回 undoFailed。后一个错误本身就在提醒人们,不要把抽象语义夸大成无边界的完美事务。
这个保证只覆盖一个 SNMP 实体处理的一次请求。它不是跨路由器事务,不是分布式锁,不证明重启后仍保存,也不证明数据平面已经按意图运行。管理成功提供一项有限事实,业务效果需要另行测量。
这套设计的进步,是不再让“存在”冒充“运行”
RowStatus 把权责分在不同层。管理器提出期望;MIB 公布合同;代理验证名称、访问、值、资源与状态转换;正在运行的设备给出最后的操作事实。
一行可见,仍可能缺字段。一行完整,仍可能被留在服务之外。激活请求可能被拒绝。即使 active,也未必说明配置持久、链路通畅或安全政策正确。每个状态的价值,恰恰来自它没有越权回答下一层问题。
来源与边界
RFC 1212 和 RFC 1271 说明早期约定及 RMON 前身;RFC 1443 与 RFC 2579 定义六值生命周期;RFC 3416 给出 SetRequest 边界;RFC 4181 总结 MIB 编写义务。这些材料不能证明当代部署比例、厂商一致性、通用清理时间、安全性或数据平面效果。把 RowStatus 解读为意图、就绪与运行的分层,是从机制得到的分析。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
