Repository navigation
Description
Describe the bug
With the POSIX driver, when the path rendered by STORAGE_USERS_POSIX_PERSONAL_SPACE_PATH_TEMPLATE changes for a user who already has a personal space, a second personal space is created for that user at the new path. The existing space is not found, and the user ends up with two personal drives.
We use an intermediate "shard" level so that spaces can be spread over several filesystems and new users go to the newest one (see #3716), e.g. users/u0/<userId> and users/u1/<userId>. Switching the active shard from u1 to u0 is enough to trigger it.
Steps to reproduce
OpenCloud 9.1.0 (reva 2.52.2), POSIX driver, OC_CACHE_STORE=nats-js-kv.
- Configure the template with an active shard:
Log in as a user. The personal space is created at
STORAGE_USERS_POSIX_PERSONAL_SPACE_PATH_TEMPLATE=users/u1/{{.User.Id.OpaqueId}}<root>/users/u1/<userId>. - Change the template to point to another shard and restart storage-users:
STORAGE_USERS_POSIX_PERSONAL_SPACE_PATH_TEMPLATE=users/u0/{{.User.Id.OpaqueId}} - Make sure the gateway's
create_personal_spacecache entry for that user is gone. Either wait for it to expire, or delete the keycreate_personal_space_<userId>from thecache-createhomeKV bucket (nats kv del). - Make any authenticated request as that user, e.g.
GET /graph/v1.0/me/drives?$filter=driveType eq 'personal'.
Expected behavior
The user keeps a single personal space: the existing one is found (or the creation returns ALREADY_EXISTS), whatever the path rendered by the current template.
Actual behavior
The request returns two personal drives with the same name, and there are two directories on disk, each with its own user.oc.space.id:
<root>/users/u1/<userId> user.oc.space.id=<first space id> (original, has the data)
<root>/users/u0/<userId> user.oc.space.id=<second space id> (new, empty)
The second space is created silently.
Cause (from reading the code)
Lookup.GenerateSpaceID (pkg/storage/fs/posix/lookup/lookup.go) decides whether a personal space already exists only from the path rendered with the current template:
case _spaceTypePersonal:
relPath := templates.WithUser(owner, lu.Options.PersonalSpacePathTemplate)
path := filepath.Join(lu.Options.Root, relPath)
// do we already know about this space?
spaceID, _, err := lu.IDsForPath(ctx, path)
...
// nothing on disk at that path -> uuid.New().String()When the template now renders another path, nothing is found there and a new UUID is generated. The same happens in general whenever a template change moves the rendered path of an existing user. The gateway cache (create_personal_space) only hides the problem while its entry exists.
Possible approach
Before generating a new ID for a personal space, check whether the owner already has one independently of the rendered path, for example through the owner index (indexes/by-user-id) or the ID cache, and reuse it.
Setup
- OpenCloud 9.1.0, reva 2.52.2, POSIX driver, NATS JetStream KV for cache and registry.
Additional context
- The extra space can be removed by disabling then purging it (
DELETE /graph/v1.0/drives/<id>, then again withPurge: T). - Related: [BUG] PosixFS does not respect custom storage paths #3434 (custom path templates not respected by all components), POSIX driver: support sharded space layouts (
users/u0,users/u1,projects/p0, …) in path templates #3716 (sharded layouts).
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsQualification
Activity