59 #include <sys/zfs_fuid.h> |
59 #include <sys/zfs_fuid.h> |
60 #include <sys/bootconf.h> |
60 #include <sys/bootconf.h> |
61 #include <sys/sunddi.h> |
61 #include <sys/sunddi.h> |
62 #include <sys/dnlc.h> |
62 #include <sys/dnlc.h> |
63 #include <sys/dmu_objset.h> |
63 #include <sys/dmu_objset.h> |
|
64 #include <sys/spa_boot.h> |
64 |
65 |
65 int zfsfstype; |
66 int zfsfstype; |
66 vfsops_t *zfs_vfsops = NULL; |
67 vfsops_t *zfs_vfsops = NULL; |
67 static major_t zfs_major; |
68 static major_t zfs_major; |
68 static minor_t zfs_minor; |
69 static minor_t zfs_minor; |
859 |
860 |
860 static int |
861 static int |
861 zfs_mountroot(vfs_t *vfsp, enum whymountroot why) |
862 zfs_mountroot(vfs_t *vfsp, enum whymountroot why) |
862 { |
863 { |
863 int error = 0; |
864 int error = 0; |
864 int ret = 0; |
|
865 static int zfsrootdone = 0; |
865 static int zfsrootdone = 0; |
866 zfsvfs_t *zfsvfs = NULL; |
866 zfsvfs_t *zfsvfs = NULL; |
867 znode_t *zp = NULL; |
867 znode_t *zp = NULL; |
868 vnode_t *vp = NULL; |
868 vnode_t *vp = NULL; |
869 char *zfs_bootpath; |
869 char *zfs_bootfs; |
870 #if defined(_OBP) |
|
871 int proplen; |
|
872 #endif |
|
873 |
870 |
874 ASSERT(vfsp); |
871 ASSERT(vfsp); |
875 |
872 |
876 /* |
873 /* |
877 * The filesystem that we mount as root is defined in the |
874 * The filesystem that we mount as root is defined in the |
878 * "zfs-bootfs" property. |
875 * boot property "zfs-bootfs" with a format of |
|
876 * "poolname/root-dataset-objnum". |
879 */ |
877 */ |
880 if (why == ROOT_INIT) { |
878 if (why == ROOT_INIT) { |
881 if (zfsrootdone++) |
879 if (zfsrootdone++) |
882 return (EBUSY); |
880 return (EBUSY); |
883 |
881 /* |
884 #if defined(_OBP) |
882 * the process of doing a spa_load will require the |
885 proplen = BOP_GETPROPLEN(bootops, "zfs-bootfs"); |
883 * clock to be set before we could (for example) do |
886 if (proplen == 0) |
884 * something better by looking at the timestamp on |
887 return (EIO); |
885 * an uberblock, so just set it to -1. |
888 zfs_bootpath = kmem_zalloc(proplen, KM_SLEEP); |
886 */ |
889 if (BOP_GETPROP(bootops, "zfs-bootfs", zfs_bootpath) == -1) { |
887 clkset(-1); |
890 kmem_free(zfs_bootpath, proplen); |
888 |
891 return (EIO); |
889 if ((zfs_bootfs = spa_get_bootfs()) == NULL) { |
|
890 cmn_err(CE_NOTE, "\nspa_get_bootfs: can not get " |
|
891 "bootfs name \n"); |
|
892 return (EINVAL); |
892 } |
893 } |
893 error = parse_bootpath(zfs_bootpath, rootfs.bo_name); |
894 |
894 kmem_free(zfs_bootpath, proplen); |
895 if (error = spa_import_rootpool(rootfs.bo_name)) { |
895 #else |
896 spa_free_bootfs(zfs_bootfs); |
896 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), |
897 cmn_err(CE_NOTE, "\nspa_import_rootpool: error %d\n", |
897 DDI_PROP_DONTPASS, "zfs-bootfs", &zfs_bootpath) != |
898 error); |
898 DDI_SUCCESS) |
|
899 return (EIO); |
|
900 |
|
901 error = parse_bootpath(zfs_bootpath, rootfs.bo_name); |
|
902 ddi_prop_free(zfs_bootpath); |
|
903 #endif |
|
904 |
|
905 if (error) |
|
906 return (error); |
899 return (error); |
|
900 } |
|
901 |
|
902 if (error = zfs_parse_bootfs(zfs_bootfs, rootfs.bo_name)) { |
|
903 spa_free_bootfs(zfs_bootfs); |
|
904 cmn_err(CE_NOTE, "\nzfs_parse_bootfs: error %d\n", |
|
905 error); |
|
906 return (error); |
|
907 } |
|
908 |
|
909 spa_free_bootfs(zfs_bootfs); |
907 |
910 |
908 if (error = vfs_lock(vfsp)) |
911 if (error = vfs_lock(vfsp)) |
909 return (error); |
912 return (error); |
910 |
913 |
911 if (error = zfs_domount(vfsp, rootfs.bo_name, CRED())) |
914 if (error = zfs_domount(vfsp, rootfs.bo_name, CRED())) { |
|
915 cmn_err(CE_NOTE, "\nzfs_domount: error %d\n", error); |
912 goto out; |
916 goto out; |
|
917 } |
913 |
918 |
914 zfsvfs = (zfsvfs_t *)vfsp->vfs_data; |
919 zfsvfs = (zfsvfs_t *)vfsp->vfs_data; |
915 ASSERT(zfsvfs); |
920 ASSERT(zfsvfs); |
916 if (error = zfs_zget(zfsvfs, zfsvfs->z_root, &zp)) |
921 if (error = zfs_zget(zfsvfs, zfsvfs->z_root, &zp)) { |
|
922 cmn_err(CE_NOTE, "\nzfs_zget: error %d\n", error); |
917 goto out; |
923 goto out; |
|
924 } |
918 |
925 |
919 vp = ZTOV(zp); |
926 vp = ZTOV(zp); |
920 mutex_enter(&vp->v_lock); |
927 mutex_enter(&vp->v_lock); |
921 vp->v_flag |= VROOT; |
928 vp->v_flag |= VROOT; |
922 mutex_exit(&vp->v_lock); |
929 mutex_exit(&vp->v_lock); |
926 * The zfs_zget call above returns with a hold on vp, we release |
933 * The zfs_zget call above returns with a hold on vp, we release |
927 * it here. |
934 * it here. |
928 */ |
935 */ |
929 VN_RELE(vp); |
936 VN_RELE(vp); |
930 |
937 |
931 /* |
|
932 * Mount root as readonly initially, it will be remouted |
|
933 * read/write by /lib/svc/method/fs-usr. |
|
934 */ |
|
935 readonly_changed_cb(vfsp->vfs_data, B_TRUE); |
|
936 vfs_add((struct vnode *)0, vfsp, |
938 vfs_add((struct vnode *)0, vfsp, |
937 (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0); |
939 (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0); |
938 out: |
940 out: |
939 vfs_unlock(vfsp); |
941 vfs_unlock(vfsp); |
940 ret = (error) ? error : 0; |
942 return (error); |
941 return (ret); |
|
942 } else if (why == ROOT_REMOUNT) { |
943 } else if (why == ROOT_REMOUNT) { |
943 readonly_changed_cb(vfsp->vfs_data, B_FALSE); |
944 readonly_changed_cb(vfsp->vfs_data, B_FALSE); |
944 vfsp->vfs_flag |= VFS_REMOUNT; |
945 vfsp->vfs_flag |= VFS_REMOUNT; |
945 |
946 |
946 /* refresh mount options */ |
947 /* refresh mount options */ |