Обновить internal/endpoint/endpoint.go

This commit is contained in:
2026-07-24 17:32:03 +03:00
parent 06f7183608
commit 1428678b58
+39 -6
View File
@@ -636,6 +636,24 @@ func (f subroot) UserSpecifiedDatasets() zfs.UserSpecifiedDatasetsSet {
}
// senderPrefixDatasetPath returns the configured literal sender-side prefix
// (e.g. "hdd_9XG1J9J1") to strip from incoming filesystem paths, or nil if
// ZREPL_STRIP_SENDER_PREFIX is unset/empty. Using a literal string (rather
// than a component count) lets us losslessly reconstruct the sender's
// original path later in ListFilesystems, which is required for the
// sender/receiver filesystem-matching in the replication planner to work.
func senderPrefixDatasetPath() *zfs.DatasetPath {
s := envconst.String("ZREPL_STRIP_SENDER_PREFIX", "")
if s == "" {
return nil
}
dp, err := zfs.NewDatasetPath(s)
if err != nil || dp.Length() == 0 {
return nil
}
return dp
}
func (f subroot) MapToLocal(fs string) (*zfs.DatasetPath, error) {
p, err := zfs.NewDatasetPath(fs)
if err != nil {
@@ -644,9 +662,10 @@ func (f subroot) MapToLocal(fs string) (*zfs.DatasetPath, error) {
if p.Length() == 0 {
return nil, errors.Errorf("cannot map empty filesystem")
}
// drop N leading components of the sender's path (e.g. pool name)
if n := envconst.Int("ZREPL_STRIP_SENDER_PREFIX_COMPS", 0); n > 0 {
p.TrimNPrefixComps(n)
// PATCH: strip a configured literal prefix (e.g. the source zpool name)
// from the *sender's* path before appending it under root_fs.
if prefix := senderPrefixDatasetPath(); prefix != nil && p.HasPrefix(prefix) {
p.TrimPrefix(prefix)
}
c := f.localRoot.Copy()
c.Extend(p)
@@ -654,8 +673,6 @@ func (f subroot) MapToLocal(fs string) (*zfs.DatasetPath, error) {
}
func (s *Receiver) ListFilesystems(ctx context.Context, req *pdu.ListFilesystemReq) (*pdu.ListFilesystemRes, error) {
defer trace.WithSpanFromStackUpdateCtx(&ctx)()
@@ -696,12 +713,28 @@ func (s *Receiver) ListFilesystems(ctx context.Context, req *pdu.ListFilesystemR
a.TrimPrefix(root)
// PATCH: re-prepend the literal sender prefix that MapToLocal strips,
// so that the Path we report here matches what the sender reports
// for the same filesystem (see replication_logic.go's Path-based
// sender/receiver matching). Without this, the planner can never
// find a matching receiverFS and will treat every cycle as if the
// filesystem doesn't exist yet on the receiver.
reportPath := a.ToString()
if prefix := senderPrefixDatasetPath(); prefix != nil {
if reportPath == "" {
reportPath = prefix.ToString()
} else {
reportPath = prefix.ToString() + "/" + reportPath
}
}
fs := &pdu.Filesystem{
Path: a.ToString(),
Path: reportPath,
IsPlaceholder: ph.IsPlaceholder,
ResumeToken: token,
}
fss = append(fss, fs)
}
if len(fss) == 0 {
getLogger(ctx).Debug("no filesystems found")