Обновить 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) { func (f subroot) MapToLocal(fs string) (*zfs.DatasetPath, error) {
p, err := zfs.NewDatasetPath(fs) p, err := zfs.NewDatasetPath(fs)
if err != nil { if err != nil {
@@ -644,9 +662,10 @@ func (f subroot) MapToLocal(fs string) (*zfs.DatasetPath, error) {
if p.Length() == 0 { if p.Length() == 0 {
return nil, errors.Errorf("cannot map empty filesystem") return nil, errors.Errorf("cannot map empty filesystem")
} }
// drop N leading components of the sender's path (e.g. pool name) // PATCH: strip a configured literal prefix (e.g. the source zpool name)
if n := envconst.Int("ZREPL_STRIP_SENDER_PREFIX_COMPS", 0); n > 0 { // from the *sender's* path before appending it under root_fs.
p.TrimNPrefixComps(n) if prefix := senderPrefixDatasetPath(); prefix != nil && p.HasPrefix(prefix) {
p.TrimPrefix(prefix)
} }
c := f.localRoot.Copy() c := f.localRoot.Copy()
c.Extend(p) 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) { func (s *Receiver) ListFilesystems(ctx context.Context, req *pdu.ListFilesystemReq) (*pdu.ListFilesystemRes, error) {
defer trace.WithSpanFromStackUpdateCtx(&ctx)() defer trace.WithSpanFromStackUpdateCtx(&ctx)()
@@ -696,12 +713,28 @@ func (s *Receiver) ListFilesystems(ctx context.Context, req *pdu.ListFilesystemR
a.TrimPrefix(root) 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{ fs := &pdu.Filesystem{
Path: a.ToString(), Path: reportPath,
IsPlaceholder: ph.IsPlaceholder, IsPlaceholder: ph.IsPlaceholder,
ResumeToken: token, ResumeToken: token,
} }
fss = append(fss, fs) fss = append(fss, fs)
} }
if len(fss) == 0 { if len(fss) == 0 {
getLogger(ctx).Debug("no filesystems found") getLogger(ctx).Debug("no filesystems found")