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(); }
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); }
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); }
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); }
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); }