Example #1
0
sc_bool sc_fs_storage_shutdown(sc_segment **segments)
{    
    g_message("Shutdown sc-storage");

    g_message("Write segments");
    sc_fs_storage_write_to_path(segments);

    g_message("Save file memory state");
    if (sc_fm_save(fm_engine) != SC_RESULT_OK)
        g_critical("Error while saves file memory");


    g_free(repo_path);

    return SC_TRUE;
}
Example #2
0
sc_bool sc_fs_storage_write_to_path(sc_segment **segments)
{
    sc_uint32 idx = 0, header_size = 0;
    const sc_segment *segment = 0;
    sc_fs_storage_segments_header header;
    GChecksum * checksum = null_ptr;
    GIOChannel * output = null_ptr;
    gchar * tmp_filename = null_ptr;
    gsize bytes;
    sc_bool result = SC_TRUE;

    if (!g_file_test(repo_path, G_FILE_TEST_IS_DIR))
    {
        g_error("%s isn't a directory.", repo_path);
        return SC_FALSE;
    }

    // create temporary file

    output = _open_tmp_file(&tmp_filename);

    memset(&header, 0, sizeof(sc_fs_storage_segments_header));
    header.segments_num = 0;
    header.timestamp = g_get_real_time();
    header.version = sc_version_to_int(&SC_VERSION);

    g_io_channel_set_encoding(output, null_ptr, null_ptr);

    checksum = g_checksum_new(_checksum_type());
    g_checksum_reset(checksum);

    for (idx = 0; idx < SC_ADDR_SEG_MAX; idx++)
    {
        segment = segments[idx];
        if (segment == null_ptr)
            break; // stop save, because we allocate segment in order

        g_checksum_update(checksum, (guchar*)segment->elements, SC_SEG_ELEMENTS_SIZE_BYTE);
    }

    header.segments_num = idx;
    bytes = SC_STORAGE_SEG_CHECKSUM_SIZE;
    g_checksum_get_digest(checksum, header.checksum, &bytes);

    header_size = sizeof(header);
    if (g_io_channel_write_chars(output, (gchar*)&header_size, sizeof(header_size), &bytes, null_ptr) != G_IO_STATUS_NORMAL || bytes != sizeof(header_size))
    {
        g_error("Can't write header size: %s", tmp_filename);
        result = SC_FALSE;
        goto clean;
    }

    if (g_io_channel_write_chars(output, (gchar*)&header, header_size, &bytes, null_ptr) != G_IO_STATUS_NORMAL || bytes != header_size)
    {
        g_error("Can't write header: %s", tmp_filename);
        result = SC_FALSE;
        goto clean;
    }

    for (idx = 0; idx < header.segments_num; ++idx)
    {
        segment = segments[idx];
        g_assert(segment != null_ptr);

        if (g_io_channel_write_chars(output, (gchar*)segment->elements, SC_SEG_ELEMENTS_SIZE_BYTE, &bytes, null_ptr) != G_IO_STATUS_NORMAL || bytes != SC_SEG_ELEMENTS_SIZE_BYTE)
        {
            g_error("Can't write segment %d into %s", idx, tmp_filename);
            result = SC_FALSE;
            goto clean;
        }
    }

    if (result == SC_TRUE)
    {
        // rename main file
        if (g_file_test(tmp_filename, G_FILE_TEST_IS_REGULAR))
        {
            g_io_channel_shutdown(output, TRUE, NULL);
            output = null_ptr;

            if (g_rename(tmp_filename, segments_path) != 0)
            {
                g_error("Can't rename %s -> %s", tmp_filename, segments_path);
                result = SC_FALSE;
            }
        }

        // save file memory
        g_message("Save file memory state");
        if (sc_fm_save(fm_engine) != SC_RESULT_OK)
            g_critical("Error while saves file memory");
    }

    clean:
    {
        if (tmp_filename)
            g_free(tmp_filename);
        if (checksum)
            g_checksum_free(checksum);
        if (output)
            g_io_channel_shutdown(output, TRUE, null_ptr);
    }

    return result;
}