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

标签 android c++ c android-ion

我写了一个android ion使用的例子:

父进程创建一个pipe,然后打开“/dev/ion”设备,ION_IOC_ALLOC的ioctl,ION_IOC_MAP的ioctl和mmap,最后我把ION_IOC_MAP返回的fd和length通过pipe传递给子进程。

子进程从管道读取 fd 和 length,读取正常,但是当我执行 ION_IOC_IMPORT 时,返回 -1,errno 为 9,perror 为“Bad file descriptor”。

这两个进程都是root用户,selinux是permissive。

父进程关键代码:

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 和所有爵士乐的类(例如参见:https://github.com/gburca/BinderDemo),但是,我认为这对于一次性共享一个 fd 来说太过分了,所以... 2. 我更喜欢使用老式的 Unix,它提供了复制通过套接字传递的 fd 的方法。只需在谷歌上搜索神奇的词:SCM_RIGHTS,您应该能够找到大量示例。

关于android ion, ION_IOC_IMPORT 的 ioctl 返回 <0, errno = 9,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38433631/

相关文章:

java - 刷新媒体扫描仪扫描的文本文件

c++ - 用于计算文件中字符串数量的预处理器

c++ - 是否可以设置toolTip出现在QGraphicsItem上的时间?

c - 使用 MKL 的稀疏矩阵乘法

c - 加密实现 - 令人困惑的结果

java - 如何从选项菜单启动 Activity

Android BroadcastReceiver 收不到任何广播事件

android - 设计方法 : Android Restful with JSON

c++ - 模板类的虚成员函数什么时候实例化?

通过 C 更改文本文件名