예제 #1
0
파일: hooklib.c 프로젝트: RavenB/abrt
/* rhbz#539551: "abrt going crazy when crashing process is respawned".
 * Check total size of problem dirs, if it overflows,
 * delete oldest/biggest dirs.
 */
void trim_problem_dirs(const char *dirname, double cap_size, const char *exclude_path)
{
    const char *excluded_basename = NULL;
    if (exclude_path)
    {
        unsigned len_dirname = strlen(dirname);
        /* Trim trailing '/'s, but dont trim name "/" to "" */
        while (len_dirname > 1 && dirname[len_dirname-1] == '/')
            len_dirname--;
        if (strncmp(dirname, exclude_path, len_dirname) == 0
         && exclude_path[len_dirname] == '/'
        ) {
            /* exclude_path is "dirname/something" */
            excluded_basename = exclude_path + len_dirname + 1;
        }
    }
    log_debug("excluded_basename:'%s'", excluded_basename);

    int count = 20;
    while (--count >= 0)
    {
        /* We exclude our own dir from candidates for deletion (3rd param): */
        char *worst_basename = NULL;
        double cur_size = get_dirsize_find_largest_dir(dirname, &worst_basename, excluded_basename);
        if (cur_size <= cap_size || !worst_basename)
        {
            log_info("cur_size:%.0f cap_size:%.0f, no (more) trimming", cur_size, cap_size);
            free(worst_basename);
            break;
        }
        log("%s is %.0f bytes (more than %.0fMiB), deleting '%s'",
                dirname, cur_size, cap_size / (1024*1024), worst_basename);
        char *d = concat_path_file(dirname, worst_basename);
        free(worst_basename);
        delete_dump_dir(d);
        free(d);
    }
}
예제 #2
0
파일: abrtd.c 프로젝트: wlindauer/abrt
/* Queueing the process will also lead to cleaning up the dump location.
 */
static void queue_post_craete_process(struct abrt_server_proc *proc)
{
    load_abrt_conf();
    struct abrt_server_proc *running = s_dir_queue == NULL ? NULL
                                                           : (struct abrt_server_proc *)s_dir_queue->data;
    if (g_settings_nMaxCrashReportsSize == 0)
        goto consider_processing;

    const char *full_path_ignored = running != NULL ? running->dirname
                                                    : proc->dirname;
    const char *ignored = strrchr(full_path_ignored, '/');
    if (NULL == ignored)
        /* Paranoia, this should not happen. */
        ignored = full_path_ignored;
    else
        /* Move behind '/' */
        ++ignored;

    char *worst_dir = NULL;
    const double max_size = 1024 * 1024 * g_settings_nMaxCrashReportsSize;
    while (get_dirsize_find_largest_dir(g_settings_dump_location, &worst_dir, ignored) >= max_size
           && worst_dir)
    {
        const char *kind = "old";

        GList *proc_of_deleted_item = NULL;
        if (proc != NULL && strcmp(worst_dir, proc->dirname) == 0)
        {
            kind = "new";
            stop_abrt_server(proc);
            proc = NULL;
        }
        else if ((proc_of_deleted_item = g_list_find_custom(s_dir_queue, worst_dir, (GCompareFunc)abrt_server_compare_dirname)))
        {
            kind = "unprocessed";
            struct abrt_server_proc *removed_proc = (struct abrt_server_proc *)proc_of_deleted_item->data;
            s_dir_queue = g_list_delete_link(s_dir_queue, proc_of_deleted_item);
            stop_abrt_server(removed_proc);
        }

        log_warning("Size of '%s' >= %u MB (MaxCrashReportsSize), deleting %s directory '%s'",
                g_settings_dump_location, g_settings_nMaxCrashReportsSize,
                kind, worst_dir);

        char *deleted = concat_path_file(g_settings_dump_location, worst_dir);
        free(worst_dir);
        worst_dir = NULL;

        struct dump_dir *dd = dd_opendir(deleted, DD_FAIL_QUIETLY_ENOENT);
        if (dd != NULL)
            dd_delete(dd);

        free(deleted);
    }

consider_processing:
    /* If the process survived cleaning up the dump location, append it to the
     * post-create queue.
     */
    if (proc != NULL)
        s_dir_queue = g_list_append(s_dir_queue, proc);

    /* If there were no running post-crate process before we added the
     * currently handled process to the post-create queue, start processing of
     * the currently handled process.
     */
    if (running == NULL)
        notify_next_post_create_process(NULL/*finished*/);
}