Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Truncate file ? #4258

Closed
orangeC23 opened this issue Oct 17, 2023 · 5 comments
Closed

Truncate file ? #4258

orangeC23 opened this issue Oct 17, 2023 · 5 comments
Assignees
Labels
bug Something isn't working 📦 lib-wasi About wasmer-wasi 🕵️ needs investigation The issue/PR needs further investigation priority-low Low priority issue
Milestone

Comments

@orangeC23
Copy link

orangeC23 commented Oct 17, 2023

Reproduction steps

(1)The cfile is :

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>


int main() {
    const char* file_name = "Data/hello.txt";
    int open_style= O_CREAT | O_RDWR;
    int fd = get_fd(file_name, open_style);
    fd_allocateUPnPm2YECn(fd, file_name);
    snapshot(fd);
    return 0;
}

int fd_allocateUPnPm2YECn (int fd, const char* file_name){
    off_t start_value = 29;
    off_t len_value = 0;
    return fd_allocate(fd, file_name, start_value, len_value);
}

int get_fd(const char* file_name, int open_style){
    int fd = open(file_name, open_style);
    if (fd == -1) {
        perror("Failed to open the file");
        return 1;
    }

    return fd;
}

int fd_allocate (int fd, const char* filename, off_t start_value, off_t len_value){
    if (posix_fallocate(fd, start_value, len_value) != 0) {
        perror("Error allocating file space");
        close(fd);
        return 1;
    }

    printf("File '%s' created and allocated with %lld bytes of space.\n", filename, (long long)len_value);
    return fd;
}

int snapshot(int myfd){   
    printf("Enter snapshot\n");
    
    struct stat file_info;
    if (fstat(myfd, &file_info) == -1) {
        perror("Error getting file attributes");
        close(myfd);
        return 1;
    }

    printf("File Size: %lld bytes \n", (long long)file_info.st_size);
    printf("File Permissions: %o \n", file_info.st_mode & ~S_IFMT); 
    printf("File Owner UID: %d \n", file_info.st_uid); 
    printf("File Group GID: %d \n", file_info.st_gid); 
    

    // Get the current offset
    off_t cur_offset = lseek(myfd, 0, SEEK_CUR);
    if (cur_offset == -1) {
        perror("Error getting current offset");
    }
    printf("Current offset: %lld \n", (long long)cur_offset);

    if (close(myfd) == -1) {
        perror("Error closing file");
        return 1;
    }

    printf("Leave snapshot\n");
}

(2)compile the c file into wasm: ./wasi-sdk-16.0/bin/clang --target=wasm32-unkown-wasi --sysroot=./wasi-sdk-16.0/share/wasi-sysroot test1.c -o test1.wasm

(3)exeute open.wasm
wasmer run test1.wasm --dir=./Data

The permission of Data/hello.txt is 0600 or 0700, user1 create the Data/hello.txt file and user1 execute the Wasm file.

(4)wasmer prints:

File 'Data/hello.txt' created and allocated with 0 bytes of space.
Enter snapshot
File Size: 29 bytes 
File Permissions: 0 
File Owner UID: 0 
File Group GID: 0 
Current offset: 0 
Leave snapshot

However, wasmedge and wazero print:

File 'Data/hello.txt' created and allocated with 0 bytes of space.
Enter snapshot
File Size: 30 bytes 
File Permissions: 0 
File Owner UID: 0 
File Group GID: 0 
Current offset: 0 
Leave snapshot

Actual behavior

File 'Data/hello.txt' created and allocated with 0 bytes of space.
Enter snapshot
File Size: 29 bytes 
File Permissions: 0 
File Owner UID: 0 
File Group GID: 0 
Current offset: 0 
Leave snapshot

The file size before executing is 30. And in the docs of func posix_fallocate claimed that if offet value adding start value is not larger than the file size, the file size should keep the initial value.
https://pubs.opengroup.org/onlinepubs/9699919799/nframe.html

Expected behavior

File 'Data/hello.txt' created and allocated with 0 bytes of space.
Enter snapshot
File Size: 30 bytes 
File Permissions: 0 
File Owner UID: 0 
File Group GID: 0 
Current offset: 0 
Leave snapshot

wasmer version

4.2.2

Operating system information

Ubuntu 20.04

Hardware Architecture

x86_64

@Michael-F-Bryan
Copy link
Contributor

This might be a bug in our in-memory virtual_fs::FileSystem implementation, possibly in virtual_fs::mem_fs::FileHandle::set_len() or the code that translates syscalls into FileSystem calls.

That said, we weren't able to get your code working on either MacOS or Linux to see what the behaviour should be like on a POSIX-compliant machine. @orangeC23 are you able to run it natively on your Ubuntu (i.e. compiling to x86, not wasm) and let us know what the output looks like?

@Michael-F-Bryan Michael-F-Bryan added bug Something isn't working 🕵️ needs investigation The issue/PR needs further investigation 📦 lib-wasi About wasmer-wasi priority-medium Medium priority issue labels Oct 17, 2023
@Michael-F-Bryan Michael-F-Bryan added this to the v4.4 milestone Oct 17, 2023
@orangeC23
Copy link
Author

Thanks for your answer. However, although other runtimes could print:

File 'Data/hello.txt' created and allocated with 0 bytes of space.
Enter snapshot
File Size: 30 bytes 
File Permissions: 0 
File Owner UID: 0 
File Group GID: 0 
Current offset: 0 
Leave snapshot

, Ubuntu natively prints:

Error allocating file space: Success
Enter snapshot
Error getting file attributes: Bad file descriptor

@Arshia001
Copy link
Member

Arshia001 commented Oct 17, 2023

@orangeC23 posix_fallocate does not set errno which is why you're getting Error allocating file space: Success. If you check the return value, it's actually erroring out with EINVAL since it doesn't let you specify a length of zero. If you specify a length of 1, it results in a 30-byte-long file. I interpret this to mean that the correct file length would be 29 bytes if it was possible to use a length of zero and wasmer's implementation is (kind of) correct mathematically.

However, wasmer should also error out when the length is zero, so I'll keep this issue open to track that.

@Arshia001 Arshia001 added priority-low Low priority issue and removed priority-medium Medium priority issue labels Oct 17, 2023
@Arshia001
Copy link
Member

Just noticed #4257. Closing this as it's a duplicate.

@orangeC23
Copy link
Author

orangeC23 commented Oct 17, 2023

Thanks a lot for your answer!
Sorry, maybe I didn't understand exactly what you mean.
If the c file is :

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>


int main() {
    const char* file_name = "Data/hello.txt";
    int open_style= O_CREAT | O_RDWR;
    int fd = get_fd(file_name, open_style);
    fd_allocateBYxRK4up9T(fd, file_name);
    snapshot(fd);
    return 0;
}

int fd_allocateBYxRK4up9T (int fd, const char* file_name){
    off_t start_value = 13;
    off_t len_value = 9;
    return fd_allocate(fd, file_name, start_value, len_value);
}

int get_fd(const char* file_name, int open_style){
    int fd = open(file_name, open_style);
    if (fd == -1) {
        perror("Failed to open the file");
        return 1;
    }

    return fd;
}

int fd_allocate (int fd, const char* filename, off_t start_value, off_t len_value){
    printf("Enter fd_allocate\n");
    
    if (posix_fallocate(fd, start_value, len_value) != 0) {
        perror("Error allocating file space");
        close(fd);
        return 1;
    }

    printf("File '%s' created and allocated with %lld bytes of space.\n", filename, (long long)len_value);
    printf("Leave fd_allocate\n");
    return fd;
}

int snapshot(int myfd){   
    printf("Enter snapshot\n");
    
    struct stat file_info;
    if (fstat(myfd, &file_info) == -1) {
        perror("Error getting file attributes");
        close(myfd);
        return 1;
    }

    printf("File Size: %lld bytes \n", (long long)file_info.st_size);
    printf("File Permissions: %o \n", file_info.st_mode & ~S_IFMT); 
    printf("File Owner UID: %d \n", file_info.st_uid);
    printf("File Group GID: %d \n", file_info.st_gid); 
    

    off_t cur_offset = lseek(myfd, 0, SEEK_CUR);
    if (cur_offset == -1) {
        perror("Error getting current offset");
    }
    printf("Current offset: %lld \n", (long long)cur_offset);

    if (close(myfd) == -1) {
        perror("Error closing file");
        return 1;
    }

    printf("Leave snapshot\n");
}

The file size before executing is 30.
The start value is 13, and the len is 9. And 13+9 is smaller than 30.

When executing the Wasm file, wasmer prints:

Enter fd_allocate
File 'Data/hello.txt' created and allocated with 9 bytes of space.
Leave fd_allocate
Enter snapshot
File Size: 22 bytes 
File Permissions: 0 
File Owner UID: 0 
File Group GID: 0 
Current offset: 0 
Leave snapshot

And the file content is truncated.

Other runtimes print:

Enter fd_allocate
File 'Data/hello.txt' created and allocated with 9 bytes of space.
Leave fd_allocate
Enter snapshot
File Size: 30 bytes 
File Permissions: 0 
File Owner UID: 0 
File Group GID: 0 
Current offset: 0 
Leave snapshot

Could this be an error? Could this be an error of wasmer or an error of other runtimes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working 📦 lib-wasi About wasmer-wasi 🕵️ needs investigation The issue/PR needs further investigation priority-low Low priority issue
Projects
None yet
Development

No branches or pull requests

3 participants