diff options
author | John Sonnenschein <johns@joyent.com> | 2012-07-30 18:55:21 +0000 |
---|---|---|
committer | John Sonnenschein <johns@joyent.com> | 2012-07-30 18:55:21 +0000 |
commit | 3f12efe73c075bbfe7e254714e8fabfb50f86af0 (patch) | |
tree | f429351c58a9955c46f03b8789bce1e152d32660 /usr/src/grub | |
parent | 2453263d59c2317dbe88d1c9e12893a32abd91b8 (diff) | |
parent | 5ada8a07255938930de285f1d55b0ef0bdba90ff (diff) | |
download | illumos-joyent-3f12efe73c075bbfe7e254714e8fabfb50f86af0.tar.gz |
Illumos Sync
Merge github.com:illumos/illumos-gate
Conflicts:
exception_lists/check_rtime
usr/src/Makefile.master
usr/src/Makefile.master.64
usr/src/cmd/Makefile
usr/src/cmd/lms/Makefile
usr/src/cmd/lp/Makefile.lp
usr/src/cmd/mdb/Makefile.mdb
usr/src/cmd/mdb/common/mdb/mdb_cmds.c
usr/src/cmd/mdb/common/mdb/mdb_print.c
usr/src/cmd/mdb/common/mdb/mdb_print.h
usr/src/cmd/mdb/common/mdb/mdb_tab.c
usr/src/cmd/mdb/common/mdb/mdb_termio.c
usr/src/cmd/mdb/common/mdb/mdb_whatis.c
usr/src/cmd/svc/svccfg/svccfg_libscf.c
usr/src/cmd/zpool/zpool_main.c
usr/src/lib/Makefile
usr/src/lib/libc/inc/thr_inlines.h
usr/src/lib/libc/port/mapfile-vers
usr/src/lib/libc/sparc/Makefile.com
usr/src/lib/libc/sparc/crt/_rtld.c
usr/src/lib/libc/sparcv9/Makefile.com
usr/src/lib/libdtrace/common/dt_open.c
usr/src/lib/libdtrace/common/dt_options.c
usr/src/lib/libumem/common/envvar.c
usr/src/lib/libumem/common/vmem_base.c
usr/src/lib/libzfs/common/libzfs_impl.h
usr/src/lib/libzfs/common/libzfs_iter.c
usr/src/lib/libzfs/common/libzfs_util.c
usr/src/lib/libzfs/common/mapfile-vers
usr/src/lib/sun_fc/Makefile.com
usr/src/lib/sun_fc/amd64/Makefile
usr/src/lib/sun_fc/sparcv9/Makefile
usr/src/man/man1m/Makefile
usr/src/uts/common/Makefile.files
usr/src/uts/common/dtrace/dtrace.c
usr/src/uts/common/fs/zfs/arc.c
usr/src/uts/common/fs/zfs/dmu.c
usr/src/uts/common/fs/zfs/dsl_dataset.c
usr/src/uts/common/fs/zfs/dsl_pool.c
usr/src/uts/common/fs/zfs/sys/zio.h
usr/src/uts/common/io/fibre-channel/fca/fcoei/fcoei_eth.c
usr/src/uts/common/io/fibre-channel/fca/fcoei/fcoei_lv.c
usr/src/uts/common/sys/dtrace.h
Diffstat (limited to 'usr/src/grub')
-rw-r--r-- | usr/src/grub/capability | 4 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/fsys_zfs.c | 422 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/fsys_zfs.h | 40 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/zfs-include/dmu.h | 70 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/zfs-include/spa.h | 7 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/zfs-include/zfs.h | 12 |
6 files changed, 448 insertions, 107 deletions
diff --git a/usr/src/grub/capability b/usr/src/grub/capability index 225ce5bb83..44aaae2cb8 100644 --- a/usr/src/grub/capability +++ b/usr/src/grub/capability @@ -19,7 +19,7 @@ # CDDL HEADER END # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# +# Copyright (c) 2012 by Delphix. All rights reserved. # # This file defines the current capabilities of GRUB over and above that # supported by the standard distribution @@ -39,7 +39,7 @@ # This file and the associated version are Solaris specific and are # not a part of the open source distribution of GRUB. # -VERSION=20 +VERSION=21 dboot xVM zfs diff --git a/usr/src/grub/grub-0.97/stage2/fsys_zfs.c b/usr/src/grub/grub-0.97/stage2/fsys_zfs.c index 4eed0afe9a..3d1129c4ea 100644 --- a/usr/src/grub/grub-0.97/stage2/fsys_zfs.c +++ b/usr/src/grub/grub-0.97/stage2/fsys_zfs.c @@ -16,12 +16,17 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* + * Copyright (c) 2012 by Delphix. All rights reserved. + */ + +/* * The zfs plug-in routines for GRUB are: * * zfs_mount() - locates a valid uberblock of the root pool and reads @@ -118,16 +123,16 @@ zio_checksum_off(const void *buf, uint64_t size, zio_cksum_t *zcp) /* Checksum Table and Values */ zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { - NULL, NULL, 0, 0, "inherit", - NULL, NULL, 0, 0, "on", - zio_checksum_off, zio_checksum_off, 0, 0, "off", - zio_checksum_SHA256, zio_checksum_SHA256, 1, 1, "label", - zio_checksum_SHA256, zio_checksum_SHA256, 1, 1, "gang_header", - NULL, NULL, 0, 0, "zilog", - fletcher_2_native, fletcher_2_byteswap, 0, 0, "fletcher2", - fletcher_4_native, fletcher_4_byteswap, 1, 0, "fletcher4", - zio_checksum_SHA256, zio_checksum_SHA256, 1, 0, "SHA256", - NULL, NULL, 0, 0, "zilog2", + {{NULL, NULL}, 0, 0, "inherit"}, + {{NULL, NULL}, 0, 0, "on"}, + {{zio_checksum_off, zio_checksum_off}, 0, 0, "off"}, + {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 1, "label"}, + {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 1, "gang_header"}, + {{NULL, NULL}, 0, 0, "zilog"}, + {{fletcher_2_native, fletcher_2_byteswap}, 0, 0, "fletcher2"}, + {{fletcher_4_native, fletcher_4_byteswap}, 1, 0, "fletcher4"}, + {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 0, "SHA256"}, + {{NULL, NULL}, 0, 0, "zilog2"}, }; /* @@ -217,9 +222,6 @@ vdev_uberblock_compare(uberblock_t *ub1, uberblock_t *ub2) * Three pieces of information are needed to verify an uberblock: the magic * number, the version number, and the checksum. * - * Currently Implemented: version number, magic number - * Need to Implement: checksum - * * Return: * 0 - Success * -1 - Failure @@ -238,7 +240,7 @@ uberblock_verify(uberblock_t *uber, uint64_t ub_size, uint64_t offset) return (-1); if (uber->ub_magic == UBERBLOCK_MAGIC && - uber->ub_version > 0 && uber->ub_version <= SPA_VERSION) + SPA_VERSION_IS_SUPPORTED(uber->ub_version)) return (0); return (-1); @@ -296,7 +298,7 @@ zio_read_gang(blkptr_t *bp, dva_t *dva, void *buf, char *stack) zio_gb = (zio_gbh_phys_t *)stack; stack += SPA_GANGBLOCKSIZE; offset = DVA_GET_OFFSET(dva); - sector = DVA_OFFSET_TO_PHYS_SECTOR(offset); + sector = DVA_OFFSET_TO_PHYS_SECTOR(offset); /* read in the gang block header */ if (devread(sector, 0, SPA_GANGBLOCKSIZE, (char *)zio_gb) == 0) { @@ -355,8 +357,8 @@ zio_read_data(blkptr_t *bp, void *buf, char *stack) } else { /* read in a data block */ offset = DVA_GET_OFFSET(&bp->blk_dva[i]); - sector = DVA_OFFSET_TO_PHYS_SECTOR(offset); - if (devread(sector, 0, psize, buf)) + sector = DVA_OFFSET_TO_PHYS_SECTOR(offset); + if (devread(sector, 0, psize, buf) != 0) return (0); } } @@ -400,7 +402,7 @@ zio_read(blkptr_t *bp, void *buf, char *stack) stack += psize; } - if (zio_read_data(bp, buf, stack)) { + if (zio_read_data(bp, buf, stack) != 0) { grub_printf("zio_read_data failed\n"); return (ERR_FSYS_CORRUPT); } @@ -466,13 +468,13 @@ dmu_read(dnode_phys_t *dn, uint64_t blkid, void *buf, char *stack) * errnum - failure */ static int -mzap_lookup(mzap_phys_t *zapobj, int objsize, char *name, +mzap_lookup(mzap_phys_t *zapobj, int objsize, const char *name, uint64_t *value) { int i, chunks; mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk; - chunks = objsize/MZAP_ENT_LEN - 1; + chunks = objsize / MZAP_ENT_LEN - 1; for (i = 0; i < chunks; i++) { if (grub_strcmp(mzap_ent[i].mze_name, name) == 0) { *value = mzap_ent[i].mze_value; @@ -512,8 +514,8 @@ zap_hash(uint64_t salt, const char *name) /* * Only use 28 bits, since we need 4 bits in the cookie for the * collision differentiator. We MUST use the high bits, since - * those are the onces that we first pay attention to when - * chosing the bucket. + * those are the ones that we first pay attention to when + * choosing the bucket. */ crc &= ~((1ULL << (64 - 28)) - 1); @@ -618,7 +620,7 @@ zap_leaf_lookup(zap_leaf_phys_t *l, int blksft, uint64_t h, */ static int fzap_lookup(dnode_phys_t *zap_dnode, zap_phys_t *zap, - char *name, uint64_t *value, char *stack) + const char *name, uint64_t *value, char *stack) { zap_leaf_phys_t *l; uint64_t hash, idx, blkid; @@ -661,7 +663,8 @@ fzap_lookup(dnode_phys_t *zap_dnode, zap_phys_t *zap, * errnum - failure */ static int -zap_lookup(dnode_phys_t *zap_dnode, char *name, uint64_t *val, char *stack) +zap_lookup(dnode_phys_t *zap_dnode, const char *name, uint64_t *val, + char *stack) { uint64_t block_type; int size; @@ -672,7 +675,7 @@ zap_lookup(dnode_phys_t *zap_dnode, char *name, uint64_t *val, char *stack) size = zap_dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT; stack += size; - if (errnum = dmu_read(zap_dnode, 0, zapbuf, stack)) + if ((errnum = dmu_read(zap_dnode, 0, zapbuf, stack)) != 0) return (errnum); block_type = *((uint64_t *)zapbuf); @@ -688,6 +691,56 @@ zap_lookup(dnode_phys_t *zap_dnode, char *name, uint64_t *val, char *stack) return (ERR_FSYS_CORRUPT); } +typedef struct zap_attribute { + int za_integer_length; + uint64_t za_num_integers; + uint64_t za_first_integer; + char *za_name; +} zap_attribute_t; + +typedef int (zap_cb_t)(zap_attribute_t *za, void *arg, char *stack); + +static int +zap_iterate(dnode_phys_t *zap_dnode, zap_cb_t *cb, void *arg, char *stack) +{ + uint32_t size = zap_dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT; + zap_attribute_t za; + int i; + mzap_phys_t *mzp = (mzap_phys_t *)stack; + stack += size; + + if ((errnum = dmu_read(zap_dnode, 0, mzp, stack)) != 0) + return (errnum); + + /* + * Iteration over fatzap objects has not yet been implemented. + * If we encounter a pool in which there are more features for + * read than can fit inside a microzap (i.e., more than 2048 + * features for read), we can add support for fatzap iteration. + * For now, fail. + */ + if (mzp->mz_block_type != ZBT_MICRO) { + grub_printf("feature information stored in fatzap, pool " + "version not supported\n"); + return (1); + } + + za.za_integer_length = 8; + za.za_num_integers = 1; + for (i = 0; i < size / MZAP_ENT_LEN - 1; i++) { + mzap_ent_phys_t *mzep = &mzp->mz_chunk[i]; + int err; + + za.za_first_integer = mzep->mze_value; + za.za_name = mzep->mze_name; + err = cb(&za, arg, stack); + if (err != 0) + return (err); + } + + return (0); +} + /* * Get the dnode of an object number from the metadnode of an object set. * @@ -767,6 +820,24 @@ is_top_dataset_file(char *str) return (0); } +static int +check_feature(zap_attribute_t *za, void *arg, char *stack) +{ + const char **names = arg; + int i; + + if (za->za_first_integer == 0) + return (0); + + for (i = 0; names[i] != NULL; i++) { + if (grub_strcmp(za->za_name, names[i]) == 0) { + return (0); + } + } + grub_printf("missing feature for read '%s'\n", za->za_name); + return (ERR_NEWER_VERSION); +} + /* * Get the file dnode for a given file name where mdn is the meta dnode * for this ZFS object set. When found, place the file dnode in dn. @@ -803,11 +874,11 @@ dnode_get_path(dnode_phys_t *mdn, char *path, dnode_phys_t *dn, while (*path == '/') path++; - while (*path && !isspace(*path)) { + while (*path && !grub_isspace(*path)) { /* get the next component name */ cname = path; - while (*path && !isspace(*path) && *path != '/') + while (*path && !grub_isspace(*path) && *path != '/') path++; ch = *path; *path = 0; /* ensure null termination */ @@ -869,6 +940,53 @@ get_default_bootfsobj(dnode_phys_t *mosmdn, uint64_t *obj, char *stack) } /* + * List of pool features that the grub implementation of ZFS supports for + * read. Note that features that are only required for write do not need + * to be listed here since grub opens pools in read-only mode. + */ +static const char *spa_feature_names[] = { + NULL +}; + +/* + * Checks whether the MOS features that are active are supported by this + * (GRUB's) implementation of ZFS. + * + * Return: + * 0: Success. + * errnum: Failure. + */ +static int +check_mos_features(dnode_phys_t *mosmdn, char *stack) +{ + uint64_t objnum; + dnode_phys_t *dn; + uint8_t error = 0; + + dn = (dnode_phys_t *)stack; + stack += DNODE_SIZE; + + if ((errnum = dnode_get(mosmdn, DMU_POOL_DIRECTORY_OBJECT, + DMU_OT_OBJECT_DIRECTORY, dn, stack)) != 0) + return (errnum); + + /* + * Find the object number for 'features_for_read' and retrieve its + * corresponding dnode. Note that we don't check features_for_write + * because GRUB is not opening the pool for write. + */ + if ((errnum = zap_lookup(dn, DMU_POOL_FEATURES_FOR_READ, &objnum, + stack)) != 0) + return (errnum); + + if ((errnum = dnode_get(mosmdn, objnum, DMU_OTN_ZAP_METADATA, + dn, stack)) != 0) + return (errnum); + + return (zap_iterate(dn, check_feature, spa_feature_names, stack)); +} + +/* * Given a MOS metadnode, get the metadnode of a given filesystem name (fsname), * e.g. pool/rootfs, or a given object number (obj), e.g. the object number * of pool/rootfs. @@ -915,23 +1033,24 @@ get_objset_mdn(dnode_phys_t *mosmdn, char *fsname, uint64_t *obj, } /* take out the pool name */ - while (*fsname && !isspace(*fsname) && *fsname != '/') + while (*fsname && !grub_isspace(*fsname) && *fsname != '/') fsname++; - while (*fsname && !isspace(*fsname)) { + while (*fsname && !grub_isspace(*fsname)) { uint64_t childobj; while (*fsname == '/') fsname++; cname = fsname; - while (*fsname && !isspace(*fsname) && *fsname != '/') + while (*fsname && !grub_isspace(*fsname) && *fsname != '/') fsname++; ch = *fsname; *fsname = 0; snapname = cname; - while (*snapname && !isspace(*snapname) && *snapname != '@') + while (*snapname && !grub_isspace(*snapname) && *snapname != + '@') snapname++; if (*snapname == '@') { issnapshot = 1; @@ -1020,8 +1139,7 @@ nvlist_unpack(char *nvlist, char **out) if (nvlist[0] != NV_ENCODE_XDR || nvlist[1] != HOST_ENDIAN) return (1); - nvlist += 4; - *out = nvlist; + *out = nvlist + 4; return (0); } @@ -1043,72 +1161,162 @@ nvlist_array(char *nvlist, int index) return (nvlist); } +/* + * The nvlist_next_nvpair() function returns a handle to the next nvpair in the + * list following nvpair. If nvpair is NULL, the first pair is returned. If + * nvpair is the last pair in the nvlist, NULL is returned. + */ +static char * +nvlist_next_nvpair(char *nvl, char *nvpair) +{ + char *cur, *prev; + int encode_size; + + if (nvl == NULL) + return (NULL); + + if (nvpair == NULL) { + /* skip over nvl_version and nvl_nvflag */ + nvpair = nvl + 4 * 2; + } else { + /* skip to the next nvpair */ + encode_size = BSWAP_32(*(uint32_t *)nvpair); + nvpair += encode_size; + } + + /* 8 bytes of 0 marks the end of the list */ + if (*(uint64_t *)nvpair == 0) + return (NULL); + + return (nvpair); +} + +/* + * This function returns 0 on success and 1 on failure. On success, a string + * containing the name of nvpair is saved in buf. + */ static int -nvlist_lookup_value(char *nvlist, char *name, void *val, int valtype, - int *nelmp) +nvpair_name(char *nvp, char *buf, int buflen) +{ + int len; + + /* skip over encode/decode size */ + nvp += 4 * 2; + + len = BSWAP_32(*(uint32_t *)nvp); + if (buflen < len + 1) + return (1); + + grub_memmove(buf, nvp + 4, len); + buf[len] = '\0'; + + return (0); +} + +/* + * This function retrieves the value of the nvpair in the form of enumerated + * type data_type_t. This is used to determine the appropriate type to pass to + * nvpair_value(). + */ +static int +nvpair_type(char *nvp) { - int name_len, type, slen, encode_size; - char *nvpair, *nvp_name, *strval = val; + int name_len, type; + + /* skip over encode/decode size */ + nvp += 4 * 2; + + /* skip over name_len */ + name_len = BSWAP_32(*(uint32_t *)nvp); + nvp += 4; + + /* skip over name */ + nvp = nvp + ((name_len + 3) & ~3); /* align */ + + type = BSWAP_32(*(uint32_t *)nvp); + + return (type); +} + +static int +nvpair_value(char *nvp, void *val, int valtype, int *nelmp) +{ + int name_len, type, slen; + char *strval = val; uint64_t *intval = val; - /* skip the header, nvl_version, and nvl_nvflag */ - nvlist = nvlist + 4 * 2; + /* skip over encode/decode size */ + nvp += 4 * 2; - /* - * Loop thru the nvpair list - * The XDR representation of an integer is in big-endian byte order. - */ - while (encode_size = BSWAP_32(*(uint32_t *)nvlist)) { + /* skip over name_len */ + name_len = BSWAP_32(*(uint32_t *)nvp); + nvp += 4; - nvpair = nvlist + 4 * 2; /* skip the encode/decode size */ + /* skip over name */ + nvp = nvp + ((name_len + 3) & ~3); /* align */ - name_len = BSWAP_32(*(uint32_t *)nvpair); - nvpair += 4; + /* skip over type */ + type = BSWAP_32(*(uint32_t *)nvp); + nvp += 4; - nvp_name = nvpair; - nvpair = nvpair + ((name_len + 3) & ~3); /* align */ + if (type == valtype) { + int nelm; - type = BSWAP_32(*(uint32_t *)nvpair); - nvpair += 4; + nelm = BSWAP_32(*(uint32_t *)nvp); + if (valtype != DATA_TYPE_BOOLEAN && nelm < 1) + return (1); + nvp += 4; - if ((grub_strncmp(nvp_name, name, name_len) == 0) && - type == valtype) { - int nelm; + switch (valtype) { + case DATA_TYPE_BOOLEAN: + return (0); - if ((nelm = BSWAP_32(*(uint32_t *)nvpair)) < 1) - return (1); - nvpair += 4; - - switch (valtype) { - case DATA_TYPE_STRING: - slen = BSWAP_32(*(uint32_t *)nvpair); - nvpair += 4; - grub_memmove(strval, nvpair, slen); - strval[slen] = '\0'; - return (0); + case DATA_TYPE_STRING: + slen = BSWAP_32(*(uint32_t *)nvp); + nvp += 4; + grub_memmove(strval, nvp, slen); + strval[slen] = '\0'; + return (0); - case DATA_TYPE_UINT64: - *intval = BSWAP_64(*(uint64_t *)nvpair); - return (0); + case DATA_TYPE_UINT64: + *intval = BSWAP_64(*(uint64_t *)nvp); + return (0); - case DATA_TYPE_NVLIST: - *(void **)val = (void *)nvpair; - return (0); + case DATA_TYPE_NVLIST: + *(void **)val = (void *)nvp; + return (0); - case DATA_TYPE_NVLIST_ARRAY: - *(void **)val = (void *)nvpair; - if (nelmp) - *nelmp = nelm; - return (0); - } + case DATA_TYPE_NVLIST_ARRAY: + *(void **)val = (void *)nvp; + if (nelmp) + *nelmp = nelm; + return (0); } - - nvlist += encode_size; /* goto the next nvpair */ } return (1); } +static int +nvlist_lookup_value(char *nvlist, char *name, void *val, int valtype, + int *nelmp) +{ + char *nvpair; + + for (nvpair = nvlist_next_nvpair(nvlist, NULL); + nvpair != NULL; + nvpair = nvlist_next_nvpair(nvlist, nvpair)) { + int name_len = BSWAP_32(*(uint32_t *)(nvpair + 4 * 2)); + char *nvp_name = nvpair + 4 * 3; + + if ((grub_strncmp(nvp_name, name, name_len) == 0) && + nvpair_type(nvpair) == valtype) { + return (nvpair_value(nvpair, val, valtype, nelmp)); + } + } + return (1); +} + /* * Check if this vdev is online and is in a good state. */ @@ -1142,7 +1350,7 @@ vdev_get_bootpath(char *nv, uint64_t inguid, char *devid, char *bootpath, NULL)) return (ERR_FSYS_CORRUPT); - if (strcmp(type, VDEV_TYPE_DISK) == 0) { + if (grub_strcmp(type, VDEV_TYPE_DISK) == 0) { uint64_t guid; if (vdev_validate(nv) != 0) @@ -1172,15 +1380,15 @@ vdev_get_bootpath(char *nv, uint64_t inguid, char *devid, char *bootpath, devid, DATA_TYPE_STRING, NULL) != 0) devid[0] = '\0'; - if (strlen(bootpath) >= MAXPATHLEN || - strlen(devid) >= MAXPATHLEN) + if (grub_strlen(bootpath) >= MAXPATHLEN || + grub_strlen(devid) >= MAXPATHLEN) return (ERR_WONT_FIT); return (0); - } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 || - strcmp(type, VDEV_TYPE_REPLACING) == 0 || - (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) { + } else if (grub_strcmp(type, VDEV_TYPE_MIRROR) == 0 || + grub_strcmp(type, VDEV_TYPE_REPLACING) == 0 || + (is_spare = (grub_strcmp(type, VDEV_TYPE_SPARE) == 0))) { int nelm, i; char *child; @@ -1208,15 +1416,14 @@ vdev_get_bootpath(char *nv, uint64_t inguid, char *devid, char *bootpath, * 0 - success * ERR_* - failure */ -int +static int check_pool_label(uint64_t sector, char *stack, char *outdevid, - char *outpath, uint64_t *outguid, uint64_t *outashift) + char *outpath, uint64_t *outguid, uint64_t *outashift, uint64_t *outversion) { vdev_phys_t *vdev; uint64_t pool_state, txg = 0; - char *nvlist, *nv; + char *nvlist, *nv, *features; uint64_t diskguid; - uint64_t version; sector += (VDEV_SKIP_SIZE >> SPA_MINBLOCKSHIFT); @@ -1249,10 +1456,10 @@ check_pool_label(uint64_t sector, char *stack, char *outdevid, if (txg == 0) return (ERR_NO_BOOTPATH); - if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_VERSION, &version, + if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_VERSION, outversion, DATA_TYPE_UINT64, NULL)) return (ERR_FSYS_CORRUPT); - if (version > SPA_VERSION) + if (!SPA_VERSION_IS_SUPPORTED(*outversion)) return (ERR_NEWER_VERSION); if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_VDEV_TREE, &nv, DATA_TYPE_NVLIST, NULL)) @@ -1268,6 +1475,30 @@ check_pool_label(uint64_t sector, char *stack, char *outdevid, if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_POOL_GUID, outguid, DATA_TYPE_UINT64, NULL)) return (ERR_FSYS_CORRUPT); + + if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_FEATURES_FOR_READ, + &features, DATA_TYPE_NVLIST, NULL) == 0) { + char *nvp; + char *name = stack; + stack += MAXNAMELEN; + + for (nvp = nvlist_next_nvpair(features, NULL); + nvp != NULL; + nvp = nvlist_next_nvpair(features, nvp)) { + zap_attribute_t za; + + if (nvpair_name(nvp, name, MAXNAMELEN) != 0) + return (ERR_FSYS_CORRUPT); + + za.za_integer_length = 8; + za.za_num_integers = 1; + za.za_first_integer = 1; + za.za_name = name; + if (check_feature(&za, spa_feature_names, stack) != 0) + return (ERR_NEWER_VERSION); + } + } + return (0); } @@ -1288,7 +1519,7 @@ zfs_mount(void) objset_phys_t *osp; char tmp_bootpath[MAXNAMELEN]; char tmp_devid[MAXNAMELEN]; - uint64_t tmp_guid, ashift; + uint64_t tmp_guid, ashift, version; uint64_t adjpl = (uint64_t)part_length << SPA_MINBLOCKSHIFT; int err = errnum; /* preserve previous errnum state */ @@ -1331,7 +1562,7 @@ zfs_mount(void) continue; if (check_pool_label(sector, stack, tmp_devid, - tmp_bootpath, &tmp_guid, &ashift)) + tmp_bootpath, &tmp_guid, &ashift, &version)) continue; if (pool_guid == 0) @@ -1343,6 +1574,10 @@ zfs_mount(void) VERIFY_OS_TYPE(osp, DMU_OST_META); + if (version >= SPA_VERSION_FEATURES && + check_mos_features(&osp->os_meta_dnode, stack) != 0) + continue; + if (find_best_root && ((pool_guid != tmp_guid) || vdev_uberblock_compare(ubbest, &(current_uberblock)) <= 0)) continue; @@ -1479,7 +1714,6 @@ int zfs_read(char *buf, int len) { char *stack; - char *tmpbuf; int blksz, length, movesize; if (file_buf == NULL) { diff --git a/usr/src/grub/grub-0.97/stage2/fsys_zfs.h b/usr/src/grub/grub-0.97/stage2/fsys_zfs.h index b0fdc6e2e9..11236c33de 100644 --- a/usr/src/grub/grub-0.97/stage2/fsys_zfs.h +++ b/usr/src/grub/grub-0.97/stage2/fsys_zfs.h @@ -16,10 +16,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ + +/* + * Copyright (c) 2012 by Delphix. All rights reserved. + */ + #ifndef _FSYS_ZFS_H #define _FSYS_ZFS_H @@ -119,10 +125,36 @@ typedef struct uberblock uberblock_t; #define NV_ENCODE_NATIVE 0 #define NV_ENCODE_XDR 1 #define HOST_ENDIAN 1 /* for x86 machine */ -#define DATA_TYPE_UINT64 8 -#define DATA_TYPE_STRING 9 -#define DATA_TYPE_NVLIST 19 -#define DATA_TYPE_NVLIST_ARRAY 20 +typedef enum { + DATA_TYPE_UNKNOWN = 0, + DATA_TYPE_BOOLEAN, + DATA_TYPE_BYTE, + DATA_TYPE_INT16, + DATA_TYPE_UINT16, + DATA_TYPE_INT32, + DATA_TYPE_UINT32, + DATA_TYPE_INT64, + DATA_TYPE_UINT64, + DATA_TYPE_STRING, + DATA_TYPE_BYTE_ARRAY, + DATA_TYPE_INT16_ARRAY, + DATA_TYPE_UINT16_ARRAY, + DATA_TYPE_INT32_ARRAY, + DATA_TYPE_UINT32_ARRAY, + DATA_TYPE_INT64_ARRAY, + DATA_TYPE_UINT64_ARRAY, + DATA_TYPE_STRING_ARRAY, + DATA_TYPE_HRTIME, + DATA_TYPE_NVLIST, + DATA_TYPE_NVLIST_ARRAY, + DATA_TYPE_BOOLEAN_VALUE, + DATA_TYPE_INT8, + DATA_TYPE_UINT8, + DATA_TYPE_BOOLEAN_ARRAY, + DATA_TYPE_INT8_ARRAY, + DATA_TYPE_UINT8_ARRAY, + DATA_TYPE_DOUBLE +} data_type_t; /* * Decompression Entry - lzjb diff --git a/usr/src/grub/grub-0.97/stage2/zfs-include/dmu.h b/usr/src/grub/grub-0.97/stage2/zfs-include/dmu.h index 7faa7088b5..0e88a8fcde 100644 --- a/usr/src/grub/grub-0.97/stage2/zfs-include/dmu.h +++ b/usr/src/grub/grub-0.97/stage2/zfs-include/dmu.h @@ -16,11 +16,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2012 by Delphix. All rights reserved. + */ + #ifndef _SYS_DMU_H #define _SYS_DMU_H @@ -31,6 +36,41 @@ * The DMU also interacts with the SPA. That interface is described in * dmu_spa.h. */ + +#define B_FALSE 0 +#define B_TRUE 1 + +#define DMU_OT_NEWTYPE 0x80 +#define DMU_OT_METADATA 0x40 +#define DMU_OT_BYTESWAP_MASK 0x3f + +#define DMU_OT(byteswap, metadata) \ + (DMU_OT_NEWTYPE | \ + ((metadata) ? DMU_OT_METADATA : 0) | \ + ((byteswap) & DMU_OT_BYTESWAP_MASK)) + +#define DMU_OT_IS_VALID(ot) (((ot) & DMU_OT_NEWTYPE) ? \ + ((ot) & DMU_OT_BYTESWAP_MASK) < DMU_BSWAP_NUMFUNCS : \ + (ot) < DMU_OT_NUMTYPES) + +#define DMU_OT_IS_METADATA(ot) (((ot) & DMU_OT_NEWTYPE) ? \ + ((ot) & DMU_OT_METADATA) : \ + dmu_ot[(ot)].ot_metadata) + +typedef enum dmu_object_byteswap { + DMU_BSWAP_UINT8, + DMU_BSWAP_UINT16, + DMU_BSWAP_UINT32, + DMU_BSWAP_UINT64, + DMU_BSWAP_ZAP, + DMU_BSWAP_DNODE, + DMU_BSWAP_OBJSET, + DMU_BSWAP_ZNODE, + DMU_BSWAP_OLDACL, + DMU_BSWAP_ACL, + DMU_BSWAP_NUMFUNCS +} dmu_object_byteswap_t; + typedef enum dmu_object_type { DMU_OT_NONE, /* general: */ @@ -38,8 +78,8 @@ typedef enum dmu_object_type { DMU_OT_OBJECT_ARRAY, /* UINT64 */ DMU_OT_PACKED_NVLIST, /* UINT8 (XDR by nvlist_pack/unpack) */ DMU_OT_PACKED_NVLIST_SIZE, /* UINT64 */ - DMU_OT_BPLIST, /* UINT64 */ - DMU_OT_BPLIST_HDR, /* UINT64 */ + DMU_OT_BPOBJ, /* UINT64 */ + DMU_OT_BPOBJ_HDR, /* UINT64 */ /* spa: */ DMU_OT_SPACE_MAP_HEADER, /* UINT64 */ DMU_OT_SPACE_MAP, /* UINT64 */ @@ -56,7 +96,7 @@ typedef enum dmu_object_type { DMU_OT_DSL_DATASET, /* UINT64 */ /* zpl: */ DMU_OT_ZNODE, /* ZNODE */ - DMU_OT_OLDACL, /* OLD ACL */ + DMU_OT_OLDACL, /* Old ACL */ DMU_OT_PLAIN_FILE_CONTENTS, /* UINT8 */ DMU_OT_DIRECTORY_CONTENTS, /* ZAP */ DMU_OT_MASTER_NODE, /* ZAP */ @@ -79,7 +119,7 @@ typedef enum dmu_object_type { DMU_OT_FUID, /* FUID table (Packed NVLIST UINT8) */ DMU_OT_FUID_SIZE, /* FUID table size UINT64 */ DMU_OT_NEXT_CLONES, /* ZAP */ - DMU_OT_SCRUB_QUEUE, /* ZAP */ + DMU_OT_SCAN_QUEUE, /* ZAP */ DMU_OT_USERGROUP_USED, /* ZAP */ DMU_OT_USERGROUP_QUOTA, /* ZAP */ DMU_OT_USERREFS, /* ZAP */ @@ -89,7 +129,24 @@ typedef enum dmu_object_type { DMU_OT_SA_MASTER_NODE, /* ZAP */ DMU_OT_SA_ATTR_REGISTRATION, /* ZAP */ DMU_OT_SA_ATTR_LAYOUTS, /* ZAP */ - DMU_OT_NUMTYPES + DMU_OT_SCAN_XLATE, /* ZAP */ + DMU_OT_DEDUP, /* fake dedup BP from ddt_bp_create() */ + DMU_OT_DEADLIST, /* ZAP */ + DMU_OT_DEADLIST_HDR, /* UINT64 */ + DMU_OT_DSL_CLONES, /* ZAP */ + DMU_OT_BPOBJ_SUBOBJ, /* UINT64 */ + DMU_OT_NUMTYPES, + + DMU_OTN_UINT8_DATA = DMU_OT(DMU_BSWAP_UINT8, B_FALSE), + DMU_OTN_UINT8_METADATA = DMU_OT(DMU_BSWAP_UINT8, B_TRUE), + DMU_OTN_UINT16_DATA = DMU_OT(DMU_BSWAP_UINT16, B_FALSE), + DMU_OTN_UINT16_METADATA = DMU_OT(DMU_BSWAP_UINT16, B_TRUE), + DMU_OTN_UINT32_DATA = DMU_OT(DMU_BSWAP_UINT32, B_FALSE), + DMU_OTN_UINT32_METADATA = DMU_OT(DMU_BSWAP_UINT32, B_TRUE), + DMU_OTN_UINT64_DATA = DMU_OT(DMU_BSWAP_UINT64, B_FALSE), + DMU_OTN_UINT64_METADATA = DMU_OT(DMU_BSWAP_UINT64, B_TRUE), + DMU_OTN_ZAP_DATA = DMU_OT(DMU_BSWAP_ZAP, B_FALSE), + DMU_OTN_ZAP_METADATA = DMU_OT(DMU_BSWAP_ZAP, B_TRUE), } dmu_object_type_t; typedef enum dmu_objset_type { @@ -107,6 +164,9 @@ typedef enum dmu_objset_type { */ #define DMU_POOL_DIRECTORY_OBJECT 1 #define DMU_POOL_CONFIG "config" +#define DMU_POOL_FEATURES_FOR_READ "features_for_read" +#define DMU_POOL_FEATURES_FOR_WRITE "features_for_write" +#define DMU_POOL_FEATURE_DESCRIPTIONS "feature_descriptions" #define DMU_POOL_ROOT_DATASET "root_dataset" #define DMU_POOL_SYNC_BPLIST "sync_bplist" #define DMU_POOL_ERRLOG_SCRUB "errlog_scrub" diff --git a/usr/src/grub/grub-0.97/stage2/zfs-include/spa.h b/usr/src/grub/grub-0.97/stage2/zfs-include/spa.h index 4c943310dc..4cb53c2d51 100644 --- a/usr/src/grub/grub-0.97/stage2/zfs-include/spa.h +++ b/usr/src/grub/grub-0.97/stage2/zfs-include/spa.h @@ -16,11 +16,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2012 by Delphix. All rights reserved. + */ + #ifndef _SYS_SPA_H #define _SYS_SPA_H @@ -65,7 +70,7 @@ /* * Size of block to hold the configuration data (a packed nvlist) */ -#define SPA_CONFIG_BLOCKSIZE (1 << 14) +#define SPA_CONFIG_BLOCKSIZE (1ULL << 14) /* * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB. diff --git a/usr/src/grub/grub-0.97/stage2/zfs-include/zfs.h b/usr/src/grub/grub-0.97/stage2/zfs-include/zfs.h index 9ad1367ed3..7180d8a515 100644 --- a/usr/src/grub/grub-0.97/stage2/zfs-include/zfs.h +++ b/usr/src/grub/grub-0.97/stage2/zfs-include/zfs.h @@ -16,8 +16,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #ifndef _SYS_FS_ZFS_H @@ -26,7 +28,14 @@ /* * On-disk version number. */ -#define SPA_VERSION 28ULL +#define SPA_VERSION_INITIAL 1ULL +#define SPA_VERSION_BEFORE_FEATURES 28ULL +#define SPA_VERSION 5000ULL +#define SPA_VERSION_FEATURES 5000ULL + +#define SPA_VERSION_IS_SUPPORTED(v) \ + (((v) >= SPA_VERSION_INITIAL && (v) <= SPA_VERSION_BEFORE_FEATURES) || \ + ((v) >= SPA_VERSION_FEATURES && (v) <= SPA_VERSION)) /* * The following are configuration names used in the nvlist describing a pool's @@ -66,6 +75,7 @@ #define ZPOOL_CONFIG_DDT_HISTOGRAM "ddt_histogram" #define ZPOOL_CONFIG_DDT_OBJ_STATS "ddt_object_stats" #define ZPOOL_CONFIG_DDT_STATS "ddt_stats" +#define ZPOOL_CONFIG_FEATURES_FOR_READ "features_for_read" /* * The persistent vdev state is stored as separate values rather than a single * 'vdev_state' entry. This is because a device can be in multiple states, such |