int map_snapshot_items(GPtrArray *snapshots_array, GPtrArray *target_array, map_snapshot_item_function map_snapshot_item, complete_snapshot_item_mapping_function complete_snapshot_item_mapping) { unsigned int num_processed = 0; int status = TRUE; GHashTable *pid_table = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL); while(num_processed < snapshots_array->len) { unsigned int i; for(i = 0; i < snapshots_array->len; i++) { SnapshotMapping *mapping = g_ptr_array_index(snapshots_array, i); Target *target = find_target(target_array, mapping->target); if(!mapping->transferred && request_available_target_core(target)) /* Check if machine has any cores available, if not wait and try again later */ { gchar **arguments = generate_activation_arguments(target, mapping->container); /* Generate an array of key=value pairs from container properties */ unsigned int arguments_length = g_strv_length(arguments); /* Determine length of the activation arguments array */ pid_t pid = map_snapshot_item(mapping, target, arguments, arguments_length); gint *pid_ptr; /* Add pid and mapping to the hash table */ pid_ptr = g_malloc(sizeof(gint)); *pid_ptr = pid; g_hash_table_insert(pid_table, pid_ptr, mapping); /* Cleanup */ g_strfreev(arguments); } } if(!wait_to_complete_snapshot_item(pid_table, target_array, complete_snapshot_item_mapping)) status = FALSE; num_processed++; } g_hash_table_destroy(pid_table); return status; }
static ActivationStatus activate(GPtrArray *union_array, const ActivationMappingKey *key, GPtrArray *target_array, const gboolean dry_run, GHashTable *pids) { /* Retrieve the mapping from the union array */ ActivationMapping *actual_mapping = find_activation_mapping(union_array, key); /* First, activate all inter-dependency mappings */ if(actual_mapping->depends_on != NULL) { unsigned int i; ActivationStatus status; for(i = 0; i < actual_mapping->depends_on->len; i++) { ActivationMappingKey *dependency = g_ptr_array_index(actual_mapping->depends_on, i); status = activate(union_array, dependency, target_array, dry_run, pids); if(status != ACTIVATION_DONE) return status; /* If any of the inter-dependencies has not been activated yet, relay its status */ } } /* Finally, activate the mapping itself if it is not activated yet */ switch(actual_mapping->status) { case ACTIVATIONMAPPING_DEACTIVATED: { Target *target = find_target(target_array, actual_mapping->target); if(request_available_target_core(target)) /* Check if machine has any cores available, if not wait and try again later */ { gchar **arguments = generate_activation_arguments(target); /* Generate an array of key=value pairs from infrastructure properties */ unsigned int arguments_size = g_strv_length(arguments); /* Determine length of the activation arguments array */ gchar *interface = find_target_client_interface(target); pid_t pid; print_activation_step(TRUE, actual_mapping, arguments, arguments_size); /* Print debug message */ if(dry_run) pid = exec_true(); /* Execute dummy process */ else pid = exec_activate(interface, actual_mapping->target, actual_mapping->type, arguments, arguments_size, actual_mapping->service); /* Execute the activation operation asynchronously */ /* Cleanup */ g_strfreev(arguments); if(pid == -1) { g_printerr("[target: %s]: Cannot fork activation process of service: %s!\n", actual_mapping->target, actual_mapping->key); return ACTIVATION_ERROR; } else { gint *pidKey = g_malloc(sizeof(gint)); *pidKey = pid; actual_mapping->status = ACTIVATIONMAPPING_IN_PROGRESS; /* Mark activation mapping as in progress */ g_hash_table_insert(pids, pidKey, actual_mapping); /* Add mapping to the pids table so that we can retrieve its status later */ return ACTIVATION_IN_PROGRESS; } } else return ACTIVATION_WAIT; } case ACTIVATIONMAPPING_ACTIVATED: return ACTIVATION_DONE; case ACTIVATIONMAPPING_IN_PROGRESS: return ACTIVATION_IN_PROGRESS; default: return ACTIVATION_ERROR; /* Should never happen */ } }
static int deactivate(GPtrArray *union_array, const ActivationMappingKey *key, GPtrArray *target_array, const gboolean dry_run, GHashTable *pids) { /* Retrieve the mapping from the union array */ ActivationMapping *actual_mapping = find_activation_mapping(union_array, key); /* Find all interdependent mapping on this mapping */ GPtrArray *interdependent_mappings = find_interdependent_mappings(union_array, actual_mapping); /* First deactivate all mappings which have an inter-dependency on this mapping */ unsigned int i; for(i = 0; i < interdependent_mappings->len; i++) { ActivationMapping *dependency_mapping = g_ptr_array_index(interdependent_mappings, i); ActivationStatus status = deactivate(union_array, (ActivationMappingKey*)dependency_mapping, target_array, dry_run, pids); if(status != ACTIVATION_DONE) { g_ptr_array_free(interdependent_mappings, TRUE); return status; /* If any inter-dependency is not deactivated, relay its status */ } } g_ptr_array_free(interdependent_mappings, TRUE); /* Finally deactivate the mapping itself if it has not been deactivated yet */ switch(actual_mapping->status) { case ACTIVATIONMAPPING_ACTIVATED: { Target *target = find_target(target_array, actual_mapping->target); if(target == NULL) { g_print("[target: %s]: Skip deactivation of service with key: %s deploying package: %s since machine is not present!\n", actual_mapping->key, actual_mapping->target, actual_mapping->service); actual_mapping->status = ACTIVATIONMAPPING_DEACTIVATED; return ACTIVATION_DONE; } else if(request_available_target_core(target)) { gchar **arguments = generate_activation_arguments(target); /* Generate an array of key=value pairs from infrastructure properties */ unsigned int arguments_size = g_strv_length(arguments); /* Determine length of the activation arguments array */ gchar *interface = find_target_client_interface(target); pid_t pid; print_activation_step(FALSE, actual_mapping, arguments, arguments_size); /* Print debug message */ if(dry_run) pid = exec_true(); /* Execute dummy process */ else pid = exec_deactivate(interface, actual_mapping->target, actual_mapping->type, arguments, arguments_size, actual_mapping->service); /* Execute the deactivation operation asynchronously */ /* Cleanup */ g_free(arguments); if(pid == -1) { g_printerr("[target: %s]: Cannot fork deactivation process of service: %s!\n", actual_mapping->target, actual_mapping->key); return ACTIVATION_ERROR; } else { gint *pidKey = g_malloc(sizeof(gint)); *pidKey = pid; actual_mapping->status = ACTIVATIONMAPPING_IN_PROGRESS; /* Mark activation mapping as in progress */ g_hash_table_insert(pids, pidKey, actual_mapping); /* Add mapping to the pids table so that we can retrieve its status later */ return ACTIVATION_IN_PROGRESS; } } else return ACTIVATION_WAIT; } case ACTIVATIONMAPPING_DEACTIVATED: return ACTIVATION_DONE; case ACTIVATIONMAPPING_IN_PROGRESS: return ACTIVATION_IN_PROGRESS; default: return ACTIVATION_ERROR; /* Should never happen */ } }