簡體   English   中英

android ion,ION_IOC_IMPORT的ioctl返回<0,errno = 9

[英]android ion, ioctl of ION_IOC_IMPORT return <0, errno = 9

我寫了一個android ion使用示例:

父進程創建管道,然后打開“ / dev / ion”設備,ION_IOC_ALLOC的ioctl,ION_IOC_MAP和mmap的ioctl,最后我通過管道將ION_IOC_MAP返回的fd和長度傳遞給子進程。

子進程從管道讀取fd和length,並且讀取沒問題,但是當我執行ION_IOC_IMPORT時,此返回-1,而errno為9,perror是“錯誤的文件描述符”。

這兩個過程是root用戶,而selinux是允許的。

父進程的關鍵代碼:

ion_fd = open("/dev/ion", O_RDONLY);
if (ion_fd < 0) {
    ALOGE("Failed to open ion device\n");
    return -EIO;
}

alloc_data.len = 0x1000;
alloc_data.align = 0x1000;
alloc_data.heap_id_mask = ION_HEAP(ION_SYSTEM_HEAP_ID);
alloc_data.flags = ION_SECURE;
rc = ioctl(ion_fd, ION_IOC_ALLOC, &alloc_data);
if (rc) {
    ALOGE( "Failed to allocate uspace ion buffer\n");
    goto uimp_alloc_err;
}
fd_data.handle = alloc_data.handle;
rc = ioctl(ion_fd, ION_IOC_MAP, &fd_data);
if (rc < 0) {
    ALOGE("unable to ion map buffer\n");
    goto uimp_map_err;
}
map_fd = fd_data.fd;
addr = mmap(NULL, alloc_data.len,
                PROT_READ | PROT_WRITE,
                MAP_SHARED , map_fd, 0);
if (!addr) {
    ALOGE("mmap failed\n");
    rc = -EIO;
    goto uimp_mmap_err;
}
write_pattern((unsigned long)addr, alloc_data.len);
fd_data.handle = alloc_data.handle;
rc = ioctl(ion_fd, ION_IOC_SHARE, &fd_data);
if (rc < 0) {
    ALOGE( "unable to share ion buffer\n");
    goto uimp_share_err;
}

itoa(fd_data.fd, ubuf, sizeof(int) * 8);
if (0 > sock_write(wr_fd, ubuf, sizeof(int) * 8))
    goto uimp_sock_err;
itoa(alloc_data.len, ubuf, sizeof(int) * 8);
if (0 > sock_write(wr_fd, ubuf, sizeof(int) * 8))
    goto uimp_sock_err;

do {
    tpid = wait(&child_status);
} while (tpid != child_pid);

子進程的關鍵代碼:

if (0 > sock_read(fd, cbuf, sizeof(int) * 8))
    return -EIO;
fd_data.fd = atoi(cbuf);
/* receive buf length */
if (0 > sock_read(fd, cbuf, sizeof(int) * 8))
    return -EIO;
size = atoi(cbuf);

ion_fd = open("/dev/ion", O_RDONLY);
if (ion_fd < 0) {
    rc = -EINVAL;
    goto child_args_err;
}
rc = ioctl(ion_fd, ION_IOC_IMPORT, &fd_data); // it failed here
if (rc) {
    ALOGE( "ION_IOC_IMPORT failed %d errno %d\n", rc, errno);
    perror("ioctl");
    rc = -EIO;
    goto child_imp_err;
}
addr = mmap(NULL, size, PROT_READ | PROT_WRITE,
                MAP_SHARED, fd_data.fd, 0);
if (!addr) {
    perror("mmap");
    rc = -EIO;
    goto child_mmap_err;
}

文件描述符(fds)是每個進程的文件,因此,僅通過傳遞一個描述符(這是一個簡單的int)就不能在進程之間共享文件-這就是為什么會出現錯誤。 在Android中,您可以采取兩種方法來解決此問題:1.使用Android的Binder,方法是使兩個進程都實現一個繼承IInterface和所有jazz的類(請參見例如: https : //github.com/gburca/BinderDemo ),但是,我相信,一次共享一個fd會帶來很多麻煩,所以... 2.我更喜歡使用老式的Unix,如果通過套接字傳遞fd,它可以復制fd。 。 只需在Google上搜索一個神奇的詞:SCM_RIGHTS,您就可以找到大量的示例。

代替rc = ioctl(ion_fd, ION_IOC_MAP, &fd_data);,使用rc = ioctl(ion_fd, **ION_IOC_SHARE**, &fd_data); 它將解決此問題。

參考: https : //groleo.wordpress.com/2012/07/24/ion-buffer-sharing-mechanism/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM