Skip to content

[BUG] POSIX: a second personal space is created for a user when the active shard in PERSONAL_SPACE_PATH_TEMPLATE changes #3978

Open

Description

@Ezanor

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.

  1. Configure the template with an active shard:
    STORAGE_USERS_POSIX_PERSONAL_SPACE_PATH_TEMPLATE=users/u1/{{.User.Id.OpaqueId}}
    
    Log in as a user. The personal space is created at <root>/users/u1/<userId>.
  2. Change the template to point to another shard and restart storage-users:
    STORAGE_USERS_POSIX_PERSONAL_SPACE_PATH_TEMPLATE=users/u0/{{.User.Id.OpaqueId}}
    
  3. Make sure the gateway's create_personal_space cache entry for that user is gone. Either wait for it to expire, or delete the key create_personal_space_<userId> from the cache-createhome KV bucket (nats kv del).
  4. 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions