static int
start (CcnetProcessor *processor, int argc, char **argv)
{
    if (argc != 2) {
        g_warning ("[notifysync-slave] argc(%d) must be 2\n", argc);
        ccnet_processor_done (processor, FALSE);
        return -1;
    }
    const char *repo_id = argv[0];
    const char *token = argv[1];

    seaf_debug ("[notifysync-slave] Receive notify sync repo %s from %s\n",
                repo_id, processor->peer_id);

    if (!seaf_repo_manager_repo_exists (seaf->repo_mgr, repo_id)) {
        ccnet_processor_send_response (processor, SC_BAD_REPO, SS_BAD_REPO, NULL, 0);
        ccnet_processor_done (processor, FALSE);
        return -1;
    }

    seaf_sync_manager_add_sync_task (seaf->sync_mgr, repo_id,
                                     processor->peer_id,
                                     token, TRUE, NULL);
    ccnet_processor_send_response (processor, SC_OK, SS_OK,
                                   NULL, 0);
    ccnet_processor_done (processor, TRUE);
    return 0;
}
Beispiel #2
0
static void *
check_tx (void *vprocessor)
{
    CcnetProcessor *processor = vprocessor;
    USE_PRIV;

    char *owner = NULL;
    int org_id;
    SearpcClient *rpc_client = NULL;

    char *repo_id = priv->repo_id;

    rpc_client = create_sync_ccnetrpc_client
                 (seaf->session->config_dir, "ccnet-threaded-rpcserver");

    if (!rpc_client) {
        priv->rsp_code = g_strdup(SC_SERVER_ERROR);
        priv->rsp_msg = g_strdup(SS_SERVER_ERROR);
        goto out;
    }

    if (!seaf_repo_manager_repo_exists (seaf->repo_mgr, repo_id)) {
        priv->rsp_code = g_strdup(SC_BAD_REPO);
        priv->rsp_msg = g_strdup(SS_BAD_REPO);
        goto out;
    }

    if (priv->type == CHECK_TX_TYPE_UPLOAD &&
            check_repo_owner_quota (processor, rpc_client, repo_id) < 0)
        goto out;

    owner = seaf_repo_manager_get_repo_owner (seaf->repo_mgr, repo_id);
    if (owner != NULL) {
        /* If the user is not owner, check share permission */
        if (strcmp (owner, priv->email) != 0) {
            if(!check_repo_share_permission (rpc_client, repo_id, priv->email)) {
                priv->rsp_code = g_strdup(SC_ACCESS_DENIED);
                priv->rsp_msg = g_strdup(SS_ACCESS_DENIED);
                goto out;
            }
        }
    } else {
        /* This should be a repo created in an org. */
        org_id = seaf_repo_manager_get_repo_org (seaf->repo_mgr, repo_id);
        if (org_id < 0 ||
                !ccnet_org_user_exists (rpc_client, org_id, priv->email)) {
            priv->rsp_code = g_strdup(SC_ACCESS_DENIED);
            priv->rsp_msg = g_strdup(SS_ACCESS_DENIED);
            goto out;
        }
    }

    get_branch_head (processor);

out:
    g_free (owner);
    if (rpc_client)
        free_sync_rpc_client (rpc_client);
    return vprocessor;
}
static void *
check_tx (void *vprocessor)
{
    CcnetProcessor *processor = vprocessor;
    USE_PRIV;

    char *user = NULL;
    char *repo_id = priv->repo_id;

    if (!seaf_repo_manager_repo_exists (seaf->repo_mgr, repo_id)) {
        priv->rsp_code = g_strdup(SC_BAD_REPO);
        priv->rsp_msg = g_strdup(SS_BAD_REPO);
        goto out;
    }

    if (decrypt_token (processor) < 0) {
        priv->rsp_code = g_strdup(SC_ACCESS_DENIED);
        priv->rsp_msg = g_strdup(SS_ACCESS_DENIED);
        goto out;
    }

    user = seaf_repo_manager_get_email_by_token (
        seaf->repo_mgr, repo_id, priv->token);
    
    if (!user) {
        priv->rsp_code = g_strdup(SC_ACCESS_DENIED);
        priv->rsp_msg = g_strdup(SS_ACCESS_DENIED);
        goto out;
    }

    if (priv->type == CHECK_TX_TYPE_UPLOAD &&
        seaf_quota_manager_check_quota (seaf->quota_mgr, repo_id) < 0) {
        priv->rsp_code = g_strdup(SC_QUOTA_FULL);
        priv->rsp_msg = g_strdup(SS_QUOTA_FULL);
        goto out;
    }
    
    char *perm = seaf_repo_manager_check_permission (seaf->repo_mgr,
                                                     repo_id, user, NULL);
    if (!perm ||
        (strcmp (perm, "r") == 0 && priv->type == CHECK_TX_TYPE_UPLOAD))
    {
        priv->rsp_code = g_strdup(SC_ACCESS_DENIED);
        priv->rsp_msg = g_strdup(SS_ACCESS_DENIED);
        g_free (perm);
        goto out;
    }
    g_free (perm);

    get_branch_head (processor);

out:
    g_free (user);
    return vprocessor;    
}
Beispiel #4
0
static gboolean
is_repo_store_in_use (const char *repo_id)
{
    if (seaf_repo_manager_repo_exists (seaf->repo_mgr, repo_id))
        return TRUE;

    char sql[256];
    snprintf (sql, sizeof(sql), "SELECT 1 FROM CloneTasks WHERE repo_id='%s'",
              repo_id);
    if (sqlite_check_for_existence (seaf->clone_mgr->db, sql))
        return TRUE;

    return FALSE;
}
static void *
check_tx (void *vprocessor)
{
    CcnetProcessor *processor = vprocessor;
    USE_PRIV;

    char *user = NULL;
    char *repo_id = priv->repo_id;

    if (!seaf_repo_manager_repo_exists (seaf->repo_mgr, repo_id)) {
        priv->rsp_code = g_strdup(SC_BAD_REPO);
        priv->rsp_msg = g_strdup(SS_BAD_REPO);
        goto out;
    }

    if (decrypt_token (processor) < 0) {
        priv->rsp_code = g_strdup(SC_ACCESS_DENIED);
        priv->rsp_msg = g_strdup(SS_ACCESS_DENIED);
        goto out;
    }

    user = seaf_repo_manager_get_email_by_token (
        seaf->repo_mgr, repo_id, priv->token);
    
    if (!user) {
        priv->rsp_code = g_strdup(SC_ACCESS_DENIED);
        priv->rsp_msg = g_strdup(SS_ACCESS_DENIED);
        goto out;
    }

    if (priv->type == CHECK_TX_TYPE_UPLOAD &&
        seaf_quota_manager_check_quota (seaf->quota_mgr, repo_id) < 0) {
        priv->rsp_code = g_strdup(SC_QUOTA_FULL);
        priv->rsp_msg = g_strdup(SS_QUOTA_FULL);
        goto out;
    }
    
    char *perm = seaf_repo_manager_check_permission (seaf->repo_mgr,
                                                     repo_id, user, NULL);
    if (!perm ||
        (strcmp (perm, "r") == 0 && priv->type == CHECK_TX_TYPE_UPLOAD))
    {
        priv->rsp_code = g_strdup(SC_ACCESS_DENIED);
        priv->rsp_msg = g_strdup(SS_ACCESS_DENIED);
        g_free (perm);
        goto out;
    }
    g_free (perm);

    /* Record the (token, email, <peer info>) information, <peer info> may
     * include peer_id, peer_ip, peer_name, etc.
     */
    if (!seaf_repo_manager_token_peer_info_exists (seaf->repo_mgr, priv->token))
        seaf_repo_manager_add_token_peer_info (seaf->repo_mgr,
                                               priv->token,
                                               processor->peer_id,
                                               priv->peer_addr,
                                               priv->peer_name,
                                               (gint64)time(NULL));
    else
        seaf_repo_manager_update_token_peer_info (seaf->repo_mgr,
                                                  priv->token,
                                                  priv->peer_addr,
                                                  (gint64)time(NULL));

    get_branch_head (processor);

out:
    g_free (user);
    return vprocessor;    
}
Beispiel #6
0
static void
repair_repos (GList *repo_id_list, gboolean repair)
{
    GList *ptr;
    char *repo_id;
    SeafRepo *repo;
    gboolean exists;
    gboolean reset;
    gboolean io_error;

    for (ptr = repo_id_list; ptr; ptr = ptr->next) {
        reset = FALSE;
        repo_id = ptr->data;

        seaf_message ("Running fsck for repo %s.\n", repo_id);

        if (!is_uuid_valid (repo_id)) {
            seaf_warning ("Invalid repo id %s.\n", repo_id);
            goto next;
        }

        exists = seaf_repo_manager_repo_exists (seaf->repo_mgr, repo_id);
        if (!exists) {
            seaf_warning ("Repo %.8s doesn't exist.\n", repo_id);
            goto next;
        }

        repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id);

        if (!repo) {
            seaf_message ("Repo %.8s HEAD commit is corrupted, "
                          "need to restore to an old version.\n", repo_id);
            repo = get_available_repo (repo_id, repair);
            if (!repo) {
                goto next;
            }
            reset = TRUE;
        } else {
            SeafCommit *commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id,
                                                                 repo->version,
                                                                 repo->head->commit_id);
            if (!commit) {
                seaf_warning ("Failed to get head commit %s of repo %s\n",
                              repo->head->commit_id, repo->id);
                seaf_repo_unref (repo);
                goto next;
            }

            io_error = FALSE;
            if (!fsck_verify_seafobj (repo->store_id, repo->version,
                                      commit->root_id,  &io_error,
                                      VERIFY_DIR, repair)) {
                if (io_error) {
                    seaf_commit_unref (commit);
                    seaf_repo_unref (repo);
                    goto next;
                } else {
                    // root fs object is corrupted, get available commit
                    seaf_message ("Repo %.8s HEAD commit is corrupted, "
                                  "need to restore to an old version.\n", repo_id);
                    seaf_commit_unref (commit);
                    seaf_repo_unref (repo);
                    repo = get_available_repo (repo_id, repair);
                    if (!repo) {
                        goto next;
                    }
                    reset = TRUE;
                }
            } else {
                // head commit is available
                seaf_commit_unref (commit);
            }
        }

        check_and_recover_repo (repo, reset, repair);

        seaf_repo_unref (repo);
next:
        seaf_message ("Fsck finished for repo %.8s.\n\n", repo_id);
    }
}
Beispiel #7
0
static void
enable_sync_repo (const char *repo_id)
{
    SeafRepo *repo = NULL;
    SeafCommit *parent_commit = NULL;
    SeafCommit *new_commit = NULL;
    gboolean exists;

    if (!is_uuid_valid (repo_id)) {
        seaf_warning ("Invalid repo id %s.\n", repo_id);
        return;
    }

    exists = seaf_repo_manager_repo_exists (seaf->repo_mgr, repo_id);
    if (!exists) {
        seaf_warning ("Repo %.8s doesn't exist.\n", repo_id);
        return;
    }

    repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id);
    if (!repo)
        return;

    if (!repo->repaired) {
        seaf_repo_unref (repo);
        return;
    }

    seaf_message ("Enabling sync repo %s.\n", repo_id);

    parent_commit = seaf_commit_manager_get_commit_compatible (seaf->commit_mgr,
                                                               repo_id,
                                                               repo->head->commit_id);
    if (!parent_commit) {
        seaf_warning ("Commit %s:%s is missing\n",
                      repo_id, repo->head->commit_id);
        goto out;
    }

    new_commit = seaf_commit_new (NULL, repo_id, parent_commit->root_id,
                                  parent_commit->creator_name,
                                  parent_commit->creator_id,
                                  "Enable sync repo", 0);
    if (!new_commit) {
        seaf_warning ("Out of memory when create commit.\n");
        goto out;
    }
    new_commit->parent_id = g_strdup (parent_commit->commit_id);
    seaf_repo_to_commit (repo, new_commit);
    new_commit->repaired = FALSE;

    if (seaf_commit_manager_add_commit (seaf->commit_mgr,
                                        new_commit) < 0) {
        seaf_warning ("Failed to save commit %.8s for repo %.8s.\n",
                      new_commit->commit_id, repo_id);
        goto out;
    }

    seaf_branch_set_commit (repo->head, new_commit->commit_id);
    if (seaf_branch_manager_update_branch (seaf->branch_mgr,
                                           repo->head) < 0) {
        seaf_warning ("Failed to update head commit %.8s to repo %.8s.\n",
                      new_commit->commit_id, repo_id);
    } else {
        seaf_message ("Enable sync repo %.8s success.\n",
                      repo_id);
    }

out:
    if (parent_commit)
        seaf_commit_unref (parent_commit);
    if (new_commit)
        seaf_commit_unref (new_commit);
    if (repo)
        seaf_repo_unref (repo);
}