Simplify hostid logic
There is plenty of compatibility code for a hw_hostid that isn't used by anything. At the same time, there are apparently issues with the current hostid logic. coredumb in #zfsonlinux on freenode reported that Fedora 17 changes its hostid on every boot, which required force importing his pool. A suggestion by wca was to adopt FreeBSD's behavior, where it treats hostid as zero if /etc/hostid does not exist Adopting FreeBSD's behavior permits us to eliminate plenty of code, including a userland helper that invokes the system's hostid as a fallback. Signed-off-by: Richard Yao <ryao@cs.stonybrook.edu> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #224
This commit is contained in:
parent
3ceb71e896
commit
acf0ade362
|
@ -143,7 +143,6 @@
|
||||||
/* Missing globals */
|
/* Missing globals */
|
||||||
extern char spl_version[32];
|
extern char spl_version[32];
|
||||||
extern unsigned long spl_hostid;
|
extern unsigned long spl_hostid;
|
||||||
extern char hw_serial[11];
|
|
||||||
|
|
||||||
/* Missing misc functions */
|
/* Missing misc functions */
|
||||||
extern int highbit(unsigned long i);
|
extern int highbit(unsigned long i);
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#ifndef _SPL_SYSTEMINFO_H
|
#ifndef _SPL_SYSTEMINFO_H
|
||||||
#define _SPL_SYSTEMINFO_H
|
#define _SPL_SYSTEMINFO_H
|
||||||
|
|
||||||
#define HW_INVALID_HOSTID 0xFFFFFFFF /* an invalid hostid */
|
|
||||||
#define HW_HOSTID_LEN 11 /* minimum buffer size needed */
|
#define HW_HOSTID_LEN 11 /* minimum buffer size needed */
|
||||||
/* to hold a decimal or hex */
|
/* to hold a decimal or hex */
|
||||||
/* hostid string */
|
/* hostid string */
|
||||||
|
|
|
@ -52,14 +52,11 @@
|
||||||
char spl_version[32] = "SPL v" SPL_META_VERSION "-" SPL_META_RELEASE;
|
char spl_version[32] = "SPL v" SPL_META_VERSION "-" SPL_META_RELEASE;
|
||||||
EXPORT_SYMBOL(spl_version);
|
EXPORT_SYMBOL(spl_version);
|
||||||
|
|
||||||
unsigned long spl_hostid = HW_INVALID_HOSTID;
|
unsigned long spl_hostid = 0;
|
||||||
EXPORT_SYMBOL(spl_hostid);
|
EXPORT_SYMBOL(spl_hostid);
|
||||||
module_param(spl_hostid, ulong, 0644);
|
module_param(spl_hostid, ulong, 0644);
|
||||||
MODULE_PARM_DESC(spl_hostid, "The system hostid.");
|
MODULE_PARM_DESC(spl_hostid, "The system hostid.");
|
||||||
|
|
||||||
char hw_serial[HW_HOSTID_LEN] = "<none>";
|
|
||||||
EXPORT_SYMBOL(hw_serial);
|
|
||||||
|
|
||||||
proc_t p0 = { 0 };
|
proc_t p0 = { 0 };
|
||||||
EXPORT_SYMBOL(p0);
|
EXPORT_SYMBOL(p0);
|
||||||
|
|
||||||
|
@ -467,7 +464,7 @@ hostid_read(void)
|
||||||
int result;
|
int result;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
struct _buf *file;
|
struct _buf *file;
|
||||||
unsigned long hostid = 0;
|
uint32_t hostid = 0;
|
||||||
|
|
||||||
file = kobj_open_file(spl_hostid_path);
|
file = kobj_open_file(spl_hostid_path);
|
||||||
|
|
||||||
|
@ -511,45 +508,10 @@ hostid_read(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_HOSTID_CMD \
|
|
||||||
"exec 0</dev/null " \
|
|
||||||
" 1>/proc/sys/kernel/spl/hostid " \
|
|
||||||
" 2>/dev/null; " \
|
|
||||||
"hostid"
|
|
||||||
|
|
||||||
static int
|
|
||||||
hostid_exec(void)
|
|
||||||
{
|
|
||||||
char *argv[] = { "/bin/sh",
|
|
||||||
"-c",
|
|
||||||
GET_HOSTID_CMD,
|
|
||||||
NULL };
|
|
||||||
char *envp[] = { "HOME=/",
|
|
||||||
"TERM=linux",
|
|
||||||
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
|
|
||||||
NULL };
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* Doing address resolution in the kernel is tricky and just
|
|
||||||
* not a good idea in general. So to set the proper 'hw_serial'
|
|
||||||
* use the usermodehelper support to ask '/bin/sh' to run
|
|
||||||
* '/usr/bin/hostid' and redirect the result to /proc/sys/spl/hostid
|
|
||||||
* for us to use. It's a horrific solution but it will do for now.
|
|
||||||
*/
|
|
||||||
rc = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
|
|
||||||
if (rc)
|
|
||||||
printk("SPL: Failed user helper '%s %s %s', rc = %d\n",
|
|
||||||
argv[0], argv[1], argv[2], rc);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
zone_get_hostid(void *zone)
|
zone_get_hostid(void *zone)
|
||||||
{
|
{
|
||||||
static int first = 1;
|
static int first = 1;
|
||||||
unsigned long hostid;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* Only the global zone is supported */
|
/* Only the global zone is supported */
|
||||||
ASSERT(zone == NULL);
|
ASSERT(zone == NULL);
|
||||||
|
@ -559,21 +521,16 @@ zone_get_hostid(void *zone)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the hostid if it was not passed as a module parameter.
|
* Get the hostid if it was not passed as a module parameter.
|
||||||
* Try reading the /etc/hostid file directly, and then fall
|
* Try reading the /etc/hostid file directly.
|
||||||
* back to calling the /usr/bin/hostid utility.
|
|
||||||
*/
|
*/
|
||||||
if ((spl_hostid == HW_INVALID_HOSTID) &&
|
if (hostid_read())
|
||||||
(rc = hostid_read()) && (rc = hostid_exec()))
|
spl_hostid = 0;
|
||||||
return HW_INVALID_HOSTID;
|
|
||||||
|
|
||||||
printk(KERN_NOTICE "SPL: using hostid 0x%08x\n",
|
printk(KERN_NOTICE "SPL: using hostid 0x%08x\n",
|
||||||
(unsigned int) spl_hostid);
|
(unsigned int) spl_hostid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ddi_strtoul(hw_serial, NULL, HW_HOSTID_LEN-1, &hostid) != 0)
|
return spl_hostid;
|
||||||
return HW_INVALID_HOSTID;
|
|
||||||
|
|
||||||
return (uint32_t)hostid;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(zone_get_hostid);
|
EXPORT_SYMBOL(zone_get_hostid);
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,6 @@ struct proc_dir_entry *proc_spl_kstat = NULL;
|
||||||
|
|
||||||
#define CTL_VERSION CTL_UNNUMBERED /* Version */
|
#define CTL_VERSION CTL_UNNUMBERED /* Version */
|
||||||
#define CTL_HOSTID CTL_UNNUMBERED /* Host id by /usr/bin/hostid */
|
#define CTL_HOSTID CTL_UNNUMBERED /* Host id by /usr/bin/hostid */
|
||||||
#define CTL_HW_SERIAL CTL_UNNUMBERED /* HW serial number by hostid */
|
|
||||||
#define CTL_KALLSYMS CTL_UNNUMBERED /* kallsyms_lookup_name addr */
|
#define CTL_KALLSYMS CTL_UNNUMBERED /* kallsyms_lookup_name addr */
|
||||||
|
|
||||||
#define CTL_DEBUG_SUBSYS CTL_UNNUMBERED /* Debug subsystem */
|
#define CTL_DEBUG_SUBSYS CTL_UNNUMBERED /* Debug subsystem */
|
||||||
|
@ -129,7 +128,6 @@ enum {
|
||||||
enum {
|
enum {
|
||||||
CTL_VERSION = 1, /* Version */
|
CTL_VERSION = 1, /* Version */
|
||||||
CTL_HOSTID, /* Host id reported by /usr/bin/hostid */
|
CTL_HOSTID, /* Host id reported by /usr/bin/hostid */
|
||||||
CTL_HW_SERIAL, /* Hardware serial number from hostid */
|
|
||||||
CTL_KALLSYMS, /* Address of kallsyms_lookup_name */
|
CTL_KALLSYMS, /* Address of kallsyms_lookup_name */
|
||||||
|
|
||||||
#ifdef DEBUG_LOG
|
#ifdef DEBUG_LOG
|
||||||
|
@ -513,9 +511,6 @@ SPL_PROC_HANDLER(proc_dohostid)
|
||||||
if (str == end)
|
if (str == end)
|
||||||
SRETURN(-EINVAL);
|
SRETURN(-EINVAL);
|
||||||
|
|
||||||
(void) snprintf(hw_serial, HW_HOSTID_LEN, "%lu", spl_hostid);
|
|
||||||
hw_serial[HW_HOSTID_LEN - 1] = '\0';
|
|
||||||
*ppos += *lenp;
|
|
||||||
} else {
|
} else {
|
||||||
len = snprintf(str, sizeof(str), "%lx", spl_hostid);
|
len = snprintf(str, sizeof(str), "%lx", spl_hostid);
|
||||||
if (*ppos >= len)
|
if (*ppos >= len)
|
||||||
|
@ -1058,14 +1053,6 @@ static struct ctl_table spl_table[] = {
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = &proc_dohostid,
|
.proc_handler = &proc_dohostid,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
CTL_NAME (CTL_HW_SERIAL)
|
|
||||||
.procname = "hw_serial",
|
|
||||||
.data = hw_serial,
|
|
||||||
.maxlen = sizeof(hw_serial),
|
|
||||||
.mode = 0444,
|
|
||||||
.proc_handler = &proc_dostring,
|
|
||||||
},
|
|
||||||
#ifndef HAVE_KALLSYMS_LOOKUP_NAME
|
#ifndef HAVE_KALLSYMS_LOOKUP_NAME
|
||||||
{
|
{
|
||||||
CTL_NAME (CTL_KALLSYMS)
|
CTL_NAME (CTL_KALLSYMS)
|
||||||
|
|
Loading…
Reference in New Issue