1
0
mirror of https://github.com/haiwen/seafile-server.git synced 2025-09-12 21:35:30 +00:00

Merge branch '11.0'

This commit is contained in:
杨赫然
2024-07-16 17:37:24 +08:00
23 changed files with 758 additions and 249 deletions

View File

@@ -1147,3 +1147,153 @@ seaf_repo_manager_init_merge_scheduler ()
SCHEDULE_INTERVAL);
return 0;
}
int
seaf_repo_manager_repair_virtual_repo (char *repo_id)
{
SeafRepoManager *mgr = seaf->repo_mgr;
SeafVirtRepo *vinfo = NULL;
SeafRepo *repo = NULL, *orig_repo = NULL;
SeafCommit *head = NULL, *orig_head = NULL;
char *root = NULL, *orig_root = NULL;
char new_base_commit[41] = {0};
int ret = 0;
GError *error = NULL;
/* repos */
repo = seaf_repo_manager_get_repo (mgr, repo_id);
if (!repo) {
seaf_warning ("Failed to get virt repo %.10s.\n", repo_id);
ret = -1;
goto out;
}
if (!repo->virtual_info) {
seaf_warning ("Repo %.10s is not a virtual repo.\n", repo_id);
ret = -1;
goto out;
}
vinfo = seaf_repo_manager_get_virtual_repo_info (mgr, repo_id);
if (!vinfo) {
seaf_warning ("Failed to get virt repo info %.10s.\n", repo_id);
ret = -1;
goto out;
}
orig_repo = seaf_repo_manager_get_repo (mgr, vinfo->origin_repo_id);
if (!orig_repo) {
seaf_warning ("Failed to get orig repo %.10s.\n", vinfo->origin_repo_id);
ret = -1;
goto out;
}
/* commits */
head = seaf_commit_manager_get_commit (seaf->commit_mgr,
repo->id, repo->version,
repo->head->commit_id);
if (!head) {
seaf_warning ("Failed to get virtual repo commit %s:%.8s.\n",
repo->id, repo->head->commit_id);
ret = -1;
goto out;
}
orig_head = seaf_commit_manager_get_commit (seaf->commit_mgr,
orig_repo->id, orig_repo->version,
orig_repo->head->commit_id);
if (!orig_head) {
seaf_warning ("Failed to get origin repo commit %s:%.8s.\n",
orig_repo->id, orig_repo->head->commit_id);
ret = -1;
goto out;
}
orig_root = seaf_fs_manager_get_seafdir_id_by_path (seaf->fs_mgr,
orig_repo->store_id,
orig_repo->version,
orig_head->root_id,
vinfo->path,
&error);
if (error &&
!g_error_matches(error,
SEAFILE_DOMAIN,
SEAF_ERR_PATH_NO_EXIST)) {
seaf_warning ("Failed to get seafdir id by path in origin repo %.10s: %s.\n", orig_repo->store_id, error->message);
ret = -1;
goto out;
}
if (!orig_root) {
seaf_message("Path %s not found in origin repo %.8s, delete or rename virtual repo %.8s\n",
vinfo->path, vinfo->origin_repo_id, repo_id);
goto out;
}
/* fs roots */
root = head->root_id;
MergeOptions opt;
const char *roots[2];
memset (&opt, 0, sizeof(opt));
opt.n_ways = 2;
memcpy (opt.remote_repo_id, repo_id, 36);
memcpy (opt.remote_head, head->commit_id, 40);
roots[0] = orig_root;
roots[1] = root;
/* Merge virtual into origin */
if (seaf_merge_trees (orig_repo->store_id, orig_repo->version,
2, roots, &opt) < 0) {
seaf_warning ("Failed to merge virtual repo %.10s.\n", repo_id);
ret = -1;
goto out;
}
seaf_debug ("Number of dirs visted in merge: %d.\n", opt.visit_dirs);
/* Update virtual repo root. */
ret = seaf_repo_manager_update_dir (mgr,
repo_id,
"/",
opt.merged_tree_root,
orig_head->creator_name,
head->commit_id,
NULL,
NULL);
if (ret < 0) {
seaf_warning ("Failed to update root of virtual repo %.10s.\n",
repo_id);
goto out;
}
/* Update origin repo path. */
ret = seaf_repo_manager_update_dir (mgr,
vinfo->origin_repo_id,
vinfo->path,
opt.merged_tree_root,
head->creator_name,
orig_head->commit_id,
new_base_commit,
NULL);
if (ret < 0) {
seaf_warning ("Failed to update origin repo %.10s path %s.\n",
vinfo->origin_repo_id, vinfo->path);
goto out;
}
set_virtual_repo_base_commit_path (repo->id, new_base_commit, vinfo->path);
out:
if (error)
g_clear_error (&error);
seaf_virtual_repo_info_free (vinfo);
seaf_repo_unref (repo);
seaf_repo_unref (orig_repo);
seaf_commit_unref (head);
seaf_commit_unref (orig_head);
g_free (orig_root);
return ret;
}