Hi @Richard W.M. Jones,

I am attaching a sample program of how we are using guestfs apis where we are 
getting this error guestfs_mount_local fail.

Please take a look into this.

Thanks,
Divyanshu

-----Original Message-----
From: Richard W.M. Jones <rjo...@redhat.com> 
Sent: Tuesday, September 19, 2023 5:36 PM
To: Raja Ram Sharma <rshar...@opentext.com>
Cc: Teja Konapalli <tkonapa...@opentext.com>; libguestfs@redhat.com; Divyanshu 
Kumar <dkum...@opentext.com>
Subject: Re: [EXTERNAL] - Re: LIBGUESTFS mount disk failure

CAUTION: This email originated from outside of the organization. Do not click 
links or open attachments unless you recognize the sender and know the content 
is safe. If you feel that the email is suspicious, please report it using 
PhishAlarm.


On Tue, Sep 19, 2023 at 11:59:43AM +0000, Raja Ram Sharma wrote:
> Hi Richard,
>
> Thank you for the response, will set both handler and let you know.
>
> when we try to execute guestfs_mount_local.
> Getting below error :
>
> [ 2023-09-19 13:34:05 ]  errno: ( 0 ) : mount_local: unknown option 
> 554101136 (this can happen if a program is compiled against a newer 
> version of libguestfs, then dynamically linked to an older version)

I attach what I said previously.

Rich.

> Setup details :
> OS : (PRETTY_NAME="Red Hat Enterprise Linux 8.2 (Ootpa)") Guesfs.h 
> version : 1.50 Guestfish version : guestfish 
> 1.38.4rhel=8,release=15.module+el8.2.0+5297+222a20af,libvirt
>
> In Below scenario:
> 1. guestfs_mount_local_run
> 2. umount /mountpoint
> 3. Again, while trying to mount, after sleep of 20sec.
>
>
> Thanks
> RR
>
>
>
>
>
> -----Original Message-----
> From: Richard W.M. Jones <rjo...@redhat.com>
> Sent: Tuesday, September 19, 2023 1:15 PM
> To: Raja Ram Sharma <rshar...@opentext.com>
> Cc: Teja Konapalli <tkonapa...@opentext.com>; libguestfs@redhat.com; 
> Divyanshu Kumar <dkum...@opentext.com>
> Subject: Re: [EXTERNAL] - Re: LIBGUESTFS mount disk failure
>
> CAUTION: This email originated from outside of the organization. Do not click 
> links or open attachments unless you recognize the sender and know the 
> content is safe. If you feel that the email is suspicious, please report it 
> using PhishAlarm.
>
>
> On Sun, Sep 17, 2023 at 04:11:25PM +0000, Raja Ram Sharma wrote:
> > One more help is needed :
> > https://urldefense.com/v3/__https://github.com/libguestfs/libguestfs
> > /i 
> > ssues/124__;!!Obbck6kTJA!blek-uFsj3xPSaSiNQrS-1lk59I6-udl4zqOJCxZ6LL
> > eu pvAFl6tPfod_GU2BLm_19gJUs3OXp6_IUEM$
> > /***************************************/
> > I can get guestfs_last_error using function_callback and write to log file.
> > But "event Handling" is not working Also, std::cout and std::cerr still 
> > printing on terminal.
> > Is there any workaround for Event Handling?
> >  How to completely disable/enable standard output?
> > /***********************************/
> >
> > In short, Any Debugging sample program, 
> > https://urldefense.com/v3/__https://github.com/libguestfs/libguestfs
> > /i 
> > ssues/124__;!!Obbck6kTJA!blek-uFsj3xPSaSiNQrS-1lk59I6-udl4zqOJCxZ6LL
> > eu pvAFl6tPfod_GU2BLm_19gJUs3OXp6_IUEM$
>
> In the two programs in that issue, the first program sets an event callback 
> and the second program sets an error handler.  To capture all messages you 
> must set both together.
>
> If you can produce a single, short reproducer which uses both types of 
> handlers and still prints to stderr, then I can look at that.
>
> Rich.
>
> --
> Richard Jones, Virtualization Group, Red Hat 
> https://urldefense.com/v3/__http://people.redhat.com/*rjones__;fg!!Obb
> ck6kTJA!blek-uFsj3xPSaSiNQrS-1lk59I6-udl4zqOJCxZ6LLeupvAFl6tPfod_GU2BL
> m_19gJUs3OXuHRnZTv$ Read my programming and virtualization blog: 
> https://urldefense.com/v3/__http://rwmj.wordpress.com__;!!Obbck6kTJA!b
> lek-uFsj3xPSaSiNQrS-1lk59I6-udl4zqOJCxZ6LLeupvAFl6tPfod_GU2BLm_19gJUs3
> OXrVS1VaN$ Fedora Windows cross-compiler. Compile Windows programs, 
> test, and build Windows installers. Over 100 libraries supported.
> https://urldefense.com/v3/__http://fedoraproject.org/wiki/MinGW__;!!Ob
> bck6kTJA!blek-uFsj3xPSaSiNQrS-1lk59I6-udl4zqOJCxZ6LLeupvAFl6tPfod_GU2B
> Lm_19gJUs3OXjCvHvVp$

--
Richard Jones, Virtualization Group, Red Hat 
https://urldefense.com/v3/__http://people.redhat.com/*rjones__;fg!!Obbck6kTJA!ZE9Jts1w7JGiKHKAcLv1I72RncLG2NUVxKSn4yXEUiITBywqaqIgR4po1KK5rdHojo9l36xX1V-CKYfN$
Read my programming and virtualization blog: 
https://urldefense.com/v3/__http://rwmj.wordpress.com__;!!Obbck6kTJA!ZE9Jts1w7JGiKHKAcLv1I72RncLG2NUVxKSn4yXEUiITBywqaqIgR4po1KK5rdHojo9l36xX1WGJ1lVR$
Fedora Windows cross-compiler. Compile Windows programs, test, and build 
Windows installers. Over 100 libraries supported.
https://urldefense.com/v3/__http://fedoraproject.org/wiki/MinGW__;!!Obbck6kTJA!ZE9Jts1w7JGiKHKAcLv1I72RncLG2NUVxKSn4yXEUiITBywqaqIgR4po1KK5rdHojo9l36xX1XNZvfww$
#include <iostream>
#include <guestfs.h>
#include <unistd.h>
#include <vector>
#include <thread>
#include <errno.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <cstring>
#include <chrono>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <guestfs.h>
#include <fstream>

#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" <<endl;
    } else {
        std::cout << "guestfs_mount_local() successful." << std::endl;
        std::cout << "Filesystem mounted successfully. Mount point: " << 
baseMountDir << "\n" << std::endl;
        std::cout << "Access the files now for the device." << "\n" << 
std::endl;
    }

    // Run the libguestfs FUSE main loop to synchronize changes to the host 
file system
    // Local unmount needs to be triggered to stop this FUSE main loop
    if (guestfs_mount_local_run(g) == -1) {
        //show_error(g, "Failed to synchronize changes to the host file 
system");
        cout << "ERROR2: should go to guestfs_logger" <<endl;
    } else {
        std::cout << "Synchronized changes to the host file system." << 
std::endl;
    }
}


int main(int argc, char* argv[]) {
    if (argc < 2) {
        std::cerr << "Usage: " << argv[0] << " /path/to/your/vmdk/file1.vmdk 
/path/to/your/vmdk/file2.vmdk ..." << std::endl;
        return 1;
    }
    log_file.open("/tmp/guestfs_error.txt", std::ios::out | std::ios::app); // 
Open the file for appending
    if (!log_file) {
        cout << "Log file not opened!";
        return 1; // Return an error code
    }


        
        char env_var[] = "LIBGUESTFS_BACKEND=direct";
    if (putenv(env_var) != 0) {
        perror("putenv");
        return 1;
    }

    const char* baseMountDir = "/mnt/dp_dir";

    // Create the base mount directory if it doesn't exist
        // We can define the base mount directory as per our requirement
        // For now keeping /mnt/dp_dir as base mount directory
    if (mkdir(baseMountDir, 0755) == -1 && errno != EEXIST) {
        std::cerr << "Failed to create directory: " << baseMountDir << 
std::endl;
        return 1;
    }
        
        // We will be calculating the overall time taken to execute this program
        auto start = std::chrono::high_resolution_clock::now();
        
    // Creating primary guestfs handler to get the list of filesystems
    guestfs_h *g = guestfs_create();
    if (g == NULL) {
        std::cerr << "Failed to create libguestfs handle" << std::endl;
        return 1;
    }else if(g != NULL){
        guestfs_set_error_handler (g, NULL, NULL);
    }
    else if(guestfs_set_event_callback (g, message_callback, event_bitmask, 0, 
NULL) == -1) {
            std::cout << "guestfs_set_event_callback failed" << std::endl;
    }
    else{
    std::cout << "Successful guestfs_create" << std::endl;
    }
    guestfs_set_trace (g, 1);
    guestfs_set_verbose (g, 1);
    // Add all the VMDK files to the primary libguestfs handle
    for (int i = 1; i < argc; ++i) {
        const char* vmdkFile = argv[i];
        if (guestfs_add_drive(g, vmdkFile) == -1) {
            //show_error(g, "Failed to add VMDK file to libguestfs");
            cout << "ERROR3: should go to guestfs_logger" <<endl;
            guestfs_close(g);
            return 1;
        }
        else {
            std::cout << "Added VMDK file: " << vmdkFile << std::endl;
        }
    }
     printf ("There is no output from this program.  "
           "Take a look in your system log file,\n"
           "eg. /tmp/guestfs_error.txt.\n");
        
    // Launch the primary libguestfs instance
    cout << "Lounching guestfs ... .... ...";
    if (guestfs_launch(g) == -1) {
        //show_error(g, "Failed to launch libguestfs");
        cout << "ERROR4: should go to guestfs_logger" <<endl;
        guestfs_close(g);
        return 1;
    }
    else {
        std::cout << "Successful guestfs_launch" << std::endl;
    }

    std::cout << "\n" << std::endl;

    // Get the list of all filesystems from the primary guestfs handle
    char **filesystems = guestfs_list_filesystems(g);
    if (filesystems == NULL) {
        //show_error(g, "Failed to get filesystems");
        cout << "ERROR5: should go to guestfs_logger" <<endl;
        guestfs_close(g);
        return 1;
    }
        display(filesystems, FILESYSTEM); 
        
        // Store the mount points in a vector.
        // This will be used to unmount locally and delete the local mountpoint 
dir later
    std::vector<const char*> 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" <<endl;
                        return 1;
                }
                else {
                        std::cout << "guestfs_mount_ro() Successful" << 
std::endl;
                }
                
                std::cout << "Mounting device :: " << devicePath << " at 
mountPoint :: " << baseMountDir << mountPoint << std::endl;

        mountPoints.push_back(strdup(mountPoint)); // Store the mount point 
path in the vector
                mountCount++;
    }
        
        // Start a new thread for the mount and synchronization process
        std::thread syncThread(mountLocalAndSyncThread, g, baseMountDir);
        
        // This code block will be used to keep the FUSE filesystem accessible 
on host system/mount proxy.
        // TODO:: External singal or user input to trigger unmount process 
still need to be decided.
        int x = 0;
        while(x == 0)
        {
                std::cout << "Type any number other that 0 to exit :: " << 
std::endl;
                std::cin >> 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" <<endl;
                } else {
                        std::cout << "Unmounting now." << std::endl;
                        std::cout << "Filesystem " << mountPoint << " unmounted 
successfully.\n" << std::endl;
                }
                free((void*)mountPoint);
    }
        
        auto end = std::chrono::high_resolution_clock::now();
        // Now we will calculate and print the overall time taken by guestfs to 
do all
        std::chrono::duration<double> 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);
    }
    
 }
_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to