bytecodealliance / wasm-micro-runtime

WebAssembly Micro Runtime (WAMR)
Apache License 2.0
4.99k stars 628 forks source link

O_DSYNC setting bug. #3566

Closed Userzxcvbvnm closed 4 months ago

Userzxcvbvnm commented 5 months ago

Subject of the issue

wamr print "Setting flags succeed!" but does not print "Access mode: Data Synchronization Write" And the same with setting O_SYNC I'm not sure whether this is a bug.

Test case

The test case is:


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

int get_fd(const char *filename, int flags) {
    int fd = open(filename, flags);

    if (fd == -1) {
        printf("Get file descriptor of file %s failed!\n", filename);
        return -1;
    } else {
        printf("Get file descriptor of file %s succeed!\n", filename);
        return fd;
    }
}

void closebyfd(int fd) {
    if (close(fd) == -1) {
        printf("Close the file %d by descriptor failed!\n", fd);
    }
}

void fd_fdstat_set_flags_00068_ZJtyU(int fd) {
    printf("Enter function fd_fdstat_set_flags_00068_ZJtyU\n");

    int flags = fcntl(fd, F_GETFL);
    flags = flags | O_DSYNC;

    if (fcntl(fd, F_SETFL, flags) == -1) {
        printf("Setting flags failed!\n");
    } else {
        printf("Setting flags succeed!\n");
    }
}

void print_flags(int fd){
    int flags1 = fcntl(fd, F_GETFL);
    int access_mode1 = flags1 & O_ACCMODE;
    if (access_mode1 == O_RDONLY) {
        printf("Access mode: Read Only\n");
    }
    if (access_mode1 == O_WRONLY) {
        printf("Access mode: Write Only\n");
    }
    if (access_mode1 == O_RDWR) {
        printf("Access mode: Read/Write\n");
    }
    if (flags1 & O_TRUNC) {
        printf("Access mode: O_TRUNC\n");
    }
    if (flags1 & O_APPEND) {
        printf("Access mode: O_APPEND\n");
    }
    if (flags1 & O_CREAT) {
        printf("Access mode: O_CREAT\n");
    }
    if (flags1 & O_EXCL) {
        printf("Access mode: O_EXCL\n");
    }
    if (flags1 & O_NONBLOCK) {
        printf("Access mode: Non-blocking\n");
    }
    if (flags1 & O_SYNC) {
        printf("Access mode: Synchronous Write\n");
    }
    if (flags1 & O_DSYNC) {
        printf("Access mode: Data Synchronization Write\n");
    }
}

int main() {

    int fd = get_fd("subdir_1/subdir_4/subfile_3", O_WRONLY);

    if (fd == -1) {
        return 1;
    }

    print_flags(fd);
    fd_fdstat_set_flags_00068_ZJtyU(fd);
    printf("After setting flags\n");
    print_flags(fd);

    closebyfd(fd);

    return 0;
}

Your environment

Ubuntu 20.04 x86_64 WAMR 1.3.2 and WAMR 1.2.3

Steps to reproduce

(1)compile to wasm:./wasi-sdk-21.0/bin/clang --target=wasm32-unkown-wasi --sysroot=./wasi-sdk-21.0/share/wasi-sysroot test.c -o test.wasm

(2)Running wasm: (Before run the Wasm file, file subdir_1/subdir_4/subfile_3 exists.) iwasm --dir=. test.wasm

Expected behavior

prints:

Get file descriptor of file subdir_1/subdir_4/subfile_3 succeed!
Access mode: Write Only
Enter function fd_fdstat_set_flags_00068_ZJtyU
Setting flags succeed!
After setting flags
Access mode: Write Only
Access mode: Data Synchronization Write

Actual behavior

WAMR prints:

Get file descriptor of file subdir_1/subdir_4/subfile_3 succeed!
Access mode: Write Only
Enter function fd_fdstat_set_flags_00068_ZJtyU
Setting flags succeed!
After setting flags
Access mode: Write Only

wamr print "Setting flags succeed!" but does not print "Access mode: Data Synchronization Write"

TianlongLiang commented 5 months ago

Similar to https://github.com/bytecodealliance/wasm-micro-runtime/issues/3565, O_DSYNC is not part of the file status flags that can be modified using fcntl. You can only set its value when first set it with open

TianlongLiang commented 5 months ago

Refer to the manual of syscall open and fcntl:

In open

       In addition, zero or more file creation flags and file status
       flags can be bitwise ORed in flags.  The file creation flags are
       O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW,
       O_TMPFILE, and O_TRUNC.  The file status flags are all of the
       remaining flags listed below.  The distinction between these two
       groups of flags is that the file creation flags affect the
       semantics of the open operation itself, while the file status
       flags affect the semantics of subsequent I/O operations.  **The
       file status flags can be retrieved and (in some cases) modified**;
       see [fcntl(2)](https://man7.org/linux/man-pages/man2/fcntl.2.html) for details.

In fcntl

       F_SETFL (int)
              Set the file status flags to the value specified by arg.
              File access mode (O_RDONLY, O_WRONLY, O_RDWR) and file
              creation flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC)
              in arg are ignored.  On Linux, this operation can change
              only the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and
              O_NONBLOCK flags.  It is not possible to change the
              O_DSYNC and O_SYNC flags; see BUGS, below.
Userzxcvbvnm commented 4 months ago

Thanks for your reply!