Use gethostid in the Linux convention.
authorDarik Horn <dajhorn@vanadac.com>
Mon, 25 Apr 2011 15:18:07 +0000 (10:18 -0500)
committerDarik Horn <dajhorn@vanadac.com>
Mon, 25 Apr 2011 15:36:17 +0000 (10:36 -0500)
Disable the gethostid() override for Solaris behavior because Linux systems
implement the POSIX standard in a way that allows a negative result.

Mask the gethostid() result to the lower four bytes, like coreutils does in
/usr/bin/hostid, to prevent junk bits or sign-extension on systems that have an
eight byte long type. This can cause a spurious hostid mismatch that prevents
zpool import on 64-bit systems.

cmd/zpool/zpool_main.c
lib/libspl/include/unistd.h
lib/libzfs/libzfs_status.c

index bad4e2a..3b81573 100644 (file)
@@ -1533,7 +1533,9 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
 
                if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
                    &hostid) == 0) {
-                       if ((unsigned long)hostid != gethostid()) {
+                       unsigned long system_hostid = gethostid() & 0xffffffff;
+
+                       if ((unsigned long)hostid != system_hostid) {
                                char *hostname;
                                uint64_t timestamp;
                                time_t t;
index 44173d2..dc95e28 100644 (file)
 # define issetugid() (geteuid() == 0 || getegid() == 0)
 #endif
 
-#if !defined(__sun__) && !defined(__sun)
-/* It seems Solaris only returns positive host ids */
-static inline long fake_gethostid(void)
-{
-       long id = gethostid();
-       return id >= 0 ? id : -id;
-}
-#define gethostid() fake_gethostid()
-#endif
-
 #endif /* _LIBSPL_UNISTD_H */
index 24725ec..d56baf0 100644 (file)
@@ -179,6 +179,7 @@ check_status(nvlist_t *config, boolean_t isimport)
        uint64_t stateval;
        uint64_t suspended;
        uint64_t hostid = 0;
+       unsigned long system_hostid = gethostid() & 0xffffffff;
 
        verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
            &version) == 0);
@@ -202,7 +203,7 @@ check_status(nvlist_t *config, boolean_t isimport)
         * Pool last accessed by another system.
         */
        (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
-       if (hostid != 0 && (unsigned long)hostid != gethostid() &&
+       if (hostid != 0 && (unsigned long)hostid != system_hostid &&
            stateval == POOL_STATE_ACTIVE)
                return (ZPOOL_STATUS_HOSTID_MISMATCH);