void backup_service::modify_backup_policy()

in src/meta/meta_backup_service.cpp [1496:1637]


void backup_service::modify_backup_policy(configuration_modify_backup_policy_rpc rpc)
{
    const configuration_modify_backup_policy_request &request = rpc.request();
    configuration_modify_backup_policy_response &response = rpc.response();
    response.err = ERR_OK;

    std::shared_ptr<policy_context> context_ptr;
    {
        zauto_lock _(_lock);
        auto iter = _policy_states.find(request.policy_name);
        if (iter == _policy_states.end()) {
            response.err = ERR_INVALID_PARAMETERS;
            context_ptr = nullptr;
        } else {
            context_ptr = iter->second;
        }
    }
    if (context_ptr == nullptr) {
        return;
    }
    policy cur_policy = context_ptr->get_policy();

    bool is_under_backup = context_ptr->is_under_backuping();
    bool have_modify_policy = false;
    std::vector<int32_t> valid_app_ids_to_add;
    std::map<int32_t, std::string> id_to_app_names;
    if (request.__isset.add_appids) {
        // lock the _lock of server_state to acquire verify the apps that added to policy
        zauto_read_lock l;
        _state->lock_read(l);

        for (const auto &appid : request.add_appids) {
            const auto &app = _state->get_app(appid);
            auto access_controller = _meta_svc->get_access_controller();
            // TODO: if app is dropped, how to process
            if (app == nullptr) {
                LOG_WARNING("{}: add app to policy failed, because invalid app({}), ignore it",
                            cur_policy.policy_name,
                            appid);
                continue;
            }
            if (access_controller->is_enable_ranger_acl() &&
                !access_controller->allowed(rpc.dsn_request(), app->app_name)) {
                LOG_WARNING("not authorized to modify backup policy({}) for app id: {}, skip it",
                            cur_policy.policy_name,
                            appid);
                continue;
            }
            valid_app_ids_to_add.emplace_back(appid);
            id_to_app_names.insert(std::make_pair(appid, app->app_name));
            have_modify_policy = true;
        }
    }

    if (request.__isset.is_disable) {
        if (request.is_disable) {
            if (is_under_backup) {
                LOG_INFO("{}: policy is under backuping, not allow to disable",
                         cur_policy.policy_name);
                response.err = ERR_BUSY;
            } else if (!cur_policy.is_disable) {
                LOG_INFO("{}: policy is marked to disable", cur_policy.policy_name);
                cur_policy.is_disable = true;
                have_modify_policy = true;
            } else { // cur_policy.is_disable = true
                LOG_INFO("{}: policy is already disabled", cur_policy.policy_name);
            }
        } else {
            if (cur_policy.is_disable) {
                cur_policy.is_disable = false;
                LOG_INFO("{}: policy is marked to enable", cur_policy.policy_name);
                have_modify_policy = true;
            } else {
                LOG_INFO("{}: policy is already enabled", cur_policy.policy_name);
                response.err = ERR_OK;
                response.hint_message = std::string("policy is already enabled");
            }
        }
    }

    if (request.__isset.add_appids && !valid_app_ids_to_add.empty()) {
        for (const auto &appid : valid_app_ids_to_add) {
            cur_policy.app_ids.insert(appid);
            cur_policy.app_names.insert(std::make_pair(appid, id_to_app_names.at(appid)));
            have_modify_policy = true;
        }
    }

    if (request.__isset.removal_appids) {
        for (const auto &appid : request.removal_appids) {
            if (appid > 0) {
                cur_policy.app_ids.erase(appid);
                LOG_INFO("{}: remove app({}) to policy", cur_policy.policy_name, appid);
                have_modify_policy = true;
            } else {
                LOG_WARNING("{}: invalid app_id({})", cur_policy.policy_name, appid);
            }
        }
    }

    if (request.__isset.new_backup_interval_sec) {
        if (request.new_backup_interval_sec > 0) {
            LOG_INFO("{}: policy will change backup interval from {}s to {}s",
                     cur_policy.policy_name,
                     cur_policy.backup_interval_seconds,
                     request.new_backup_interval_sec);
            cur_policy.backup_interval_seconds = request.new_backup_interval_sec;
            have_modify_policy = true;
        } else {
            LOG_WARNING("{}: invalid backup_interval_sec({})",
                        cur_policy.policy_name,
                        request.new_backup_interval_sec);
        }
    }

    if (request.__isset.backup_history_count_to_keep) {
        if (request.backup_history_count_to_keep > 0) {
            LOG_INFO("{}: policy will change backup_history_count_to_keep from {} to {}",
                     cur_policy.policy_name,
                     cur_policy.backup_history_count_to_keep,
                     request.backup_history_count_to_keep);
            cur_policy.backup_history_count_to_keep = request.backup_history_count_to_keep;
            have_modify_policy = true;
        }
    }

    if (request.__isset.start_time) {
        backup_start_time t_start_time;
        if (t_start_time.parse_from(request.start_time)) {
            LOG_INFO("{}: policy change start_time from {} to {}",
                     cur_policy.policy_name,
                     cur_policy.start_time,
                     t_start_time);
            cur_policy.start_time = t_start_time;
            have_modify_policy = true;
        }
    }

    if (have_modify_policy) {
        do_update_policy_to_remote_storage(rpc, cur_policy, context_ptr);
    }
}