-
Improvement
-
Resolution: Unresolved
-
Medium
-
None
-
None
-
None
-
3
-
9223372036854775807
Problem
A server keys the per-export statistics of a client on the NID that the client used at connect time. LU-20403 makes the server re-key exp->exp_connection when the LNet primary NID of the client changes. The re-key does not move exp->exp_nid_stats. The statistics directory keeps the old name, and a lookup by the current NID of the client does not find the export.
Evidence
A VM test migrated the primary NID of a client from A to B. The server logged the re-key. The test then read the exports tree on both targets:
- The directory for NID B does not exist. The read returns ENOENT.
- The directory for NID A exists, but a read of export and of uuid returns ENODEV.
The client is not visible under either NID. This result is a run of conf-sanity test_73z on a 4 node cluster.
Effect
- obdfilter..exports. and mdt..exports. name a NID that the client no longer uses.
- obd_export_evict_by_nid() (lustre/obdclass/genops.c:1676) does not find the export by the current NID. An administrator cannot evict the client by the NID that the client uses now.
- The counters stay correct. Every counter goes through exp->exp_nid_stats, which the export still holds.
Why the re-key cannot do this today
Each target builds its own statistics tree:
- ofd_export_stats_init() (lustre/ofd/ofd_obd.c:46)
- mdt_export_stats_init() (lustre/mdt/mdt_fs.c:42)
- mgs_export_stats_init() (lustre/mgs/mgs_fs.c:37)
Each one calls lprocfs_exp_setup() and then allocates a counter set with a name that holds the NID. The connect path of each target calls its own function directly. These functions are not in obd_ops, so the generic re-key path in ptlrpc cannot reach them.
lprocfs_exp_setup() (lustre/obdclass/lprocfs_status_server.c:701) also returns EALREADY when the export already holds an exp_nid_stats pointer. The guard tests the pointer, not the NID. A second call with a new NID therefore does no work.
Possible work items
- Add an obd_ops hook, for example o_export_stats_init(obd, exp, nid). Move the three target functions behind it.
- Let lprocfs_exp_setup() accept a NID that differs from the NID of the current exp_nid_stats. The function must drop the old nid_stat reference and build the new tree.
- Call the hook from the re-key path. The service thread can sleep, so the work needs no workqueue. The call must be outside exp_lock.
- Add a test that migrates the primary NID of a client and reads the exports tree under the new NID.
An estimate for these items is 150 to 250 lines across 8 files.
Relation to other tickets
LU-20403 adds the re-key. This ticket covers the statistics that the re-key leaves behind. LU-20403 does not need this work. The statistics gap is older than LU-20403. A client that reconnects on a new NID gets a new export and a new directory. The old directory stays until obdclass destroys the old export.
LU-20538 asks which nodemap holds a client that has more than one NID. The nodemap membership has the same shape as this problem, because nodemap_add_member() also keys on the NID of the client. The two tickets are separate: LU-20538 must select a classification rule, and this ticket must move a debugfs tree.