Beispiel #1
0
static void
khttpd_ktr_logging_main(void *arg)
{
	struct sbuf *sbuf;
	struct thread *td;
	int error;

	KHTTPD_ASSERT_CURPROC_IS_KHTTPD();

	td = curthread;

	khttpd_ktr_logging_idx = ktr_idx;

	error = kern_openat(td, AT_FDCWD, KHTTPD_KTR_FILE, UIO_SYSSPACE,
	    O_CREAT | O_TRUNC | O_WRONLY, 0666);
	if (error != 0) {
		log(LOG_WARNING, "khttpd: failed to open ktr file '%s' "
		    "(error %d)", KHTTPD_KTR_FILE, error);
		goto quit;
	}
	kern_close(td, td->td_retval[0]);

	sbuf = sbuf_new_auto();

	while (!khttpd_ktr_logging_shutdown) {
		khttpd_ktr_logging(sbuf);
		pause("khttpd-ktr-flush", hz);
	}

	sbuf_delete(sbuf);

quit:
	khttpd_ktr_logging_thread = NULL;
	kthread_exit();
}
Beispiel #2
0
static void
khttpd_ktr_logging(struct sbuf *sbuf)
{
	struct uio auio;
	struct iovec aiov;
	struct ktr_entry *ep;
	struct thread *td;
	int error, fd, i, n;

	KHTTPD_ASSERT_CURPROC_IS_KHTTPD();

	td = curthread;

	error = kern_openat(td, AT_FDCWD, KHTTPD_KTR_FILE,
	    UIO_SYSSPACE, O_WRONLY | O_APPEND, 0666);
	if (error != 0) {
		log(LOG_WARNING,
		    "khttpd: failed to open ktr file '%s' (error %d)",
		    KHTTPD_KTR_FILE, error);
		return;
	}
	fd = td->td_retval[0];

	sbuf_clear(sbuf);

	n = ktr_entries;
	for (i = khttpd_ktr_logging_idx; i != ktr_idx;
	     i = i == n - 1 ? 0 : i + 1) {
		ep = &ktr_buf[i];

		sbuf_printf(sbuf, "%lld %p %d ",
		    (long long)ep->ktr_timestamp, ep->ktr_thread,
		    ep->ktr_cpu);
		sbuf_printf(sbuf, ep->ktr_desc, ep->ktr_parms[0],
		    ep->ktr_parms[1], ep->ktr_parms[2],
		    ep->ktr_parms[3], ep->ktr_parms[4],
		    ep->ktr_parms[5]);
		sbuf_cat(sbuf, "\n");
	}

	sbuf_finish(sbuf);

	khttpd_ktr_logging_idx = i;

	aiov.iov_base = sbuf_data(sbuf);
	aiov.iov_len = sbuf_len(sbuf);
	auio.uio_iov = &aiov;
	auio.uio_iovcnt = 1;
	auio.uio_resid = aiov.iov_len;
	auio.uio_segflg = UIO_SYSSPACE;
	error = kern_writev(td, fd, &auio);
	if (error != 0)
		log(LOG_WARNING, "khttpd: KTR flush failed "
		    "(error: %d)", error);

	kern_close(td, fd);
}
Beispiel #3
0
int
linux_creat(struct thread *td, struct linux_creat_args *args)
{
	char *path;
	int error;

	LCONVPATHEXIST(td, args->path, &path);
#ifdef DEBUG
	if (ldebug(creat))
		printf(ARGS(creat, "%s, %d"), path, args->mode);
#endif
	error = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE,
	    O_WRONLY | O_CREAT | O_TRUNC, args->mode);
	LFREEPATH(path);
	return (error);
}
Beispiel #4
0
static int
linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mode)
{
	cap_rights_t rights;
	struct proc *p = td->td_proc;
	struct file *fp;
	int fd;
	int bsd_flags, error;

	bsd_flags = 0;
	switch (l_flags & LINUX_O_ACCMODE) {
	case LINUX_O_WRONLY:
		bsd_flags |= O_WRONLY;
		break;
	case LINUX_O_RDWR:
		bsd_flags |= O_RDWR;
		break;
	default:
		bsd_flags |= O_RDONLY;
	}
	if (l_flags & LINUX_O_NDELAY)
		bsd_flags |= O_NONBLOCK;
	if (l_flags & LINUX_O_APPEND)
		bsd_flags |= O_APPEND;
	if (l_flags & LINUX_O_SYNC)
		bsd_flags |= O_FSYNC;
	if (l_flags & LINUX_O_NONBLOCK)
		bsd_flags |= O_NONBLOCK;
	if (l_flags & LINUX_FASYNC)
		bsd_flags |= O_ASYNC;
	if (l_flags & LINUX_O_CREAT)
		bsd_flags |= O_CREAT;
	if (l_flags & LINUX_O_TRUNC)
		bsd_flags |= O_TRUNC;
	if (l_flags & LINUX_O_EXCL)
		bsd_flags |= O_EXCL;
	if (l_flags & LINUX_O_NOCTTY)
		bsd_flags |= O_NOCTTY;
	if (l_flags & LINUX_O_DIRECT)
		bsd_flags |= O_DIRECT;
	if (l_flags & LINUX_O_NOFOLLOW)
		bsd_flags |= O_NOFOLLOW;
	if (l_flags & LINUX_O_DIRECTORY)
		bsd_flags |= O_DIRECTORY;
	/* XXX LINUX_O_NOATIME: unable to be easily implemented. */

	error = kern_openat(td, dirfd, path, UIO_SYSSPACE, bsd_flags, mode);
	if (error != 0)
		goto done;
	if (bsd_flags & O_NOCTTY)
		goto done;

	/*
	 * XXX In between kern_open() and fget(), another process
	 * having the same filedesc could use that fd without
	 * checking below.
	*/
	fd = td->td_retval[0];
	if (fget(td, fd, cap_rights_init(&rights, CAP_IOCTL), &fp) == 0) {
		if (fp->f_type != DTYPE_VNODE) {
			fdrop(fp, td);
			goto done;
		}
		sx_slock(&proctree_lock);
		PROC_LOCK(p);
		if (SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
			PROC_UNLOCK(p);
			sx_sunlock(&proctree_lock);
			/* XXXPJD: Verify if TIOCSCTTY is allowed. */
			(void) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0,
			    td->td_ucred, td);
		} else {
			PROC_UNLOCK(p);
			sx_sunlock(&proctree_lock);
		}
		fdrop(fp, td);
	}

done:
#ifdef DEBUG
	if (ldebug(open))
		printf(LMSG("open returns error %d"), error);
#endif
	LFREEPATH(path);
	return (error);
}
Beispiel #5
0
static int
parse_dir_md(char **conf)
{
	struct stat sb;
	struct thread *td;
	struct md_ioctl *mdio;
	char *path, *tok;
	int error, fd, len;

	td = curthread;

	error = parse_token(conf, &tok);
	if (error)
		return (error);

	len = strlen(tok);
	mdio = malloc(sizeof(*mdio) + len + 1, M_TEMP, M_WAITOK | M_ZERO);
	path = (void *)(mdio + 1);
	bcopy(tok, path, len);
	free(tok, M_TEMP);

	/* Get file status. */
	error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &sb, NULL);
	if (error)
		goto out;

	/* Open /dev/mdctl so that we can attach/detach. */
	error = kern_openat(td, AT_FDCWD, "/dev/" MDCTL_NAME, UIO_SYSSPACE,
	    O_RDWR, 0);
	if (error)
		goto out;

	fd = td->td_retval[0];
	mdio->md_version = MDIOVERSION;
	mdio->md_type = MD_VNODE;

	if (root_mount_mddev != -1) {
		mdio->md_unit = root_mount_mddev;
		DROP_GIANT();
		error = kern_ioctl(td, fd, MDIOCDETACH, (void *)mdio);
		PICKUP_GIANT();
		/* Ignore errors. We don't care. */
		root_mount_mddev = -1;
	}

	mdio->md_file = (void *)(mdio + 1);
	mdio->md_options = MD_AUTOUNIT | MD_READONLY;
	mdio->md_mediasize = sb.st_size;
	mdio->md_unit = 0;
	DROP_GIANT();
	error = kern_ioctl(td, fd, MDIOCATTACH, (void *)mdio);
	PICKUP_GIANT();
	if (error)
		goto out;

	if (mdio->md_unit > 9) {
		printf("rootmount: too many md units\n");
		mdio->md_file = NULL;
		mdio->md_options = 0;
		mdio->md_mediasize = 0;
		DROP_GIANT();
		error = kern_ioctl(td, fd, MDIOCDETACH, (void *)mdio);
		PICKUP_GIANT();
		/* Ignore errors. We don't care. */
		error = ERANGE;
		goto out;
	}

	root_mount_mddev = mdio->md_unit;
	printf(MD_NAME "%u attached to %s\n", root_mount_mddev, mdio->md_file);

	error = kern_close(td, fd);

 out:
	free(mdio, M_TEMP);
	return (error);
}