Ejemplo n.º 1
0
static int generic_restore_queues(struct sock *sk, struct cpt_sock_image *si,
                                  loff_t pos, struct cpt_context *ctx)
{
    loff_t endpos;

    pos = pos + si->cpt_hdrlen;
    endpos = pos + si->cpt_next;
    while (pos < endpos) {
        struct sk_buff *skb;
        __u32 type;

        skb = rst_skb(sk, &pos, NULL, &type, ctx);
        if (IS_ERR(skb)) {
            if (PTR_ERR(skb) == -EINVAL) {
                int err;

                err = rst_sock_attr(&pos, sk, ctx);
                if (err)
                    return err;
            }
            return PTR_ERR(skb);
        }

        if (type == CPT_SKB_RQ) {
            skb_set_owner_r(skb, sk);
            skb_queue_tail(&sk->sk_receive_queue, skb);
        } else {
            wprintk_ctx("strange socket queue type %u\n", type);
            kfree_skb(skb);
        }
    }
    return 0;
}
Ejemplo n.º 2
0
static int restore_queues(struct sock *sk, struct cpt_sock_image *si,
			  loff_t pos, struct cpt_context *ctx)
{
	loff_t endpos;

	endpos = pos + si->cpt_next;
	pos = pos + si->cpt_hdrlen;
	while (pos < endpos) {
		struct sk_buff *skb;
		__u32 type;
		int err;

		err = rst_sock_attr(&pos, sk, ctx);
		if (!err)
			continue;
		if (err < 0)
			return err;

		skb = rst_skb(sk, &pos, NULL, &type, ctx);
		if (IS_ERR(skb))
			return PTR_ERR(skb);

		if (sk->sk_type == SOCK_STREAM) {
			if (type == CPT_SKB_RQ) {
				skb_set_owner_r(skb, sk);
				ub_tcprcvbuf_charge_forced(sk, skb);
				skb_queue_tail(&sk->sk_receive_queue, skb);
			} else if (type == CPT_SKB_OFOQ) {
				struct tcp_sock *tp = tcp_sk(sk);
				skb_set_owner_r(skb, sk);
				ub_tcprcvbuf_charge_forced(sk, skb);
				skb_queue_tail(&tp->out_of_order_queue, skb);
			} else if (type == CPT_SKB_WQ) {
				sk->sk_wmem_queued += skb->truesize;
				sk->sk_forward_alloc -= skb->truesize;
				ub_tcpsndbuf_charge_forced(sk, skb);
				skb_queue_tail(&sk->sk_write_queue, skb);
			} else {
				wprintk_ctx("strange stream queue type %u\n", type);
				kfree_skb(skb);
			}
		} else {
			if (type == CPT_SKB_RQ) {
				skb_set_owner_r(skb, sk);
				skb_queue_tail(&sk->sk_receive_queue, skb);
			} else if (type == CPT_SKB_WQ) {
				struct inet_sock *inet = inet_sk(sk);
				if (inet->cork.fragsize) {
					skb_set_owner_w(skb, sk);
					skb_queue_tail(&sk->sk_write_queue, skb);
				} else {
					eprintk_ctx("cork skb is dropped\n");
					kfree_skb(skb);
				}
			} else {
				wprintk_ctx("strange dgram queue type %u\n", type);
				kfree_skb(skb);
			}
		}
	}
	return 0;
}
Ejemplo n.º 3
0
struct file * rst_open_tty(cpt_object_t *mntobj, char *name,
			   struct cpt_file_image *fi, struct cpt_inode_image *ii,
			   unsigned flags, struct cpt_context *ctx)
{
	int err;
	cpt_object_t *obj;
	struct file *master, *slave;
	struct tty_struct *stty;
	struct cpt_tty_image *pi;
	static char *a = "pqrstuvwxyzabcde";
	static char *b = "0123456789abcdef";
	char pairname[16];
	unsigned master_flags, slave_flags;

	if (fi->cpt_priv == CPT_NULL)
		return ERR_PTR(-EINVAL);

	obj = lookup_cpt_obj_bypos(CPT_OBJ_TTY, fi->cpt_priv, ctx);
	if (obj && obj->o_parent) {
		dprintk_ctx("obtained pty as pair to existing\n");
		master = obj->o_parent;
		stty = file_tty(master);

		if (stty->driver->subtype == PTY_TYPE_MASTER &&
		    (stty->driver->flags&TTY_DRIVER_DEVPTS_MEM)) {
			wprintk_ctx("cloning ptmx\n");
			get_file(master);
			return master;
		}

		master = dentry_open(dget(master->f_dentry),
				     mntget(master->f_vfsmnt), flags,
				     current_cred());
		if (!IS_ERR(master)) {
			stty = file_tty(master);
			if (stty->driver->subtype != PTY_TYPE_MASTER)
				fixup_tty_attrs(ii, master, ctx);
		}
		return master;
	}

	pi = cpt_get_buf(ctx);
	err = rst_get_object(CPT_OBJ_TTY, fi->cpt_priv, pi, ctx);
	if (err) {
		cpt_release_buf(ctx);
		return ERR_PTR(err);
	}

	if (MAJOR(ii->cpt_rdev) == TTY_MAJOR ||
	    ii->cpt_rdev == MKDEV(TTYAUX_MAJOR, 1)) {
		if (mntobj && (mntobj->o_flags & CPT_VFSMOUNT_DELAYFS))
		       return ERR_PTR(-ENOTSUPP);
		master = rst_open_file(mntobj, name, fi,
				flags|O_NONBLOCK|O_NOCTTY, ctx);
		if (IS_ERR(master)) {
			eprintk_ctx("rst_open_tty: %s %Ld %ld\n",
					name, (long long)fi->cpt_priv,
					PTR_ERR(master));
			return master;
		}

		stty = file_tty(master);
		obj = cpt_object_add(CPT_OBJ_TTY, stty, ctx);
		obj->o_parent = master;
		cpt_obj_setpos(obj, fi->cpt_priv, ctx);

		obj = cpt_object_add(CPT_OBJ_FILE, master, ctx);
		cpt_obj_setpos(obj, CPT_NULL, ctx);
		get_file(master);

		/* Do not restore /dev/ttyX state */
		cpt_release_buf(ctx);
		return master;
	}

	master_flags = slave_flags = 0;
	if (pi->cpt_drv_subtype == PTY_TYPE_MASTER)
		master_flags = flags;
	else
		slave_flags = flags;

	/*
	 * Open pair master/slave.
	 */
	if (pi->cpt_drv_flags&TTY_DRIVER_DEVPTS_MEM) {
		master = ptmx_open(pi->cpt_index, master_flags);
	} else {
		sprintf(pairname, "/dev/pty%c%c", a[pi->cpt_index/16], b[pi->cpt_index%16]);
		master = filp_open(pairname, master_flags|O_NONBLOCK|O_NOCTTY|O_RDWR, 0);
	}
	if (IS_ERR(master)) {
		eprintk_ctx("filp_open master: %Ld %ld\n", (long long)fi->cpt_priv, PTR_ERR(master));
		cpt_release_buf(ctx);
		return master;
	}
	stty = file_tty(master);
	clear_bit(TTY_PTY_LOCK, &stty->flags);
	if (pi->cpt_drv_flags&TTY_DRIVER_DEVPTS_MEM)
		sprintf(pairname, "/dev/pts/%d", stty->index);
	else
		sprintf(pairname, "/dev/tty%c%c", a[stty->index/16], b[stty->index%16]);
	slave = filp_open(pairname, slave_flags|O_NONBLOCK|O_NOCTTY|O_RDWR, 0);
	if (IS_ERR(slave)) {
		eprintk_ctx("filp_open slave %s: %ld\n", pairname, PTR_ERR(slave));
		fput(master);
		cpt_release_buf(ctx);
		return slave;
	}

	if (pi->cpt_drv_subtype != PTY_TYPE_MASTER)
		fixup_tty_attrs(ii, slave, ctx);

	cpt_object_add(CPT_OBJ_TTY, file_tty(master), ctx);
	cpt_object_add(CPT_OBJ_TTY, file_tty(slave), ctx);
	cpt_object_add(CPT_OBJ_FILE, master, ctx);
	cpt_object_add(CPT_OBJ_FILE, slave, ctx);

	if (pi->cpt_drv_subtype == PTY_TYPE_MASTER) {
		loff_t pos;
		obj = lookup_cpt_object(CPT_OBJ_TTY, file_tty(master), ctx);
		obj->o_parent = master;
		cpt_obj_setpos(obj, fi->cpt_priv, ctx);
		pty_setup(stty, fi->cpt_priv, pi, ctx);

		obj = lookup_cpt_object(CPT_OBJ_TTY, file_tty(slave), ctx);
		obj->o_parent = slave;
		pos = find_pty_pair(stty->link, fi->cpt_priv, pi, ctx);
		cpt_obj_setpos(obj, pos, ctx);

		obj = lookup_cpt_object(CPT_OBJ_FILE, slave, ctx);
		cpt_obj_setpos(obj, CPT_NULL, ctx);
		get_file(master);
		cpt_release_buf(ctx);
		return master;
	} else {
		loff_t pos;
		obj = lookup_cpt_object(CPT_OBJ_TTY, file_tty(slave), ctx);
		obj->o_parent = slave;
		cpt_obj_setpos(obj, fi->cpt_priv, ctx);
		pty_setup(stty->link, fi->cpt_priv, pi, ctx);

		obj = lookup_cpt_object(CPT_OBJ_TTY, file_tty(master), ctx);
		obj->o_parent = master;
		pos = find_pty_pair(stty, fi->cpt_priv, pi, ctx);
		cpt_obj_setpos(obj, pos, ctx);

		obj = lookup_cpt_object(CPT_OBJ_FILE, master, ctx);
		cpt_obj_setpos(obj, CPT_NULL, ctx);
		get_file(slave);
		cpt_release_buf(ctx);
		return slave;
	}
}