Better atomicity of moving .repodata/ -> repodata/
authorTomas Mlcoch <tmlcoch@redhat.com>
Thu, 8 Nov 2012 14:57:21 +0000 (15:57 +0100)
committerTomas Mlcoch <tmlcoch@redhat.com>
Thu, 8 Nov 2012 14:57:21 +0000 (15:57 +0100)
src/createrepo_c.c
src/mergerepo_c.c

index a2b003e..a6f9dad 100644 (file)
@@ -990,78 +990,15 @@ main(int argc, char **argv)
     g_mutex_free(user_data.mutex_oth);
 
 
-    // Close db
-
-    cr_destroy_primary_db_statements(user_data.pri_statements);
-    cr_destroy_filelists_db_statements(user_data.fil_statements);
-    cr_destroy_other_db_statements(user_data.oth_statements);
-
-    cr_close_primary_db(pri_db, NULL);
-    cr_close_filelists_db(fil_db, NULL);
-    cr_close_other_db(oth_db, NULL);
-
-
-    // Move files from out_repo into tmp_out_repo
-
-    g_debug("Moving data from %s", out_repo);
-
-    if (g_file_test(out_repo, G_FILE_TEST_EXISTS)) {
-
-        // Delete old metadata
-        g_debug("Removing old metadata from %s", out_repo);
-        cr_remove_metadata_classic(out_dir, cmd_options->retain_old);
-
-        // Move files from out_repo to tmp_out_repo
-        GDir *dirp;
-        dirp = g_dir_open (out_repo, 0, NULL);
-        if (!dirp) {
-            g_critical("Cannot open directory: %s", out_repo);
-            exit(1);
-        }
-
-        const gchar *filename;
-        while ((filename = g_dir_read_name(dirp))) {
-            gchar *full_path = g_strconcat(out_repo, filename, NULL);
-            gchar *new_full_path = g_strconcat(tmp_out_repo, filename, NULL);
-
-            if (g_rename(full_path, new_full_path) == -1) {
-                g_critical("Cannot move file %s -> %s", full_path, new_full_path);
-            } else {
-                g_debug("Moved %s -> %s", full_path, new_full_path);
-            }
-
-            g_free(full_path);
-            g_free(new_full_path);
-        }
-
-        g_dir_close(dirp);
-
-        // Remove out_repo
-        if (g_rmdir(out_repo) == -1) {
-            g_critical("Cannot remove %s", out_repo);
-        } else {
-            g_debug("Old out repo %s removed", out_repo);
-        }
-    }
-
-
-    // Rename tmp_out_repo to out_repo
-    if (g_rename(tmp_out_repo, out_repo) == -1) {
-        g_critical("Cannot rename %s -> %s", tmp_out_repo, out_repo);
-    } else {
-        g_debug("Renamed %s -> %s", tmp_out_repo, out_repo);
-    }
-
-
     // Create repomd records for each file
 
     g_debug("Generating repomd.xml");
 
     cr_Repomd repomd_obj = cr_new_repomd();
 
-    cr_RepomdRecord pri_xml_rec = cr_new_repomdrecord("repodata/primary.xml.gz");
-    cr_RepomdRecord fil_xml_rec = cr_new_repomdrecord("repodata/filelists.xml.gz");
-    cr_RepomdRecord oth_xml_rec = cr_new_repomdrecord("repodata/other.xml.gz");
+    cr_RepomdRecord pri_xml_rec = cr_new_repomdrecord(pri_xml_filename);
+    cr_RepomdRecord fil_xml_rec = cr_new_repomdrecord(fil_xml_filename);
+    cr_RepomdRecord oth_xml_rec = cr_new_repomdrecord(oth_xml_filename);
     cr_RepomdRecord pri_db_rec               = NULL;
     cr_RepomdRecord fil_db_rec               = NULL;
     cr_RepomdRecord oth_db_rec               = NULL;
@@ -1072,90 +1009,60 @@ main(int argc, char **argv)
 
     // XML
 
-    cr_fill_repomdrecord(out_dir, pri_xml_rec, &(cmd_options->checksum_type));
-    cr_fill_repomdrecord(out_dir, fil_xml_rec, &(cmd_options->checksum_type));
-    cr_fill_repomdrecord(out_dir, oth_xml_rec, &(cmd_options->checksum_type));
+    cr_fill_repomdrecord(pri_xml_rec, &(cmd_options->checksum_type));
+    cr_fill_repomdrecord(fil_xml_rec, &(cmd_options->checksum_type));
+    cr_fill_repomdrecord(oth_xml_rec, &(cmd_options->checksum_type));
 
 
     // Groupfile
 
     if (groupfile) {
-        gchar *groupfile_name;
-        groupfile_name = g_strconcat("repodata/",
-                                     cr_get_filename(groupfile),
-                                     NULL);
-        groupfile_rec = cr_new_repomdrecord(groupfile_name);
-        compressed_groupfile_rec = cr_new_repomdrecord(groupfile_name);
-        cr_process_groupfile_repomdrecord(out_dir,
-                                          groupfile_rec,
+        groupfile_rec = cr_new_repomdrecord(groupfile);
+        compressed_groupfile_rec = cr_new_repomdrecord(groupfile);
+        cr_process_groupfile_repomdrecord(groupfile_rec,
                                           compressed_groupfile_rec,
                                           &(cmd_options->checksum_type),
                                           groupfile_compression);
-        g_free(groupfile_name);
     }
 
 
     // Updateinfo
 
     if (updateinfo) {
-        gchar *updateinfo_name;
-        updateinfo_name = g_strconcat("repodata/",
-                                      cr_get_filename(updateinfo),
-                                      NULL);
-        updateinfo_rec = cr_new_repomdrecord(updateinfo_name);
-        cr_fill_repomdrecord(out_dir, updateinfo_rec, &(cmd_options->checksum_type));
-        g_free(updateinfo_name);
+        updateinfo_rec = cr_new_repomdrecord(updateinfo);
+        cr_fill_repomdrecord(updateinfo_rec, &(cmd_options->checksum_type));
     }
 
 
     // Sqlite db
 
     if (!cmd_options->no_database) {
-        gchar *pri_db_name = g_strconcat("repodata/primary.sqlite",
+
+        gchar *pri_db_name = g_strconcat(pri_db_filename,
                                          sqlite_compression_suffix, NULL);
-        gchar *fil_db_name = g_strconcat("repodata/filelists.sqlite",
+        gchar *fil_db_name = g_strconcat(fil_db_filename,
                                          sqlite_compression_suffix, NULL);
-        gchar *oth_db_name = g_strconcat("repodata/other.sqlite",
+        gchar *oth_db_name = g_strconcat(oth_db_filename,
                                          sqlite_compression_suffix, NULL);
 
-        gchar *tmp_pri_db_path;
-        gchar *tmp_fil_db_path;
-        gchar *tmp_oth_db_path;
-
-
-        // Open dbs again (but from the new (final) location)
-        // and insert XML checksums
-
-        tmp_pri_db_path = g_strconcat(out_dir, "repodata/primary.sqlite", NULL);
-        tmp_fil_db_path = g_strconcat(out_dir, "repodata/filelists.sqlite", NULL);
-        tmp_oth_db_path = g_strconcat(out_dir, "repodata/other.sqlite", NULL);
-
-        sqlite3_open(tmp_pri_db_path, &pri_db);
-        sqlite3_open(tmp_fil_db_path, &fil_db);
-        sqlite3_open(tmp_oth_db_path, &oth_db);
-
         cr_dbinfo_update(pri_db, pri_xml_rec->checksum, NULL);
         cr_dbinfo_update(fil_db, fil_xml_rec->checksum, NULL);
         cr_dbinfo_update(oth_db, oth_xml_rec->checksum, NULL);
 
-        sqlite3_close(pri_db);
-        sqlite3_close(fil_db);
-        sqlite3_close(oth_db);
+        cr_close_primary_db(pri_db, NULL);
+        cr_close_filelists_db(fil_db, NULL);
+        cr_close_other_db(oth_db, NULL);
 
 
         // Compress dbs
 
-        cr_compress_file(tmp_pri_db_path, NULL, sqlite_compression);
-        cr_compress_file(tmp_fil_db_path, NULL, sqlite_compression);
-        cr_compress_file(tmp_oth_db_path, NULL, sqlite_compression);
-
-        remove(tmp_pri_db_path);
-        remove(tmp_fil_db_path);
-        remove(tmp_oth_db_path);
+        cr_compress_file(pri_db_filename, NULL, sqlite_compression);
+        cr_compress_file(fil_db_filename, NULL, sqlite_compression);
+        cr_compress_file(oth_db_filename, NULL, sqlite_compression);
 
-        g_free(tmp_pri_db_path);
-        g_free(tmp_fil_db_path);
-        g_free(tmp_oth_db_path);
+        remove(pri_db_filename);
+        remove(fil_db_filename);
+        remove(oth_db_filename);
 
 
         // Prepare repomd records
@@ -1164,9 +1071,9 @@ main(int argc, char **argv)
         fil_db_rec = cr_new_repomdrecord(fil_db_name);
         oth_db_rec = cr_new_repomdrecord(oth_db_name);
 
-        cr_fill_repomdrecord(out_dir, pri_db_rec, &(cmd_options->checksum_type));
-        cr_fill_repomdrecord(out_dir, fil_db_rec, &(cmd_options->checksum_type));
-        cr_fill_repomdrecord(out_dir, oth_db_rec, &(cmd_options->checksum_type));
+        cr_fill_repomdrecord(pri_db_rec, &(cmd_options->checksum_type));
+        cr_fill_repomdrecord(fil_db_rec, &(cmd_options->checksum_type));
+        cr_fill_repomdrecord(oth_db_rec, &(cmd_options->checksum_type));
 
         g_free(pri_db_name);
         g_free(fil_db_name);
@@ -1177,19 +1084,18 @@ main(int argc, char **argv)
     // Add checksums into files names
 
     if (cmd_options->unique_md_filenames) {
-        cr_rename_repomdrecord_file(out_dir, pri_xml_rec);
-        cr_rename_repomdrecord_file(out_dir, fil_xml_rec);
-        cr_rename_repomdrecord_file(out_dir, oth_xml_rec);
-        cr_rename_repomdrecord_file(out_dir, pri_db_rec);
-        cr_rename_repomdrecord_file(out_dir, fil_db_rec);
-        cr_rename_repomdrecord_file(out_dir, oth_db_rec);
-        cr_rename_repomdrecord_file(out_dir, groupfile_rec);
-        cr_rename_repomdrecord_file(out_dir, compressed_groupfile_rec);
-        cr_rename_repomdrecord_file(out_dir, updateinfo_rec);
+        cr_rename_repomdrecord_file(pri_xml_rec);
+        cr_rename_repomdrecord_file(fil_xml_rec);
+        cr_rename_repomdrecord_file(oth_xml_rec);
+        cr_rename_repomdrecord_file(pri_db_rec);
+        cr_rename_repomdrecord_file(fil_db_rec);
+        cr_rename_repomdrecord_file(oth_db_rec);
+        cr_rename_repomdrecord_file(groupfile_rec);
+        cr_rename_repomdrecord_file(compressed_groupfile_rec);
+        cr_rename_repomdrecord_file(updateinfo_rec);
     }
 
 
-
     // Gen xml
 
     cr_repomd_set_record(repomd_obj, pri_xml_rec,    CR_MD_PRIMARY_XML);
@@ -1228,9 +1134,10 @@ main(int argc, char **argv)
 
     cr_free_repomd(repomd_obj);
 
+
     // Write repomd.xml
 
-    gchar *repomd_path = g_strconcat(out_repo, "repomd.xml", NULL);
+    gchar *repomd_path = g_strconcat(tmp_out_repo, "repomd.xml", NULL);
     FILE *frepomd = fopen(repomd_path, "w");
     if (!frepomd || !repomd_xml) {
         g_critical("Generate of repomd.xml failed");
@@ -1242,6 +1149,58 @@ main(int argc, char **argv)
     g_free(repomd_path);
 
 
+    // Move files from out_repo into tmp_out_repo
+
+    g_debug("Moving data from %s", out_repo);
+
+    if (g_file_test(out_repo, G_FILE_TEST_EXISTS)) {
+
+        // Delete old metadata
+        g_debug("Removing old metadata from %s", out_repo);
+        cr_remove_metadata_classic(out_dir, cmd_options->retain_old);
+
+        // Move files from out_repo to tmp_out_repo
+        GDir *dirp;
+        dirp = g_dir_open (out_repo, 0, NULL);
+        if (!dirp) {
+            g_critical("Cannot open directory: %s", out_repo);
+            exit(1);
+        }
+
+        const gchar *filename;
+        while ((filename = g_dir_read_name(dirp))) {
+            gchar *full_path = g_strconcat(out_repo, filename, NULL);
+            gchar *new_full_path = g_strconcat(tmp_out_repo, filename, NULL);
+
+            if (g_rename(full_path, new_full_path) == -1) {
+                g_critical("Cannot move file %s -> %s", full_path, new_full_path);
+            } else {
+                g_debug("Moved %s -> %s", full_path, new_full_path);
+            }
+
+            g_free(full_path);
+            g_free(new_full_path);
+        }
+
+        g_dir_close(dirp);
+
+        // Remove out_repo
+        if (g_rmdir(out_repo) == -1) {
+            g_critical("Cannot remove %s", out_repo);
+        } else {
+            g_debug("Old out repo %s removed", out_repo);
+        }
+    }
+
+
+    // Rename tmp_out_repo to out_repo
+    if (g_rename(tmp_out_repo, out_repo) == -1) {
+        g_critical("Cannot rename %s -> %s", tmp_out_repo, out_repo);
+    } else {
+        g_debug("Renamed %s -> %s", tmp_out_repo, out_repo);
+    }
+
+
     // Clean up
 
     g_debug("Memory cleanup");
index 6c3c2b3..e1c399b 100644 (file)
@@ -980,7 +980,6 @@ dump_merged_metadata(GHashTable *merged_hashtable,
     CR_FILE *fil_f;
     CR_FILE *oth_f;
 
-    const char *db_suffix = cr_compression_suffix(cmd_options->db_compression_type);
     const char *groupfile_suffix = cr_compression_suffix(cmd_options->groupfile_compression_type);
 
     gchar *pri_xml_filename = g_strconcat(cmd_options->tmp_out_repo, "/primary.xml.gz", NULL);
@@ -1131,62 +1130,13 @@ dump_merged_metadata(GHashTable *merged_hashtable,
     }
 
 
-    // Move files from out_repo into tmp_out_repo
-
-    g_debug("Moving data from %s", cmd_options->out_repo);
-
-    if (g_file_test(cmd_options->out_repo, G_FILE_TEST_EXISTS)) {
-
-        // Move files from out_repo to tmp_out_repo
-        GDir *dirp;
-        dirp = g_dir_open (cmd_options->out_repo, 0, NULL);
-        if (!dirp) {
-            g_critical("Cannot open directory: %s", cmd_options->out_repo);
-            exit(1);
-        }
-
-        const gchar *filename;
-        while ((filename = g_dir_read_name(dirp))) {
-            gchar *full_path = g_strconcat(cmd_options->out_repo, filename, NULL);
-            gchar *new_full_path = g_strconcat(cmd_options->tmp_out_repo, filename, NULL);
-
-            if (g_rename(full_path, new_full_path) == -1) {
-                g_critical("Cannot move file %s -> %s", full_path, new_full_path);
-            } else {
-                g_debug("Moved %s -> %s", full_path, new_full_path);
-            }
-
-            g_free(full_path);
-            g_free(new_full_path);
-        }
-
-        g_dir_close(dirp);
-
-        // Remove out_repo
-        if (g_rmdir(cmd_options->out_repo) == -1) {
-            g_critical("Cannot remove %s", cmd_options->out_repo);
-        } else {
-            g_debug("Old out repo %s removed", cmd_options->out_repo);
-        }
-    }
-
-
-    // Rename tmp_out_repo to out_repo
-    if (g_rename(cmd_options->tmp_out_repo, cmd_options->out_repo) == -1) {
-        g_critical("Cannot rename %s -> %s", cmd_options->tmp_out_repo, cmd_options->out_repo);
-    } else {
-        g_debug("Renamed %s -> %s", cmd_options->tmp_out_repo, cmd_options->out_repo);
-    }
-
 
 
     // Prepare repomd records
 
-    char *out_dir = cmd_options->out_dir;
-
-    cr_RepomdRecord pri_xml_rec = cr_new_repomdrecord("repodata/primary.xml.gz");
-    cr_RepomdRecord fil_xml_rec = cr_new_repomdrecord("repodata/filelists.xml.gz");
-    cr_RepomdRecord oth_xml_rec = cr_new_repomdrecord("repodata/other.xml.gz");
+    cr_RepomdRecord pri_xml_rec = cr_new_repomdrecord(pri_xml_filename);
+    cr_RepomdRecord fil_xml_rec = cr_new_repomdrecord(fil_xml_filename);
+    cr_RepomdRecord oth_xml_rec = cr_new_repomdrecord(oth_xml_filename);
     cr_RepomdRecord pri_db_rec               = NULL;
     cr_RepomdRecord fil_db_rec               = NULL;
     cr_RepomdRecord oth_db_rec               = NULL;
@@ -1198,50 +1148,46 @@ dump_merged_metadata(GHashTable *merged_hashtable,
 
     // XML
 
-    cr_fill_repomdrecord(out_dir, pri_xml_rec, NULL);
-    cr_fill_repomdrecord(out_dir, fil_xml_rec, NULL);
-    cr_fill_repomdrecord(out_dir, oth_xml_rec, NULL);
+    cr_fill_repomdrecord(pri_xml_rec, NULL);
+    cr_fill_repomdrecord(fil_xml_rec, NULL);
+    cr_fill_repomdrecord(oth_xml_rec, NULL);
 
 
     // Groupfile
 
     if (groupfile) {
-        gchar *groupfile_name = g_strconcat("repodata/",
-                                            cr_get_filename(groupfile), NULL);
-        groupfile_rec = cr_new_repomdrecord(groupfile_name);
-        compressed_groupfile_rec = cr_new_repomdrecord(groupfile_name);
-
-        cr_process_groupfile_repomdrecord(out_dir,
-                                          groupfile_rec,
+        groupfile_rec = cr_new_repomdrecord(groupfile);
+        compressed_groupfile_rec = cr_new_repomdrecord(groupfile);
+        cr_process_groupfile_repomdrecord(groupfile_rec,
                                           compressed_groupfile_rec,
                                           NULL,
                                           cmd_options->groupfile_compression_type);
-        g_free(groupfile_name);
     }
 
 
     // Update info
 
     if (!cmd_options->noupdateinfo) {
-        gchar *update_info_name = g_strconcat("repodata/updateinfo.xml",
-                                              groupfile_suffix, NULL);
-        update_info_rec = cr_new_repomdrecord(update_info_name);
-        cr_fill_repomdrecord(out_dir, update_info_rec, NULL);
-        g_free(update_info_name);
+        update_info_rec = cr_new_repomdrecord(update_info_filename);
+        cr_fill_repomdrecord(update_info_rec, NULL);
     }
 
 
     // Pkgorigins
 
     if (cmd_options->koji) {
-        pkgorigins_rec = cr_new_repomdrecord("repodata/pkgorigins.gz");
-        cr_fill_repomdrecord(out_dir, pkgorigins_rec, NULL);
+        gchar *pkgorigins_path = g_strconcat(cmd_options->tmp_out_repo, "pkgorigins.gz", NULL);
+        pkgorigins_rec = cr_new_repomdrecord(pkgorigins_path);
+        cr_fill_repomdrecord(pkgorigins_rec, NULL);
+        g_free(pkgorigins_path);
     }
 
 
     // Sqlite db
 
     if (!cmd_options->no_database) {
+        const char *db_suffix = cr_compression_suffix(cmd_options->db_compression_type);
+
         // Insert XML checksums into the dbs
         cr_dbinfo_update(pri_db, pri_xml_rec->checksum, NULL);
         cr_dbinfo_update(fil_db, fil_xml_rec->checksum, NULL);
@@ -1257,10 +1203,13 @@ dump_merged_metadata(GHashTable *merged_hashtable,
         cr_close_other_db(oth_db, NULL);
 
         // Compress dbs
+        gchar *pri_db_filename = g_strconcat(cmd_options->tmp_out_repo, "/primary.sqlite", NULL);
+        gchar *fil_db_filename = g_strconcat(cmd_options->tmp_out_repo, "/filelists.sqlite", NULL);
+        gchar *oth_db_filename = g_strconcat(cmd_options->tmp_out_repo, "/other.sqlite", NULL);
 
-        gchar *pri_db_filename = g_strconcat(cmd_options->out_repo, "/primary.sqlite", NULL);
-        gchar *fil_db_filename = g_strconcat(cmd_options->out_repo, "/filelists.sqlite", NULL);
-        gchar *oth_db_filename = g_strconcat(cmd_options->out_repo, "/other.sqlite", NULL);
+        gchar *pri_db_c_filename = g_strconcat(pri_db_filename, db_suffix, NULL);
+        gchar *fil_db_c_filename = g_strconcat(fil_db_filename, db_suffix, NULL);
+        gchar *oth_db_c_filename = g_strconcat(oth_db_filename, db_suffix, NULL);
 
         cr_compress_file(pri_db_filename, NULL, cmd_options->db_compression_type);
         cr_compress_file(fil_db_filename, NULL, cmd_options->db_compression_type);
@@ -1270,41 +1219,37 @@ dump_merged_metadata(GHashTable *merged_hashtable,
         remove(fil_db_filename);
         remove(oth_db_filename);
 
+        // Prepare repomd records
+        pri_db_rec = cr_new_repomdrecord(pri_db_c_filename);
+        fil_db_rec = cr_new_repomdrecord(fil_db_c_filename);
+        oth_db_rec = cr_new_repomdrecord(oth_db_c_filename);
+
         g_free(pri_db_filename);
         g_free(fil_db_filename);
         g_free(oth_db_filename);
 
-        // Prepare repomd records
-        gchar *pri_db_name = g_strconcat("repodata/primary.sqlite", db_suffix, NULL);
-        gchar *fil_db_name = g_strconcat("repodata/filelists.sqlite", db_suffix, NULL);
-        gchar *oth_db_name = g_strconcat("repodata/other.sqlite", db_suffix, NULL);
-
-        pri_db_rec = cr_new_repomdrecord(pri_db_name);
-        fil_db_rec = cr_new_repomdrecord(fil_db_name);
-        oth_db_rec = cr_new_repomdrecord(oth_db_name);
-
-        g_free(pri_db_name);
-        g_free(fil_db_name);
-        g_free(oth_db_name);
+        g_free(pri_db_c_filename);
+        g_free(fil_db_c_filename);
+        g_free(oth_db_c_filename);
 
-        cr_fill_repomdrecord(out_dir, pri_db_rec, NULL);
-        cr_fill_repomdrecord(out_dir, fil_db_rec, NULL);
-        cr_fill_repomdrecord(out_dir, oth_db_rec, NULL);
+        cr_fill_repomdrecord(pri_db_rec, NULL);
+        cr_fill_repomdrecord(fil_db_rec, NULL);
+        cr_fill_repomdrecord(oth_db_rec, NULL);
     }
 
 
     // Add checksums into files names
 
-    cr_rename_repomdrecord_file(out_dir, pri_xml_rec);
-    cr_rename_repomdrecord_file(out_dir, fil_xml_rec);
-    cr_rename_repomdrecord_file(out_dir, oth_xml_rec);
-    cr_rename_repomdrecord_file(out_dir, pri_db_rec);
-    cr_rename_repomdrecord_file(out_dir, fil_db_rec);
-    cr_rename_repomdrecord_file(out_dir, oth_db_rec);
-    cr_rename_repomdrecord_file(out_dir, groupfile_rec);
-    cr_rename_repomdrecord_file(out_dir, compressed_groupfile_rec);
-    cr_rename_repomdrecord_file(out_dir, update_info_rec);
-    cr_rename_repomdrecord_file(out_dir, pkgorigins_rec);
+    cr_rename_repomdrecord_file(pri_xml_rec);
+    cr_rename_repomdrecord_file(fil_xml_rec);
+    cr_rename_repomdrecord_file(oth_xml_rec);
+    cr_rename_repomdrecord_file(pri_db_rec);
+    cr_rename_repomdrecord_file(fil_db_rec);
+    cr_rename_repomdrecord_file(oth_db_rec);
+    cr_rename_repomdrecord_file(groupfile_rec);
+    cr_rename_repomdrecord_file(compressed_groupfile_rec);
+    cr_rename_repomdrecord_file(update_info_rec);
+    cr_rename_repomdrecord_file(pkgorigins_rec);
 
 
     // Gen repomd.xml content
@@ -1327,7 +1272,7 @@ dump_merged_metadata(GHashTable *merged_hashtable,
     cr_free_repomd(repomd_obj);
 
     if (repomd_xml) {
-        gchar *repomd_path = g_strconcat(cmd_options->out_repo, "repomd.xml", NULL);
+        gchar *repomd_path = g_strconcat(cmd_options->tmp_out_repo, "repomd.xml", NULL);
         FILE *frepomd = fopen(repomd_path, "w");
         if (frepomd) {
             fputs(repomd_xml, frepomd);
@@ -1339,6 +1284,53 @@ dump_merged_metadata(GHashTable *merged_hashtable,
         g_critical("Generate of repomd.xml failed");
 
 
+    // Move files from out_repo into tmp_out_repo
+
+    g_debug("Moving data from %s", cmd_options->out_repo);
+    if (g_file_test(cmd_options->out_repo, G_FILE_TEST_EXISTS)) {
+
+        // Move files from out_repo to tmp_out_repo
+        GDir *dirp;
+        dirp = g_dir_open (cmd_options->out_repo, 0, NULL);
+        if (!dirp) {
+            g_critical("Cannot open directory: %s", cmd_options->out_repo);
+            exit(1);
+        }
+
+        const gchar *filename;
+        while ((filename = g_dir_read_name(dirp))) {
+            gchar *full_path = g_strconcat(cmd_options->out_repo, filename, NULL);
+            gchar *new_full_path = g_strconcat(cmd_options->tmp_out_repo, filename, NULL);
+
+            if (g_rename(full_path, new_full_path) == -1) {
+                g_critical("Cannot move file %s -> %s", full_path, new_full_path);
+            } else {
+                g_debug("Moved %s -> %s", full_path, new_full_path);
+            }
+
+            g_free(full_path);
+            g_free(new_full_path);
+        }
+
+        g_dir_close(dirp);
+
+        // Remove out_repo
+        if (g_rmdir(cmd_options->out_repo) == -1) {
+            g_critical("Cannot remove %s", cmd_options->out_repo);
+        } else {
+            g_debug("Old out repo %s removed", cmd_options->out_repo);
+        }
+    }
+
+
+    // Rename tmp_out_repo to out_repo
+    if (g_rename(cmd_options->tmp_out_repo, cmd_options->out_repo) == -1) {
+        g_critical("Cannot rename %s -> %s", cmd_options->tmp_out_repo, cmd_options->out_repo);
+    } else {
+        g_debug("Renamed %s -> %s", cmd_options->tmp_out_repo, cmd_options->out_repo);
+    }
+
+
     // Clean up
 
     g_free(repomd_xml);