Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1156275
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2279
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(241)

文章存档

2023年(8)

2022年(2)

2021年(3)

2020年(30)

2019年(11)

2018年(27)

2017年(54)

2016年(83)

2015年(23)

我的朋友

分类: LINUX

2016-09-06 16:50:16

参考http://blog.csdn.net/lieye_leaves/article/details/41492309
sched.h中

struct task_struct

{

…………

/* namespaces */
        struct nsproxy *nsproxy;

………….

}

////////////////
/*
 * A structure to contain pointers to all per-process每个进程
 * namespaces - fs (mount), uts, network, sysvipc, etc.
 *
 * The pid namespace is an exception例外-- it's accessed using
 * task_active_pid_ns.  The pid namespace here is the
 * namespace that children will use.
 *
 * 'count' is the number of tasks holding a reference参考,引用.
 * The count总数,计数 for each namespace, then, will be the number
 * of nsproxies pointing to it, not the number of tasks.
 *
 * The nsproxy is shared by tasks which share all namespaces.
 * As soon as a single namespace is cloned or unshared, the
 * nsproxy is copied.
 */
include/linux/nsproxy.h
struct nsproxy {
    atomic_t count;
    struct uts_namespace *uts_ns;
    struct ipc_namespace *ipc_ns;
    struct mnt_namespace *mnt_ns;
    struct pid_namespace *pid_ns_for_children;
    struct net          *net_ns;
};
////////////////IPC通信相关
include/linux/ipc_namespace.h
struct ipc_ids {
    int in_use;
    unsigned short seq;
    struct rw_semaphore rwsem;
    struct idr ipcs_idr;
    int next_id;
};

struct ipc_namespace {
    atomic_t    count;
    struct ipc_ids    ids[3];

    int        sem_ctls[4];
    int        used_sems;

    unsigned int    msg_ctlmax;
    unsigned int    msg_ctlmnb;
    unsigned int    msg_ctlmni;
    atomic_t    msg_bytes;
    atomic_t    msg_hdrs;

    size_t        shm_ctlmax;
    size_t        shm_ctlall;
    unsigned long    shm_tot;
    int        shm_ctlmni;
    /*
     * Defines whether IPC_RMID is forced for _all_ shm segments regardless
     * of shmctl()
     */
    int        shm_rmid_forced;

    struct notifier_block ipcns_nb;

    /* The kern_mount of the mqueuefs sb.  We take a ref on it */
    struct vfsmount    *mq_mnt;

    /* # queues in this ns, protected by mq_lock */
    unsigned int    mq_queues_count;

    /* next fields are set through sysctl */
    unsigned int    mq_queues_max;   /* initialized to DFLT_QUEUESMAX */
    unsigned int    mq_msg_max;      /* initialized to DFLT_MSGMAX */
    unsigned int    mq_msgsize_max;  /* initialized to DFLT_MSGSIZEMAX */
    unsigned int    mq_msg_default;
    unsigned int    mq_msgsize_default;

    /* user_ns which owns the ipc ns */
    struct user_namespace *user_ns;

    struct ns_common ns;
};
//////////////////////

IPC/sem.c
kernel中include/uapi/linux/sem.h

/* semop system calls takes an array of these. */
struct sembuf {
    unsigned short  sem_num;    /* semaphore index in array */要操作的信号灯的编号
    short        sem_op;        /* semaphore operation */ 0 ---- 等待  +1 V操作 释放资源  -1 P操作
    short        sem_flg;    /* operation flags */ 0,IPC_NOWAIT,SEM_UNDO
    //SEM_UNDO 自动平衡信号量(因进程异常推出后系统给这个进程所加的锁给以释放(或者反向))
};

include/uapi/linux/sem.h
/* arg for semctl system calls. */
union semun {
    int val;            /* value for SETVAL */
    struct semid_ds __user *buf;    /* buffer for IPC_STAT & IPC_SET */
    unsigned short __user *array;    /* array for GETALL & SETALL */
    struct seminfo __user *__buf;    /* buffer for IPC_INFO */
    void __user *__pad;
};
////////////////////////////
SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
        unsigned long, third, void __user *, ptr, long, fifth)
{
    int version, ret;

    version = call >> 16; /* hack for backward compatibility */
    call &= 0xffff;

    switch (call) {
    case SEMOP:
        return sys_semtimedop(first, (struct sembuf __user *)ptr,
                      second, NULL);
    case SEMTIMEDOP:
        return sys_semtimedop(first, (struct sembuf __user *)ptr,
                      second,
                      (const struct timespec __user *)fifth);

    case SEMGET:
        return sys_semget(first, second, third);
    case SEMCTL: {
        unsigned long arg;
        if (!ptr)
            return -EINVAL;
        if (get_user(arg, (unsigned long __user *) ptr))
            return -EFAULT;
        return sys_semctl(first, second, third, arg);
    }

    case MSGSND:
        return sys_msgsnd(first, (struct msgbuf __user *) ptr,
                  second, third);
    case MSGRCV:
        switch (version) {
        case 0: {
            struct ipc_kludge tmp;
            if (!ptr)
                return -EINVAL;

            if (copy_from_user(&tmp,
                       (struct ipc_kludge __user *) ptr,
                       sizeof(tmp)))
                return -EFAULT;
            return sys_msgrcv(first, tmp.msgp, second,
                       tmp.msgtyp, third);
        }
        default:
            return sys_msgrcv(first,
                       (struct msgbuf __user *) ptr,
                       second, fifth, third);
        }
    case MSGGET:
        return sys_msgget((key_t) first, second);
    case MSGCTL:
        return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);

    case SHMAT:
        switch (version) {
        default: {
            unsigned long raddr;
            ret = do_shmat(first, (char __user *)ptr,
                       second, &raddr, SHMLBA);
            if (ret)
                return ret;
            return put_user(raddr, (unsigned long __user *) third);
        }
        case 1:
            /*
             * This was the entry point for kernel-originating calls
             * from iBCS2 in 2.2 days.
             */
            return -EINVAL;
        }
    case SHMDT:
        return sys_shmdt((char __user *)ptr);
    case SHMGET:
        return sys_shmget(first, second, third);
    case SHMCTL:
        return sys_shmctl(first, second,
                   (struct shmid_ds __user *) ptr);
    default:
        return -ENOSYS;
    }
}
////////////////////
semget系统调用函数定义处 ipc/sem.c
//????sys_shmget与此处何联系和不同?
SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg)
{
    struct ipc_namespace *ns;
    static const struct ipc_ops sem_ops = {
        .getnew = newary,
        .associate = sem_security,
        .more_checks = sem_more_checks,
    };
    struct ipc_params sem_params;

    ns = current->nsproxy->ipc_ns;

    if (nsems < 0 || nsems > ns->sc_semmsl)
        return -EINVAL;

    sem_params.key = key;
    sem_params.flg = semflg;
    sem_params.u.nsems = nsems;

    return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
}
//////////////////////////////
ipc/compat.c 中
COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg)
{
    return do_compat_semctl(semid, semnum, cmd, arg);
}
//////////////////
ipc/sem.c  semop函数的系统调用
SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops,
        unsigned, nsops)
{
    return sys_semtimedop(semid, tsops, nsops, NULL);
}

semget系统函数include/linux/sem.h
/* Obsolete, used only for backwards compatibility and libc5 compiles */
struct semid_ds {
    struct ipc_perm    sem_perm;        /* permissions .. see ipc.h */
    __kernel_time_t    sem_otime;        /* last semop time */
    __kernel_time_t    sem_ctime;        /* last change time */
    struct sem    *sem_base;        /* ptr to first semaphore in array */
    struct sem_queue *sem_pending;        /* pending operations to be processed */
    struct sem_queue **sem_pending_last;    /* last pending operation */
    struct sem_undo    *undo;            /* undo requests on this array */
    unsigned short    sem_nsems;        /* no. of semaphores in array */
};



阅读(1292) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~