Обновить internal/endpoint/endpoint.go
This commit is contained in:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user