summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_mib.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_mib.c')
-rw-r--r--sys/kern/kern_mib.c156
1 files changed, 79 insertions, 77 deletions
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
index 38116d5..823df6b 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
#include <sys/smp.h>
#include <sys/sx.h>
#include <sys/unistd.h>
-#include <sys/vimage.h>
SYSCTL_NODE(, 0, sysctl, CTLFLAG_RW, 0,
"Sysctl internal magic");
@@ -209,71 +208,69 @@ static char machine_arch[] = MACHINE_ARCH;
SYSCTL_STRING(_hw, HW_MACHINE_ARCH, machine_arch, CTLFLAG_RD,
machine_arch, 0, "System architecture");
-#ifdef VIMAGE_GLOBALS
-char hostname[MAXHOSTNAMELEN];
-#endif
-
-/*
- * This mutex is used to protect the hostname and domainname variables, and
- * perhaps in the future should also protect hostid, hostuid, and others.
- */
-struct mtx hostname_mtx;
-MTX_SYSINIT(hostname_mtx, &hostname_mtx, "hostname", MTX_DEF);
-
static int
sysctl_hostname(SYSCTL_HANDLER_ARGS)
{
- INIT_VPROCG(TD_TO_VPROCG(req->td));
- struct prison *pr;
- char tmphostname[MAXHOSTNAMELEN];
- int error;
+ struct prison *pr, *cpr;
+ size_t pr_offset;
+ char tmpname[MAXHOSTNAMELEN];
+ int descend, error, len;
+
+ /*
+ * This function can set: hostname domainname hostuuid.
+ * Keep that in mind when comments say "hostname".
+ */
+ pr_offset = (size_t)arg1;
+ len = arg2;
+ KASSERT(len <= sizeof(tmpname),
+ ("length %d too long for %s", len, __func__));
pr = req->td->td_ucred->cr_prison;
- if (pr != &prison0) {
- if (!(pr->pr_allow & PR_ALLOW_SET_HOSTNAME) && req->newptr)
- return (EPERM);
+ if (!(pr->pr_allow & PR_ALLOW_SET_HOSTNAME) && req->newptr)
+ return (EPERM);
+ /*
+ * Make a local copy of hostname to get/set so we don't have to hold
+ * the jail mutex during the sysctl copyin/copyout activities.
+ */
+ mtx_lock(&pr->pr_mtx);
+ bcopy((char *)pr + pr_offset, tmpname, len);
+ mtx_unlock(&pr->pr_mtx);
+
+ error = sysctl_handle_string(oidp, tmpname, len, req);
+
+ if (req->newptr != NULL && error == 0) {
/*
- * Process is in jail, so make a local copy of jail
- * hostname to get/set so we don't have to hold the jail
- * mutex during the sysctl copyin/copyout activities.
+ * Copy the locally set hostname to all jails that share
+ * this host info.
*/
+ sx_slock(&allprison_lock);
+ while (!(pr->pr_flags & PR_HOST))
+ pr = pr->pr_parent;
mtx_lock(&pr->pr_mtx);
- bcopy(pr->pr_host, tmphostname, MAXHOSTNAMELEN);
+ bcopy(tmpname, (char *)pr + pr_offset, len);
+ FOREACH_PRISON_DESCENDANT_LOCKED(pr, cpr, descend)
+ if (cpr->pr_flags & PR_HOST)
+ descend = 0;
+ else
+ bcopy(tmpname, (char *)cpr + pr_offset, len);
mtx_unlock(&pr->pr_mtx);
-
- error = sysctl_handle_string(oidp, tmphostname,
- sizeof pr->pr_host, req);
-
- if (req->newptr != NULL && error == 0) {
- /*
- * Copy the locally set hostname to the jail, if
- * appropriate.
- */
- mtx_lock(&pr->pr_mtx);
- bcopy(tmphostname, pr->pr_host, MAXHOSTNAMELEN);
- mtx_unlock(&pr->pr_mtx);
- }
- } else {
- mtx_lock(&hostname_mtx);
- bcopy(V_hostname, tmphostname, MAXHOSTNAMELEN);
- mtx_unlock(&hostname_mtx);
- error = sysctl_handle_string(oidp, tmphostname,
- sizeof tmphostname, req);
- if (req->newptr != NULL && error == 0) {
- mtx_lock(&prison0.pr_mtx);
- mtx_lock(&hostname_mtx);
- bcopy(tmphostname, prison0.pr_host, MAXHOSTNAMELEN);
- bcopy(tmphostname, V_hostname, MAXHOSTNAMELEN);
- mtx_unlock(&hostname_mtx);
- mtx_unlock(&prison0.pr_mtx);
- }
+ sx_sunlock(&allprison_lock);
}
return (error);
}
SYSCTL_PROC(_kern, KERN_HOSTNAME, hostname,
- CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_PRISON|CTLFLAG_MPSAFE,
- 0, 0, sysctl_hostname, "A", "Hostname");
+ CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
+ (void *)(offsetof(struct prison, pr_host)), MAXHOSTNAMELEN,
+ sysctl_hostname, "A", "Hostname");
+SYSCTL_PROC(_kern, KERN_NISDOMAINNAME, domainname,
+ CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
+ (void *)(offsetof(struct prison, pr_domain)), MAXHOSTNAMELEN,
+ sysctl_hostname, "A", "Name of the current YP/NIS domain");
+SYSCTL_PROC(_kern, KERN_HOSTUUID, hostuuid,
+ CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
+ (void *)(offsetof(struct prison, pr_uuid)), HOSTUUIDLEN,
+ sysctl_hostname, "A", "Host UUID");
static int regression_securelevel_nonmonotonic = 0;
@@ -341,38 +338,43 @@ SYSCTL_PROC(_kern, OID_AUTO, conftxt, CTLTYPE_STRING|CTLFLAG_RW,
0, 0, sysctl_kern_config, "", "Kernel configuration file");
#endif
-#ifdef VIMAGE_GLOBALS
-char domainname[MAXHOSTNAMELEN]; /* Protected by hostname_mtx. */
-#endif
-
static int
-sysctl_domainname(SYSCTL_HANDLER_ARGS)
+sysctl_hostid(SYSCTL_HANDLER_ARGS)
{
- INIT_VPROCG(TD_TO_VPROCG(req->td));
- char tmpdomainname[MAXHOSTNAMELEN];
- int error;
-
- mtx_lock(&hostname_mtx);
- bcopy(V_domainname, tmpdomainname, MAXHOSTNAMELEN);
- mtx_unlock(&hostname_mtx);
- error = sysctl_handle_string(oidp, tmpdomainname,
- sizeof tmpdomainname, req);
+ struct prison *pr, *cpr;
+ u_long tmpid;
+ int descend, error;
+
+ /*
+ * Like sysctl_hostname, except it operates on a u_long
+ * instead of a string, and is used only for hostid.
+ */
+ pr = req->td->td_ucred->cr_prison;
+ if (!(pr->pr_allow & PR_ALLOW_SET_HOSTNAME) && req->newptr)
+ return (EPERM);
+ tmpid = pr->pr_hostid;
+ error = sysctl_handle_long(oidp, &tmpid, 0, req);
+
if (req->newptr != NULL && error == 0) {
- mtx_lock(&hostname_mtx);
- bcopy(tmpdomainname, V_domainname, MAXHOSTNAMELEN);
- mtx_unlock(&hostname_mtx);
+ sx_slock(&allprison_lock);
+ while (!(pr->pr_flags & PR_HOST))
+ pr = pr->pr_parent;
+ mtx_lock(&pr->pr_mtx);
+ pr->pr_hostid = tmpid;
+ FOREACH_PRISON_DESCENDANT_LOCKED(pr, cpr, descend)
+ if (cpr->pr_flags & PR_HOST)
+ descend = 0;
+ else
+ cpr->pr_hostid = tmpid;
+ mtx_unlock(&pr->pr_mtx);
+ sx_sunlock(&allprison_lock);
}
return (error);
}
-SYSCTL_PROC(_kern, KERN_NISDOMAINNAME, domainname, CTLTYPE_STRING|CTLFLAG_RW,
- 0, 0, sysctl_domainname, "A", "Name of the current YP/NIS domain");
-
-u_long hostid;
-SYSCTL_ULONG(_kern, KERN_HOSTID, hostid, CTLFLAG_RW, &hostid, 0, "Host ID");
-char hostuuid[64] = "00000000-0000-0000-0000-000000000000";
-SYSCTL_STRING(_kern, KERN_HOSTUUID, hostuuid, CTLFLAG_RW, hostuuid,
- sizeof(hostuuid), "Host UUID");
+SYSCTL_PROC(_kern, KERN_HOSTID, hostid,
+ CTLTYPE_ULONG | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
+ NULL, 0, sysctl_hostid, "LU", "Host ID");
SYSCTL_NODE(_kern, OID_AUTO, features, CTLFLAG_RD, 0, "Kernel Features");
OpenPOWER on IntegriCloud