and used by tar. [1] - bsd-user: Fix crashes in sysctl.kern.proc in 32bit envs on 64bit. [1] - Bump PORTREVISION. Submitted by: sson [1]
154 lines
4.8 KiB
Plaintext
154 lines
4.8 KiB
Plaintext
diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c
|
|
index 6012562..87a6aa7 100644
|
|
--- a/bsd-user/freebsd/os-sys.c
|
|
+++ b/bsd-user/freebsd/os-sys.c
|
|
@@ -1,7 +1,7 @@
|
|
/*
|
|
* FreeBSD sysctl() and sysarch() system call emulation
|
|
*
|
|
- * Copyright (c) 2013 Stacey D. Son
|
|
+ * Copyright (c) 2013-14 Stacey D. Son
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
@@ -19,6 +19,7 @@
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/param.h>
|
|
+#include <sys/mount.h>
|
|
#include <sys/sysctl.h>
|
|
#include <string.h>
|
|
|
|
@@ -28,6 +29,59 @@
|
|
#include "target_os_vmparam.h"
|
|
|
|
/*
|
|
+ * XXX The following should maybe go some place else. Also, see the note
|
|
+ * about using "thunk" for sysctl's that pass data using structures.
|
|
+ */
|
|
+/* From sys/mount.h: */
|
|
+#define TARGET_MFSNAMELEN 16 /* length of type name including null */
|
|
+struct target_xvfsconf {
|
|
+ abi_ulong vfc_vfsops; /* filesystem op vector - not used */
|
|
+ char vfc_name[TARGET_MFSNAMELEN]; /* filesystem type name */
|
|
+ int32_t vfc_typenum; /* historic fs type number */
|
|
+ int32_t vfc_refcount; /* number mounted of this type */
|
|
+ int32_t vfc_flags; /* permanent flags */
|
|
+ abi_ulong vfc_next; /* next int list - not used */
|
|
+};
|
|
+
|
|
+/* vfc_flag definitions */
|
|
+#define TARGET_VFCF_STATIC 0x00010000 /* statically compiled into kernel */
|
|
+#define TARGET_VFCF_NETWORK 0x00020000 /* may get data over the network */
|
|
+#define TARGET_VFCF_READONLY 0x00040000 /* writes are not implemented */
|
|
+#define TARGET_VFCF_SYNTHETIC 0x00080000 /* doesn't represent real files */
|
|
+#define TARGET_VFCF_LOOPBACK 0x00100000 /* aliases some other mounted FS */
|
|
+#define TARGET_VFCF_UNICODE 0x00200000 /* stores file names as Unicode */
|
|
+#define TARGET_VFCF_JAIL 0x00400000 /* can be mounted within a jail */
|
|
+#define TARGET_VFCF_DELEGADMIN 0x00800000 /* supports delegated admin */
|
|
+#define TARGET_VFCF_SBDRY 0x01000000 /* defer stop requests */
|
|
+
|
|
+static int
|
|
+host_to_target_vfc_flags(int flags)
|
|
+{
|
|
+ int ret = 0;
|
|
+
|
|
+ if (flags & VFCF_STATIC)
|
|
+ ret |= TARGET_VFCF_STATIC;
|
|
+ if (flags & VFCF_NETWORK)
|
|
+ ret |= TARGET_VFCF_NETWORK;
|
|
+ if (flags & VFCF_READONLY)
|
|
+ ret |= TARGET_VFCF_READONLY;
|
|
+ if (flags & VFCF_SYNTHETIC)
|
|
+ ret |= TARGET_VFCF_SYNTHETIC;
|
|
+ if (flags & VFCF_LOOPBACK)
|
|
+ ret |= TARGET_VFCF_LOOPBACK;
|
|
+ if (flags & VFCF_UNICODE)
|
|
+ ret |= TARGET_VFCF_UNICODE;
|
|
+ if (flags & VFCF_JAIL)
|
|
+ ret |= TARGET_VFCF_JAIL;
|
|
+ if (flags & VFCF_DELEGADMIN)
|
|
+ ret |= TARGET_VFCF_DELEGADMIN;
|
|
+ if (flags & VFCF_SBDRY)
|
|
+ ret |= TARGET_VFCF_SBDRY;
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/*
|
|
* XXX this uses the undocumented oidfmt interface to find the kind of
|
|
* a requested sysctl, see /sys/kern/kern_sysctl.c:sysctl_sysctl_oidfmt()
|
|
* (compare to src/sbin/sysctl/sysctl.c)
|
|
@@ -161,6 +215,7 @@ abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen,
|
|
oidfmt(snamep, namelen, NULL, &kind);
|
|
|
|
/* Handle some arch/emulator dependent sysctl()'s here. */
|
|
+ /* XXX sysctl()'s that pass structs should use thunk like ioctl(). */
|
|
switch (snamep[0]) {
|
|
case CTL_KERN:
|
|
switch (snamep[1]) {
|
|
@@ -212,6 +267,63 @@ abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen,
|
|
}
|
|
break;
|
|
|
|
+ case CTL_VFS:
|
|
+ {
|
|
+ static int oid_vfs_conflist;
|
|
+
|
|
+ if (!oid_vfs_conflist) {
|
|
+ int real_oid[CTL_MAXNAME+2];
|
|
+ size_t len = sizeof(real_oid) / sizeof(int);
|
|
+
|
|
+ if (sysctlnametomib("vfs.conflist", real_oid, &len) >= 0)
|
|
+ oid_vfs_conflist = real_oid[1];
|
|
+ }
|
|
+
|
|
+ if (oid_vfs_conflist && snamep[1] == oid_vfs_conflist) {
|
|
+ struct xvfsconf *xvfsp;
|
|
+ struct target_xvfsconf *txp;
|
|
+ int cnt, i;
|
|
+
|
|
+ if (sysctlbyname("vfs.conflist", NULL, &holdlen, NULL, 0) < 0) {
|
|
+ ret = -1;
|
|
+ goto out;
|
|
+ }
|
|
+ cnt = holdlen / sizeof(struct xvfsconf);
|
|
+ if (!holdp) {
|
|
+ holdlen = cnt * sizeof(struct target_xvfsconf);
|
|
+ ret = 0;
|
|
+ goto out;
|
|
+ }
|
|
+ xvfsp = (struct xvfsconf *)g_malloc(holdlen);
|
|
+ if (xvfsp == NULL) {
|
|
+ ret = -TARGET_ENOMEM;
|
|
+ goto out;
|
|
+ }
|
|
+ if (sysctlbyname("vfs.conflist", xvfsp, &holdlen, NULL, 0) < 0){
|
|
+ g_free(xvfsp);
|
|
+ ret = -1;
|
|
+ goto out;
|
|
+ }
|
|
+ cnt = holdlen / sizeof(struct xvfsconf);
|
|
+ holdlen = cnt * sizeof(struct target_xvfsconf);
|
|
+ txp = (struct target_xvfsconf *)holdp;
|
|
+ for (i = 0; i < cnt; i++) {
|
|
+ txp[i].vfc_vfsops = 0;
|
|
+ strlcpy(txp[i].vfc_name, xvfsp[i].vfc_name,
|
|
+ TARGET_MFSNAMELEN);
|
|
+ txp[i].vfc_typenum = tswap32(xvfsp[i].vfc_typenum);
|
|
+ txp[i].vfc_refcount = tswap32(xvfsp[i].vfc_refcount);
|
|
+ txp[i].vfc_flags = tswap32(
|
|
+ host_to_target_vfc_flags(xvfsp[i].vfc_flags));
|
|
+ txp[i].vfc_next = 0;
|
|
+ }
|
|
+ g_free(xvfsp);
|
|
+ ret = 0;
|
|
+ goto out;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+
|
|
case CTL_HW:
|
|
switch (snamep[1]) {
|
|
case HW_MACHINE:
|