97干视频,99国产精品懂色,亚洲精品99久久久久中文字幕,伊人五月丁香综合AⅤ,国产精品成人免费999

  您的位置:華清遠(yuǎn)見(jiàn)教育科技集團(tuán) >> 新聞動(dòng)態(tài) >> Android資料 >> Android RPC管道文件系統(tǒng)  
 
Android RPC管道文件系統(tǒng)
分享到:

在Linux中,由于沒(méi)有對(duì)應(yīng)的物理設(shè)備,RPC管道文件系統(tǒng)是作為一種虛擬的文件系統(tǒng)存在的,其在系統(tǒng)中的注冊(cè)和注銷(xiāo)等操作都必須遵循Linux文件系統(tǒng)規(guī)范。關(guān)于RPC管道的實(shí)現(xiàn)主要分布在rpc_pipe.c文件中。下面是RPC管道文件系統(tǒng)在sunrpc_syms.c文件中的初始化過(guò)程:

代碼1-1 RPC管道文件系統(tǒng)的初始化過(guò)程

static int __init init_sunrpc(void) //__init表示該函數(shù)只在初始化過(guò)程中調(diào)用
    {
        int err=register_rpc_pipefs(); //注冊(cè)RPC管道文件系統(tǒng)"rpc_pipefs"
        if (err)
        goto out;
        err=rpc_init_mempool(); //初始化內(nèi)存池
        if (err) {
        unregister_rpc_pipefs(); //注銷(xiāo)RPC管道文件系統(tǒng)"rpc_pipefs"
        goto out;
        }
        #ifdef RPC_DEBUG
        rpc_register_sysctl(); //注冊(cè)SYSCTL,方便用戶讀取或調(diào)整系統(tǒng)設(shè)置
    #endif
    #ifdef CONFIG_PROC_FS
        rpc_proc_init(); //初始化PROC,方便用戶獲取運(yùn)行時(shí)信息
    #endif
        cache_register(&ip_map_cache); //注冊(cè)緩沖
        cache_register(&unix_gid_cache);
        svc_init_xprt_sock();
    init_socket_xprt(); //初始化套接字
        rpcauth_init_module(); //初始化RPC鑒權(quán)模塊
    out:
        return err;
    }

和其他文件系統(tǒng)一樣,一個(gè)RPC管道是作為RPC管道文件系統(tǒng)下的一個(gè)文件存在的,下面是RPC管道的接口定義:

static const struct file_operations rpc_pipe_fops={
    .owner=THIS_MODULE,
    .llseek=no_llseek,
    .read=rpc_pipe_read, //讀取管道數(shù)據(jù)
    .write=rpc_pipe_write, //寫(xiě)入管道數(shù)據(jù)
    .poll=rpc_pipe_poll, //輪詢管道
    .ioctl=rpc_pipe_ioctl, //管道的ioctl
    .open=rpc pipe_open, //打開(kāi)管道
    .release=rpc_pipe_release, //釋放管道
    };

一個(gè)RPC管道就是RPC管道文件系統(tǒng)的一個(gè)節(jié)點(diǎn),下面是RPC節(jié)點(diǎn)的定義:

struct rpc_inode {
    struct inode vfs_inode; //繼承VFS節(jié)點(diǎn)
    void *private;
    struct list_head pipe;
    struct list_head in_upcall; //通知上層節(jié)點(diǎn)
    struct list_head in_downcall; //通知下層節(jié)點(diǎn)
    int pipelen;
    int nreaders; //讀數(shù)據(jù)線程數(shù)
    int nwriters; //寫(xiě)數(shù)據(jù)線程數(shù)
    int nkern_readwriters;
    wait_queue_head_t waitq; //等待隊(duì)列
    #define RPC_PIPE_WAIT_FOR_OPEN 1
    int flags;
    struct rpc_pipe_ops *ops; //管道選項(xiàng)
    struct delayed_work queue_timeout;
    };

struct rpc_pipe_ops {
    ssize_t (*upcall)(struct file *, struct rpc_pipe_msg *, char __user *, size_t);
    ssize_t (*downcall)(struct file *, const char __user *, size_t);
    void (*release_pipe)(struct inode *); //釋放管道
    int (*open_pipe)(struct inode *); //打開(kāi)管道
    void (*destroy_msg)(struct rpc_pipe_msg *); //銷(xiāo)毀管道消息
    };

為了利用RPC在Linux內(nèi)核和用戶空間之間進(jìn)行通信,需要?jiǎng)?chuàng)建一個(gè)RPC管道,下面是創(chuàng)建一個(gè)RPC管道的實(shí)現(xiàn)過(guò)程:

代碼1-2 創(chuàng)建RPC管道的過(guò)程

struct dentry * rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pipe_ops *ops, int flags)
    {
    struct dentry *dentry;
    struct inode *dir, *inode;
    struct rpc_inode *rpci;
    dentry=rpc_lookup_create(parent, name, strlen(name), 0); //創(chuàng)建目錄
    if (IS_ERR(dentry))
        return dentry;
    dir=parent->d_inode;
    if (dentry->d_inode) {
        rpci=RPC_I(dentry->d_inode);
        if (rpci->private !=private ||
            rpci->ops !=ops ||
            rpci->flags !=flags) {
            dput (dentry);
            dentry=ERR_PTR(-EBUSY);
        }
        rpci->nkern_readwriters++;
        goto out;
    }
    inode=rpc_get_inode(dir->i_sb, S_IFIFO | S_IRUSR | S_IWUSR); //配置權(quán)限
    if (!inode)
        goto err_dput;
    inode->i_ino=iunique(dir->i_sb, 100);
    inode->i_fop=&rpc_pipe_fops;
    d_instantiate(dentry, inode);
    rpci=RPC_I(inode);
    rpci->private=private;
    rpci->flags=flags;
    rpci->ops=ops;
    rpci->nkern_readwriters=1;
    fsnotify_create(dir, dentry);
    dget(dentry);
    out:
        mutex_unlock(&dir->i_mutex);
        return dentry;
    err_dput:
        dput(dentry);
        dentry=ERR_PTR(-ENOMEM);
        printk(KERN_WARNING "%s: %s() failed to create pipe %s/%s (errno=%d)\n",__FILE__, __func__, parent->d_name.name, name,-ENOMEM);
        goto out;
    }

通過(guò)RPC管道文件系統(tǒng),調(diào)用者可以像操作其他文件那樣進(jìn)行RPC管道的操作,常見(jiàn)的操作有讀取數(shù)據(jù)、寫(xiě)入數(shù)據(jù)、查詢管道信息、創(chuàng)建路徑、刪除路徑、創(chuàng)建RPC管道等。

需要說(shuō)明的是,當(dāng)管道數(shù)據(jù)可讀時(shí),需要調(diào)用rpc_queue_upcall()函數(shù)通知用戶空間,當(dāng)管道可寫(xiě)入數(shù)據(jù)時(shí),則不需要通知用戶空間。在通知用戶空間RPC管道的狀態(tài)時(shí),需要將消息封裝在rpc_pipe_msg結(jié)構(gòu)體中。下面是rpc_queue_upcall()函數(shù)的實(shí)現(xiàn)過(guò)程:

代碼1-3 RPC通知用戶空間的過(guò)程

int rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
    {
        struct rpc_inode *rpci=RPC_I(inode);
        int res=-EPIPE;
        spin_lock(&inode->i_lock); //自旋鎖
        if (rpci->ops==NULL)
            goto out;
        if (rpci->nreaders) {
            list_add_tail(&msg->list, &rpci->pipe); //添加到消息隊(duì)列
            rpci->pipelen+=msg->len;
            res=0;
        } else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) { //如果RPC管道等待打開(kāi)
        if (list_empty(&rpci->pipe))
            queue_delayed_work(rpciod_workqueue, //添加到rpciod_workqueue
&rpci->queue_timeout,
            RPC_UPCALL_TIMEOUT);
        list_add_tail(&msg->list, &rpci->pipe); //添加到消息隊(duì)列
        rpci->pipelen += msg->len;
        res=0;
        }
        out:
        spin_unlock(&inode->i_lock);
        wake_up(&rpci->waitq); //喚醒等待隊(duì)列
        return res;
    }

在auth_gss.c文件中,有RPC管道的運(yùn)用實(shí)例,感興趣的朋友可以自行研讀。

 更多相關(guān)文章

·Android RPC遠(yuǎn)程調(diào)用
·SMSM狀態(tài)通信處理過(guò)程
·SMD 數(shù)據(jù)通信的實(shí)現(xiàn)
·Android SMD數(shù)據(jù)通信概述
·淺析Android多媒體元數(shù)據(jù)