Exemple #1
0
static void
futex_put(struct futex *f, struct waiting_proc *wp)
{
	LIN_SDT_PROBE2(futex, futex_put, entry, f, wp);

	FUTEX_ASSERT_LOCKED(f);
	if (wp != NULL) {
		if ((wp->wp_flags & FUTEX_WP_REMOVED) == 0)
			TAILQ_REMOVE(&f->f_waiting_proc, wp, wp_list);
		free(wp, M_FUTEX_WP);
	}

	FUTEXES_LOCK;
	if (--f->f_refcount == 0) {
		LIST_REMOVE(f, f_list);
		FUTEXES_UNLOCK;
		FUTEX_UNLOCK(f);

		LIN_SDT_PROBE3(futex, futex_put, destroy, f->f_uaddr,
		    f->f_refcount, f->f_key.shared);
		LINUX_CTR3(sys_futex, "futex_put destroy uaddr %p ref %d "
		    "shared %d", f->f_uaddr, f->f_refcount, f->f_key.shared);
		umtx_key_release(&f->f_key);
		FUTEX_DESTROY(f);
		free(f, M_FUTEX);

		LIN_SDT_PROBE0(futex, futex_put, return);
		return;
	}
Exemple #2
0
int
linux_lchown16(struct thread *td, struct linux_lchown16_args *args)
{
	char *path;
	int error;

	LCONVPATHEXIST(td, args->path, &path);

	/*
	 * The DTrace probes have to be after the LCONVPATHEXIST, as
	 * LCONVPATHEXIST may return on its own and we do not want to
	 * have a stray entry without the corresponding return.
	 */
	LIN_SDT_PROBE3(uid16, linux_lchown16, entry, args->path, args->uid,
	    args->gid);
	LIN_SDT_PROBE1(uid16, linux_lchown16, conv_path, path);

	error = kern_lchown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid),
	    CAST_NOCHG(args->gid));
	LFREEPATH(path);

	LIN_SDT_PROBE1(uid16, linux_lchown16, return, error);
	return (error);
}
Exemple #3
0
int
linux_proc_init(struct thread *td, pid_t child, int flags)
{
	struct linux_emuldata *em, *p_em;
	struct proc *p;

	LIN_SDT_PROBE3(emul, proc_init, entry, td, child, flags);

	if (child != 0) {
		/* fork or create a thread */
		em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO);
		em->pid = child;
		em->pdeath_signal = 0;
		em->flags = 0;
		em->robust_futexes = NULL;
		if (flags & LINUX_CLONE_THREAD) {
			/* handled later in the code */
			LIN_SDT_PROBE0(emul, proc_init, create_thread);
		} else {
			struct linux_emuldata_shared *s;

			LIN_SDT_PROBE0(emul, proc_init, fork);

			s = malloc(sizeof *s, M_LINUX, M_WAITOK | M_ZERO);
			s->refs = 1;
			s->group_pid = child;

			LIST_INIT(&s->threads);
			em->shared = s;
		}
	} else {
		/* exec */
		LIN_SDT_PROBE0(emul, proc_init, exec);

		/* lookup the old one */
		em = em_find(td->td_proc, EMUL_DOLOCK);
		KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n"));
	}

	em->child_clear_tid = NULL;
	em->child_set_tid = NULL;

	/*
	 * allocate the shared struct only in clone()/fork cases in the case
	 * of clone() td = calling proc and child = pid of the newly created
	 * proc
	 */
	if (child != 0) {
		if (flags & LINUX_CLONE_THREAD) {
			/* lookup the parent */
			/* 
			 * we dont have to lock the p_em because
			 * its waiting for us in linux_clone so
			 * there is no chance of it changing the
			 * p_em->shared address
			 */
			p_em = em_find(td->td_proc, EMUL_DONTLOCK);
			KASSERT(p_em != NULL, ("proc_init: parent emuldata not found for CLONE_THREAD\n"));
			em->shared = p_em->shared;
			EMUL_SHARED_WLOCK(&emul_shared_lock);
			em->shared->refs++;
			EMUL_SHARED_WUNLOCK(&emul_shared_lock);
		} else {
			/*
			 * handled earlier to avoid malloc(M_WAITOK) with
			 * rwlock held
			 */
		}

		EMUL_SHARED_WLOCK(&emul_shared_lock);
		LIST_INSERT_HEAD(&em->shared->threads, em, threads);
		EMUL_SHARED_WUNLOCK(&emul_shared_lock);

		p = pfind(child);
		KASSERT(p != NULL, ("process not found in proc_init\n"));
		p->p_emuldata = em;
		PROC_UNLOCK(p);
	} else
		EMUL_UNLOCK(&emul_lock);

	LIN_SDT_PROBE0(emul, proc_init, return);
	return (0);
}