#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define FILESYSTEM "filesystem" using namespace std; std::fstream log_file; void message_callback (guestfs_h *g, void *opaque, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len); /* Events we are interested in. This bitmask covers all trace and * debug messages. */ static const uint64_t event_bitmask = GUESTFS_EVENT_LIBRARY | GUESTFS_EVENT_WARNING | GUESTFS_EVENT_APPLIANCE | GUESTFS_EVENT_TRACE; // Function to show error messages from libguestfs void show_error(guestfs_h *g, const char* msg) { const char *err = guestfs_last_error(g); std::cerr << msg << ": " << (err ? err : "Unknown error") << std::endl; if (err) free((char*)err); } // Function to free the list of strings void free_list_of_strings(char **list) { char **p; for (p = list; *p; ++p) { free(*p); } free(list); } // Display lvs, devices, and partitions // This function will be called as per the requirement void display(char **strArr, std::string type) { if (strArr != NULL) { // Traverse and print the contents of devices for (char **p = strArr; *p != NULL; ++p) { std::cout << type << *p << std::endl; } } std::cout << "\n" << std::endl; } // Function to mount and synchronize changes in a separate thread void mountLocalAndSyncThread(guestfs_h *g, const char* baseMountDir) { // Mount the filesystem in read-only mode if (guestfs_mount_local(g, baseMountDir, GUESTFS_MOUNT_LOCAL_READONLY, 1, -1) < 0) { // show_error(g, "guestfs_mount_local() failed"); cout << "ERROR1: should go to guestfs_logger" < mountPoints; int mountCount = 1; // Iterating through list of filesystems for (char **p = filesystems; *p != NULL; p += 2) { const char* devicePath = *p; const char* deviceType = *(p + 1); std::cout << "Device Path :: " << devicePath << " and Device Type :: " << deviceType << std::endl; // Incase if the deviceType is unknown, we need to skip the mount process for the same // TODO:: Workaround or appropriate messsage or action plan still need to be decided. if(strcmp(deviceType, "unknown") == 0) { std::cout << "Disk type is unknown, skipping mount for device " << devicePath << std::endl; continue; } // Create a separate mount directory for each filesystem char mountPoint[100]; snprintf(mountPoint, sizeof(mountPoint), "/mount%d", mountCount); guestfs_mkmountpoint (g, mountPoint); // Mount the filesystem in read only mode if (guestfs_mount_ro(g, devicePath, mountPoint) < 0) { //show_error(g, "Failed to mount disk"); cout << "ERROR6: should go to guestfs_logger" <> x; } // Unmount the devices locally before waiting for threads to finish // Local unmount of respective mount point is required to interupt the FUSE main loop in each thread to proceed // We can map the thread with mountpoint incase if we want to close individual thread if (umount2(baseMountDir, MNT_DETACH) != 0) { std::cout << "Unmount failed for mount point: " << baseMountDir << std::endl; } else { std::cout << "Unmount successful for mount point: " << baseMountDir << std::endl; } // Wait for the synchronization thread to finish syncThread.join(); for (const auto& mountPoint : mountPoints) { // Unmount the filesystem after using it // This function is being called after local unmount if (guestfs_umount(g, mountPoint) == -1) { //show_error(g, "Failed to unmount filesystem"); cout << "ERROR7: should go to guestfs_logger" < duration = end - start; // Print the time taken in seconds std::cout << "Overall Time taken: " << duration.count() << " seconds" << std::endl; if (rmdir(baseMountDir) == -1) { std::cerr << "Failed to delete directory: " << baseMountDir << std::endl; } else { std::cout << "Deleted mount directory: " << baseMountDir << std::endl; } // Free the list of strings free_list_of_strings(filesystems); // Close the primary libguestfs handle and release resources guestfs_close(g); return 0; } void message_callback (guestfs_h *g, void *opaque, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len) { const int priority = LOG_USER|LOG_INFO; const char *err = guestfs_last_error(g); char *event_name, *msg; if (buf_len > 0) { event_name = guestfs_event_to_string (event); msg = strndup (buf, buf_len); //syslog (priority, "[%s] %s", event_name, msg); log_file <<"Internal msg from message_callback: " << msg << "\n"; log_file <<"custom Error from guestfs_last_error: " << err << "\n"; free (msg); free (event_name); } }