void delete_manifest(Manifest *manifest) { if(manifest != NULL) { delete_distribution_array(manifest->distribution_array); delete_activation_array(manifest->activation_array); delete_snapshots_array(manifest->snapshots_array); delete_target_array(manifest->target_array); g_free(manifest); } }
int restore(const gchar *manifest_file, const unsigned int max_concurrent_transfers, const int transfer_only, const int all, const gchar *old_manifest, const gchar *coordinator_profile_path, gchar *profile, const gboolean no_upgrade, const gchar *container_filter, const gchar *component_filter) { /* Generate a distribution array from the manifest file */ Manifest *manifest = open_provided_or_previous_manifest_file(manifest_file, coordinator_profile_path, profile, MANIFEST_SNAPSHOT_FLAG, container_filter, component_filter); if(manifest == NULL) { g_print("[coordinator]: Error while opening manifest file!\n"); return 1; } else { int exit_status; GPtrArray *snapshots_array; gchar *old_manifest_file; if(old_manifest == NULL) old_manifest_file = determine_previous_manifest_file(coordinator_profile_path, profile); else old_manifest_file = g_strdup(old_manifest); if(no_upgrade || old_manifest_file == NULL) { g_printerr("[coordinator]: Sending snapshots of all components...\n"); snapshots_array = manifest->snapshots_array; } else { GPtrArray *old_snapshots_array = create_snapshots_array(old_manifest_file, container_filter, component_filter); g_printerr("[coordinator]: Snapshotting state of moved components...\n"); snapshots_array = subtract_snapshot_mappings(manifest->snapshots_array, old_snapshots_array); delete_snapshots_array(old_snapshots_array); } if(send_snapshots(snapshots_array, manifest->target_array, max_concurrent_transfers, all) /* First, send the snapshots to the remote machines */ && (transfer_only || restore_services(snapshots_array, manifest->target_array))) /* Then, restore them on the remote machines */ exit_status = 0; else exit_status = 1; /* Cleanup */ g_free(old_manifest_file); if(!no_upgrade && old_manifest_file != NULL) g_ptr_array_free(snapshots_array, TRUE); delete_manifest(manifest); /* Return the exit status */ return exit_status; } }
GPtrArray *create_snapshots_array(const gchar *manifest_file, const gchar *container_filter, const gchar *component_filter) { xmlDocPtr doc; xmlNodePtr node_root; xmlXPathObjectPtr result; GPtrArray *snapshots_array; /* Parse the XML document */ if((doc = xmlParseFile(manifest_file)) == NULL) { g_printerr("Error with parsing the manifest XML file!\n"); xmlCleanupParser(); return NULL; } /* Retrieve root element */ node_root = xmlDocGetRootElement(doc); if(node_root == NULL) { g_printerr("The distribution manifest XML file is empty!\n"); xmlFreeDoc(doc); xmlCleanupParser(); return NULL; } /* Query the distribution elements */ result = executeXPathQuery(doc, "/manifest/snapshots/mapping"); /* Initialize snapshots array */ snapshots_array = g_ptr_array_new(); /* Iterate over all the distribution elements and add them to the array */ if(result) { xmlNodeSetPtr nodeset = result->nodesetval; unsigned int i; /* Iterate over all the mapping elements */ for(i = 0; i < nodeset->nodeNr; i++) { xmlNodePtr mapping_children = nodeset->nodeTab[i]->children; gchar *component = NULL; gchar *container = NULL; gchar *target = NULL; gchar *service = NULL; gchar *type = NULL; SnapshotMapping *mapping = (SnapshotMapping*)g_malloc(sizeof(SnapshotMapping)); /* Iterate over all the mapping item children (service,target,targetProperty,type,dependsOn elements) */ while(mapping_children != NULL) { if(xmlStrcmp(mapping_children->name, (xmlChar*) "component") == 0) component = duplicate_node_text(mapping_children); else if(xmlStrcmp(mapping_children->name, (xmlChar*) "container") == 0) container = duplicate_node_text(mapping_children); else if(xmlStrcmp(mapping_children->name, (xmlChar*) "target") == 0) target = duplicate_node_text(mapping_children); else if(xmlStrcmp(mapping_children->name, (xmlChar*) "service") == 0) service = duplicate_node_text(mapping_children); else if(xmlStrcmp(mapping_children->name, (xmlChar*) "type") == 0) type = duplicate_node_text(mapping_children); mapping_children = mapping_children->next; } mapping->component = component; mapping->container = container; mapping->target = target; mapping->service = service; mapping->type = type; mapping->transferred = FALSE; if(mapping_is_selected(mapping, container_filter, component_filter)) { if(component == NULL || container == NULL || target == NULL || service == NULL || type == NULL) { /* Check if all mandatory properties have been provided */ g_printerr("A mandatory property seems to be missing. Have you provided a correct\n"); g_printerr("manifest file?\n"); delete_snapshots_array(snapshots_array); snapshots_array = NULL; break; } else g_ptr_array_add(snapshots_array, mapping); /* Add the mapping to the array */ } else delete_snapshot_mapping(mapping); } xmlXPathFreeObject(result); } /* Cleanup */ xmlFreeDoc(doc); xmlCleanupParser(); /* Sort the snapshots array */ if(snapshots_array != NULL) g_ptr_array_sort(snapshots_array, (GCompareFunc)compare_snapshot_mapping); /* Return the snapshots array */ return snapshots_array; }