Author: pjd
Date: Wed Jul 29 05:23:52 2009
New Revision: 195938
URL: http://svn.freebsd.org/changeset/base/195938

Log:
  Currently there is a problem with fscking UFS file systems created on
  top of ZVOLs. The problem is that rc.d/fsck runs before rc.d/zfs. The
  latter makes ZVOLs to appear in /dev/. In such case rc.d/fsck cannot
  find devfs entry and aborts. We cannot simply move rc.d/zfs before
  rc.d/fsck, because we first want kern.hostid to be configured (by
  rc.d/hostid). If we won't wait (hostid will be 0) we can reuse disks
  which are in use by different systems (eg. in SAN/NAS environment).
  We also cannot move rc.d/hostid before rc.d/fsck, because rc.d/hostid on
  first system start stores generated kern.hostuuid in /etc/hostid file,
  so it needs root file system to be mounted read-write.
  
  The fix is to split rc.d/hostid so that rc.d/hostid (which will now run
  before rc.d/fsck) only generates hostid and sets up sysctls, but doesn't
  touch root file system and rc.d/hostid_save (which is run after
  rc.d/root) and only creates /etc/hostid file.
  
  With that in place, we can move ZVOL initialization to dedicated
  rc.d/zvol script which runs before rc.d/fsck.
  
  PR:           conf/120194
  Reported by:  James Snow <s...@teardrop.org>
  Reviewed by:  brooks
  Approved by:  re (kib)
  MFC after:    2 weeks

Added:
  head/etc/rc.d/hostid_save   (contents, props changed)
  head/etc/rc.d/zvol   (contents, props changed)
Modified:
  head/etc/rc.d/Makefile
  head/etc/rc.d/hostid
  head/etc/rc.d/zfs

Modified: head/etc/rc.d/Makefile
==============================================================================
--- head/etc/rc.d/Makefile      Wed Jul 29 00:39:46 2009        (r195937)
+++ head/etc/rc.d/Makefile      Wed Jul 29 05:23:52 2009        (r195938)
@@ -13,7 +13,7 @@ FILES=        DAEMON FILESYSTEMS LOGIN NETWORKI
        fsck ftp-proxy ftpd \
        gbde geli geli2 gssd \
        hcsecd \
-       hostapd hostid hostname \
+       hostapd hostid hostid_save hostname \
        inetd initrandom \
        ip6addrctl ip6fw ipfilter ipfs ipfw ipmon \
        ipnat ipsec ipxrouted \
@@ -40,7 +40,7 @@ FILES=        DAEMON FILESYSTEMS LOGIN NETWORKI
        watchdogd wpa_supplicant \
        ypbind yppasswdd ypserv \
        ypset ypupdated ypxfrd \
-       zfs
+       zfs zvol
 
 .if ${MK_OPENSSH} != "no"
 FILES+=        sshd

Modified: head/etc/rc.d/hostid
==============================================================================
--- head/etc/rc.d/hostid        Wed Jul 29 00:39:46 2009        (r195937)
+++ head/etc/rc.d/hostid        Wed Jul 29 05:23:52 2009        (r195938)
@@ -28,8 +28,7 @@
 #
 
 # PROVIDE: hostid
-# REQUIRE: root
-# BEFORE: mountcritlocal
+# BEFORE: fsck
 # KEYWORD: nojail
 
 . /etc/rc.subr
@@ -68,7 +67,7 @@ hostid_hardware()
        esac
 }
 
-hostid_reset()
+hostid_generate()
 {
        # First look for UUID in hardware.
        uuid=`hostid_hardware`
@@ -76,12 +75,17 @@ hostid_reset()
                # If not found, fall back to software-generated UUID.
                uuid=`uuidgen`
        fi
+       hostid_set $uuid
+}
+
+hostid_reset()
+{
+       hostid_generate
        # Store newly generated UUID in ${hostid_file}.
        echo $uuid > ${hostid_file}
        if [ $? -ne 0 ]; then
                warn "could not store hostuuid in ${hostid_file}."
        fi
-       hostid_set $uuid
 }
 
 hostid_start()
@@ -91,7 +95,7 @@ hostid_start()
                hostid_set `cat ${hostid_file}`
        else
                # No hostid file, generate UUID.
-               hostid_reset
+               hostid_generate
        fi
 }
 

Added: head/etc/rc.d/hostid_save
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/etc/rc.d/hostid_save   Wed Jul 29 05:23:52 2009        (r195938)
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# PROVIDE: hostid_save
+# REQUIRE: root
+# BEFORE: mountcritlocal
+# KEYWORD: nojail
+
+. /etc/rc.subr
+
+name="hostid_save"
+start_cmd="hostid_save"
+stop_cmd=":"
+rcvar="hostid_enable"
+
+hostid_save()
+{
+       if [ ! -r ${hostid_file} ]; then
+               $SYSCTL_N kern.hostuuid > ${hostid_file}
+               if [ $? -ne 0 ]; then
+                       warn "could not store hostuuid in ${hostid_file}."
+               fi
+       fi
+}
+
+load_rc_config $name
+run_rc_command "$1"

Modified: head/etc/rc.d/zfs
==============================================================================
--- head/etc/rc.d/zfs   Wed Jul 29 00:39:46 2009        (r195937)
+++ head/etc/rc.d/zfs   Wed Jul 29 05:23:52 2009        (r195938)
@@ -23,21 +23,11 @@ zfs_start_jail()
 
 zfs_start_main()
 {
-       zfs volinit
        zfs mount -a
        zfs share -a
        if [ ! -r /etc/zfs/exports ]; then
                touch /etc/zfs/exports
        fi
-       # Enable swap on ZVOLs with property org.freebsd:swap=on.
-       zfs list -H -o org.freebsd:swap,name -t volume | \
-       while read state name; do
-               case "${state}" in
-               [oO][nN])
-                       swapon /dev/zvol/${name}
-                       ;;
-               esac
-       done
 }
 
 zfs_start()
@@ -58,18 +48,8 @@ zfs_stop_jail()
 
 zfs_stop_main()
 {
-       # Disable swap on ZVOLs with property org.freebsd:swap=on.
-       zfs list -H -o org.freebsd:swap,name -t volume | \
-       while read state name; do
-               case "${state}" in
-               [oO][nN])
-                       swapoff /dev/zvol/${name}
-                       ;;
-               esac
-       done
        zfs unshare -a
        zfs unmount -a
-       zfs volfini
 }
 
 zfs_stop()

Added: head/etc/rc.d/zvol
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/etc/rc.d/zvol  Wed Jul 29 05:23:52 2009        (r195938)
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# PROVIDE: zvol
+# REQUIRE: hostid
+# BEFORE: fsck
+# KEYWORD: nojail
+
+. /etc/rc.subr
+
+name="zvol"
+rcvar="zfs_enable"
+start_cmd="zvol_start"
+stop_cmd="zvol_stop"
+required_modules="zfs"
+
+zvol_start()
+{
+       zfs volinit
+       # Enable swap on ZVOLs with property org.freebsd:swap=on.
+       zfs list -H -o org.freebsd:swap,name -t volume | \
+       while read state name; do
+               case "${state}" in
+               [oO][nN])
+                       swapon /dev/zvol/${name}
+                       ;;
+               esac
+       done
+}
+
+zvol_stop()
+{
+       # Disable swap on ZVOLs with property org.freebsd:swap=on.
+       zfs list -H -o org.freebsd:swap,name -t volume | \
+       while read state name; do
+               case "${state}" in
+               [oO][nN])
+                       swapoff /dev/zvol/${name}
+                       ;;
+               esac
+       done
+       zfs volfini
+}
+
+load_rc_config $name
+run_rc_command "$1"
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to