diff options
| author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2019-11-26 12:25:31 +0000 |
|---|---|---|
| committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2019-11-26 12:25:31 +0000 |
| commit | a0fae2e039f343951fa97d02c576ee3d45c877d1 (patch) | |
| tree | 368950193f69019c430d784134b81fde3feed62a /usr/src | |
| parent | 70102ef7b7b71b21e8fae6172bf09af8d95c02f2 (diff) | |
| parent | a629ded1d7b2e67c2028ccbc5ba9099328cc4e1b (diff) | |
| download | illumos-joyent-a0fae2e039f343951fa97d02c576ee3d45c877d1.tar.gz | |
[illumos-gate merge]
commit a629ded1d7b2e67c2028ccbc5ba9099328cc4e1b
11962 Port ZoL zfs diff tests to illumos
commit 32a71e42b5b15681007be8f91ac790b320b74d43
11993 format: reserved partition size calculation should use sector size
commit 32114f8806363681160c9505a0dfa90331e8579d
12012 zdb: do not output binary org.illumos:checksum_salt on terminal
commit 93d2b6f25d9da54278148dfd3d9a33ff2827016e
11938 loader.efi: HARDDRIVE_DEVICE_PATH may have subpaths
commit 247e9a8ed695b16d62e2a0cb581e5c07d949d5ae
12009 Memory leaks in blkdev when blkdev device is detached
commit eb44bcc7bc940d7cc1f4c10afa5a1cb7ec0dd198
12013 fix smatch build for GCC4
Diffstat (limited to 'usr/src')
30 files changed, 849 insertions, 134 deletions
diff --git a/usr/src/boot/sys/boot/efi/libefi/efipart.c b/usr/src/boot/sys/boot/efi/libefi/efipart.c index 87fcee95a5..65870cfc7a 100644 --- a/usr/src/boot/sys/boot/efi/libefi/efipart.c +++ b/usr/src/boot/sys/boot/efi/libefi/efipart.c @@ -299,11 +299,14 @@ efipart_floppy(EFI_DEVICE_PATH *node) static pdinfo_t * efipart_find_parent(pdinfo_list_t *pdi, EFI_DEVICE_PATH *devpath) { - pdinfo_t *pd; + pdinfo_t *pd, *part; STAILQ_FOREACH(pd, pdi, pd_link) { if (efi_devpath_is_prefix(pd->pd_devpath, devpath)) return (pd); + part = efipart_find_parent(&pd->pd_part, devpath); + if (part != NULL) + return (part); } return (NULL); } @@ -486,22 +489,65 @@ efipart_initcd(void) return (0); } -static void -efipart_hdinfo_add(pdinfo_t *hd, HARDDRIVE_DEVICE_PATH *node) +static bool +efipart_hdinfo_add_node(pdinfo_t *hd, EFI_DEVICE_PATH *node) { - pdinfo_t *pd, *last; + pdinfo_t *pd, *ptr; + if (node == NULL) + return (false); + + /* Find our disk device. */ STAILQ_FOREACH(pd, &hdinfo, pd_link) { - if (efi_devpath_is_prefix(pd->pd_devpath, hd->pd_devpath)) { - /* Add the partition. */ - hd->pd_unit = node->PartitionNumber; - hd->pd_parent = pd; - hd->pd_devsw = &efipart_hddev; - STAILQ_INSERT_TAIL(&pd->pd_part, hd, pd_link); - return; + if (efi_devpath_is_prefix(pd->pd_devpath, hd->pd_devpath)) + break; + } + if (pd == NULL) + return (false); + + /* If the node is not MEDIA_HARDDRIVE_DP, it is sub-partition. */ + if (DevicePathSubType(node) != MEDIA_HARDDRIVE_DP) { + STAILQ_FOREACH(ptr, &pd->pd_part, pd_link) { + if (efi_devpath_is_prefix(ptr->pd_devpath, + hd->pd_devpath)) + break; } + /* + * If we don't find a pdinfo_t for this node, then that + * means that the partition list we got from firmware isn't + * properly ordered. We assume that firmware has ordered it. + * In case we don't find anything, rather than blow up, we + * add this node as another partition. + */ + if (ptr != NULL) + pd = ptr; + + /* Add the partition. */ + ptr = STAILQ_LAST(&pd->pd_part, pdinfo, pd_link); + if (ptr != NULL) + hd->pd_unit = ptr->pd_unit + 1; + else + hd->pd_unit = 0; + } else { + /* Add the partition. */ + hd->pd_unit = ((HARDDRIVE_DEVICE_PATH *)node)->PartitionNumber; } + hd->pd_parent = pd; + hd->pd_devsw = &efipart_hddev; + + STAILQ_INSERT_TAIL(&pd->pd_part, hd, pd_link); + return (true); +} + +static void +efipart_hdinfo_add(pdinfo_t *hd, EFI_DEVICE_PATH *node) +{ + pdinfo_t *last; + + if (efipart_hdinfo_add_node(hd, node)) + return; + last = STAILQ_LAST(&hdinfo, pdinfo, pd_link); if (last != NULL) hd->pd_unit = last->pd_unit + 1; @@ -663,7 +709,7 @@ restart: efipart_hdinfo_add(parent, NULL); } - efipart_hdinfo_add(hd, (HARDDRIVE_DEVICE_PATH *)node); + efipart_hdinfo_add(hd, node); goto restart; } } diff --git a/usr/src/cmd/format/auto_sense.c b/usr/src/cmd/format/auto_sense.c index 6d51a72414..eefb43809e 100644 --- a/usr/src/cmd/format/auto_sense.c +++ b/usr/src/cmd/format/auto_sense.c @@ -226,7 +226,7 @@ static char *strcopy( int n); static int adjust_disk_geometry(diskaddr_t capacity, uint_t *cyl, uint_t *nsect, uint_t *nhead); -static void compute_chs_values(diskaddr_t total_capacity, +static void compute_chs_values(diskaddr_t total_capacity, diskaddr_t usable_capacity, uint_t *pcylp, uint_t *nheadp, uint_t *nsectp); #if defined(_SUNOS_VTOC_8) @@ -254,6 +254,7 @@ auto_efi_sense(int fd, struct efi_info *label) struct ctlr_info *ctlr; struct dk_cinfo dkinfo; struct partition_info *part; + uint64_t reserved; if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) { if (option_msg && diag_msg) { @@ -286,6 +287,7 @@ auto_efi_sense(int fd, struct efi_info *label) } label->e_parts = vtoc; + reserved = efi_reserved_sectors(vtoc); /* * Create a whole hog EFI partition table: @@ -295,7 +297,7 @@ auto_efi_sense(int fd, struct efi_info *label) vtoc->efi_parts[0].p_tag = V_USR; vtoc->efi_parts[0].p_start = vtoc->efi_first_u_lba; vtoc->efi_parts[0].p_size = vtoc->efi_last_u_lba - vtoc->efi_first_u_lba - - EFI_MIN_RESV_SIZE + 1; + - reserved + 1; /* * S1-S6 are unassigned slices. @@ -311,8 +313,8 @@ auto_efi_sense(int fd, struct efi_info *label) */ vtoc->efi_parts[vtoc->efi_nparts - 1].p_tag = V_RESERVED; vtoc->efi_parts[vtoc->efi_nparts - 1].p_start = - vtoc->efi_last_u_lba - EFI_MIN_RESV_SIZE + 1; - vtoc->efi_parts[vtoc->efi_nparts - 1].p_size = EFI_MIN_RESV_SIZE; + vtoc->efi_last_u_lba - reserved + 1; + vtoc->efi_parts[vtoc->efi_nparts - 1].p_size = reserved; /* * Now stick all of it into the disk_type struct @@ -462,7 +464,7 @@ auto_label_init(struct dk_label *label) efi_gpt_t *databack = NULL; struct dk_geom disk_geom; struct dk_minfo disk_info; - efi_gpt_t *backsigp; + efi_gpt_t *backsigp; int fd = cur_file; int rval = -1; int efisize = EFI_LABEL_SIZE * 2; @@ -2190,7 +2192,7 @@ square_box( } if (((*dim1) > lim1) || ((*dim2) > lim2) || ((*dim3) > lim3)) { - double d[4]; + double d[4]; /* * Second: @@ -2269,15 +2271,15 @@ compute_chs_values(diskaddr_t total_capacity, diskaddr_t usable_capacity, * The following table (in order) illustrates some end result * calculations: * - * Maximum number of blocks nhead nsect + * Maximum number of blocks nhead nsect * * 2097152 (1GB) 64 32 * 16777216 (8GB) 128 32 - * 1052819775 (502.02GB) 255 63 + * 1052819775 (502.02GB) 255 63 * 2105639550 (0.98TB) 255 126 - * 3158459325 (1.47TB) 255 189 - * 4211279100 (1.96TB) 255 252 - * 5264098875 (2.45TB) 255 315 + * 3158459325 (1.47TB) 255 189 + * 4211279100 (1.96TB) 255 252 + * 5264098875 (2.45TB) 255 315 * ... */ diff --git a/usr/src/cmd/format/io.c b/usr/src/cmd/format/io.c index 7fd8baf6bc..d0953a59d6 100644 --- a/usr/src/cmd/format/io.c +++ b/usr/src/cmd/format/io.c @@ -38,6 +38,7 @@ #include <sys/tty.h> #include <sys/termio.h> #include <sys/termios.h> +#include <sys/efi_partition.h> #include "startup.h" #include "misc.h" @@ -1556,7 +1557,10 @@ or g(gigabytes)\n"); * either blocks/cyls/megabytes - a convenient fiction. */ if (strcmp(cleantoken, WILD_STRING) == 0) { - return (bounds->upper - EFI_MIN_RESV_SIZE - + uint64_t reserved; + + reserved = efi_reserved_sectors(cur_parts->etoc); + return (bounds->upper - reserved - efi_deflt->start_sector); } diff --git a/usr/src/cmd/format/label.c b/usr/src/cmd/format/label.c index f4fde20d68..ac0bbd066a 100644 --- a/usr/src/cmd/format/label.c +++ b/usr/src/cmd/format/label.c @@ -55,40 +55,22 @@ #define WD_NODE 7 #endif -#ifdef __STDC__ -/* - * Prototypes for ANSI C compilers - */ static int do_geometry_sanity_check(void); -static int vtoc_to_label(struct dk_label *label, struct extvtoc *vtoc, - struct dk_geom *geom, struct dk_cinfo *cinfo); +static int vtoc_to_label(struct dk_label *, struct extvtoc *, + struct dk_geom *, struct dk_cinfo *); extern int read_extvtoc(int, struct extvtoc *); extern int write_extvtoc(int, struct extvtoc *); static int vtoc64_to_label(struct efi_info *, struct dk_gpt *); -#else /* __STDC__ */ - -/* - * Prototypes for non-ANSI C compilers - */ -static int do_geometry_sanity_check(); -static int vtoc_to_label(); -extern int read_extvtoc(); -extern int write_extvtoc(); -static int vtoc64_to_label(); - -#endif /* __STDC__ */ - #ifdef DEBUG -static void dump_label(struct dk_label *label); +static void dump_label(struct dk_label *); #endif /* * This routine checks the given label to see if it is valid. */ int -checklabel(label) - register struct dk_label *label; +checklabel(struct dk_label *label) { /* @@ -109,12 +91,10 @@ checklabel(label) * the mode it is called in. */ int -checksum(label, mode) - struct dk_label *label; - int mode; +checksum(struct dk_label *label, int mode) { - register short *sp, sum = 0; - register short count = (sizeof (struct dk_label)) / (sizeof (short)); + short *sp, sum = 0; + short count = (sizeof (struct dk_label)) / (sizeof (short)); /* * If we are generating a checksum, don't include the checksum @@ -152,10 +132,9 @@ checksum(label, mode) * and truncate it there. */ int -trim_id(id) - char *id; +trim_id(char *id) { - register char *c; + char *c; /* * Start at the end of the string. When we match the word ' cyl', @@ -167,7 +146,8 @@ trim_id(id) * Remove any white space. */ for (; (((*(c - 1) == ' ') || (*(c - 1) == '\t')) && - (c >= id)); c--); + (c >= id)); c--) + ; break; } } @@ -222,13 +202,15 @@ int SMI_vtoc_to_EFI(int fd, struct dk_gpt **new_vtoc) { int i; - struct dk_gpt *efi; + struct dk_gpt *efi; + uint64_t reserved; if (efi_alloc_and_init(fd, EFI_NUMPAR, new_vtoc) != 0) { err_print("SMI vtoc to EFI failed\n"); return (-1); } efi = *new_vtoc; + reserved = efi_reserved_sectors(efi); /* * create a clear EFI partition table: @@ -239,7 +221,7 @@ SMI_vtoc_to_EFI(int fd, struct dk_gpt **new_vtoc) efi->efi_parts[0].p_tag = V_USR; efi->efi_parts[0].p_start = efi->efi_first_u_lba; efi->efi_parts[0].p_size = efi->efi_last_u_lba - efi->efi_first_u_lba - - EFI_MIN_RESV_SIZE + 1; + - reserved + 1; /* * s1-s6 are unassigned slices @@ -255,8 +237,8 @@ SMI_vtoc_to_EFI(int fd, struct dk_gpt **new_vtoc) */ efi->efi_parts[efi->efi_nparts - 1].p_tag = V_RESERVED; efi->efi_parts[efi->efi_nparts - 1].p_start = - efi->efi_last_u_lba - EFI_MIN_RESV_SIZE + 1; - efi->efi_parts[efi->efi_nparts - 1].p_size = EFI_MIN_RESV_SIZE; + efi->efi_last_u_lba - reserved + 1; + efi->efi_parts[efi->efi_nparts - 1].p_size = reserved; return (0); } @@ -1001,14 +983,16 @@ is_efi_type(int fd) void err_check(struct dk_gpt *vtoc) { - int resv_part = -1; - int i, j; - diskaddr_t istart, jstart, isize, jsize, endsect; - int overlap = 0; + int resv_part = -1; + int i, j; + diskaddr_t istart, jstart, isize, jsize, endsect; + int overlap = 0; + uint_t reserved; /* * make sure no partitions overlap */ + reserved = efi_reserved_sectors(vtoc); for (i = 0; i < vtoc->efi_nparts; i++) { /* It can't be unassigned and have an actual size */ if ((vtoc->efi_parts[i].p_tag == V_UNASSIGNED) && @@ -1026,10 +1010,10 @@ err_check(struct dk_gpt *vtoc) "found duplicate reserved partition at %d\n", i); } resv_part = i; - if (vtoc->efi_parts[i].p_size != EFI_MIN_RESV_SIZE) + if (vtoc->efi_parts[i].p_size != reserved) (void) fprintf(stderr, -"Warning: reserved partition size must be %d sectors\n", - EFI_MIN_RESV_SIZE); +"Warning: reserved partition size must be %u sectors\n", + reserved); } if ((vtoc->efi_parts[i].p_start < vtoc->efi_first_u_lba) || (vtoc->efi_parts[i].p_start > vtoc->efi_last_u_lba)) { @@ -1088,8 +1072,7 @@ err_check(struct dk_gpt *vtoc) #ifdef DEBUG static void -dump_label(label) - struct dk_label *label; +dump_label(struct dk_label *label) { int i; @@ -1141,8 +1124,8 @@ dump_label(label) #if defined(_SUNOS_VTOC_8) fmt_print("%c: cyl=%d, blocks=%d", i+'a', - label->dkl_map[i].dkl_cylno, - label->dkl_map[i].dkl_nblk); + label->dkl_map[i].dkl_cylno, + label->dkl_map[i].dkl_nblk); #elif defined(_SUNOS_VTOC_16) fmt_print("%c: start=%u, blocks=%u", i+'a', @@ -1153,8 +1136,8 @@ dump_label(label) #endif /* defined(_SUNOS_VTOC_8) */ fmt_print(", tag=%d, flag=%d", - label->dkl_vtoc.v_part[i].p_tag, - label->dkl_vtoc.v_part[i].p_flag); + label->dkl_vtoc.v_part[i].p_tag, + label->dkl_vtoc.v_part[i].p_flag); fmt_print("\n"); } diff --git a/usr/src/cmd/format/menu_command.c b/usr/src/cmd/format/menu_command.c index 031c94e70d..18836ecfc2 100644 --- a/usr/src/cmd/format/menu_command.c +++ b/usr/src/cmd/format/menu_command.c @@ -575,7 +575,9 @@ c_type() new_partitiontable(tptr, oldtype); } else if ((index == other_choice) && (cur_label == L_TYPE_EFI)) { uint64_t start_lba = cur_parts->etoc->efi_first_u_lba; + uint64_t reserved; + reserved = efi_reserved_sectors(cur_parts->etoc); maxLBA = get_mlba(); cur_parts->etoc->efi_last_lba = maxLBA; cur_parts->etoc->efi_last_u_lba = maxLBA - start_lba; @@ -585,8 +587,8 @@ c_type() cur_parts->etoc->efi_parts[i].p_tag = V_UNASSIGNED; } cur_parts->etoc->efi_parts[8].p_start = - maxLBA - start_lba - (1024 * 16); - cur_parts->etoc->efi_parts[8].p_size = (1024 * 16); + maxLBA - start_lba - reserved; + cur_parts->etoc->efi_parts[8].p_size = reserved; cur_parts->etoc->efi_parts[8].p_tag = V_RESERVED; if (write_label()) { err_print("Write label failed\n"); diff --git a/usr/src/cmd/format/menu_partition.c b/usr/src/cmd/format/menu_partition.c index b228821beb..444d4f585d 100644 --- a/usr/src/cmd/format/menu_partition.c +++ b/usr/src/cmd/format/menu_partition.c @@ -380,7 +380,7 @@ p_name() * for all the partitions in the current partition map. */ int -p_print() +p_print(void) { /* * check if there exists a partition table for the disk. @@ -411,13 +411,16 @@ p_print() fmt_print("Total disk cylinders available: %d + %d " "(reserved cylinders)\n\n", ncyl, acyl); } else if (cur_label == L_TYPE_EFI) { + unsigned reserved; + + reserved = efi_reserved_sectors(cur_parts->etoc); fmt_print("Current partition table (%s):\n", cur_parts->pinfo_name != NULL ? cur_parts->pinfo_name : "unnamed"); - fmt_print("Total disk sectors available: %llu + %d " + fmt_print("Total disk sectors available: %llu + %u " "(reserved sectors)\n\n", - cur_parts->etoc->efi_last_u_lba - EFI_MIN_RESV_SIZE - - cur_parts->etoc->efi_first_u_lba + 1, EFI_MIN_RESV_SIZE); + cur_parts->etoc->efi_last_u_lba - reserved - + cur_parts->etoc->efi_first_u_lba + 1, reserved); } diff --git a/usr/src/cmd/format/modify_partition.c b/usr/src/cmd/format/modify_partition.c index 23ea44a971..d01463e757 100644 --- a/usr/src/cmd/format/modify_partition.c +++ b/usr/src/cmd/format/modify_partition.c @@ -560,53 +560,53 @@ get_user_map_efi(map, float_part) char tmpstr[80]; uint64_t i64; uint64_t start_lba = map->efi_first_u_lba; + uint64_t reserved; + reserved = efi_reserved_sectors(map); for (i = 0; i < map->efi_nparts - 1; i++) { if (i == float_part) continue; - else { - ioparam.io_bounds.lower = start_lba; - ioparam.io_bounds.upper = map->efi_last_u_lba; - efi_deflt.start_sector = ioparam.io_bounds.lower; - efi_deflt.end_sector = map->efi_parts[i].p_size; - (void) sprintf(tmpstr, - "Enter size of partition %d ", i); - i64 = input(FIO_EFI, tmpstr, ':', - &ioparam, (int *)&efi_deflt, DATA_INPUT); - if (i64 == 0) { - map->efi_parts[i].p_tag = V_UNASSIGNED; - } else if ((i64 != 0) && (map->efi_parts[i].p_tag == - V_UNASSIGNED)) { - map->efi_parts[i].p_tag = V_USR; - } - if (i64 == 0) { - map->efi_parts[i].p_start = 0; - } else { - map->efi_parts[i].p_start = start_lba; - } - map->efi_parts[i].p_size = i64; - start_lba += i64; + + ioparam.io_bounds.lower = start_lba; + ioparam.io_bounds.upper = map->efi_last_u_lba; + efi_deflt.start_sector = ioparam.io_bounds.lower; + efi_deflt.end_sector = map->efi_parts[i].p_size; + (void) sprintf(tmpstr, "Enter size of partition %d ", i); + i64 = input(FIO_EFI, tmpstr, ':', + &ioparam, (int *)&efi_deflt, DATA_INPUT); + if (i64 == 0) { + map->efi_parts[i].p_tag = V_UNASSIGNED; + } else if ((i64 != 0) && (map->efi_parts[i].p_tag == + V_UNASSIGNED)) { + map->efi_parts[i].p_tag = V_USR; } - } - map->efi_parts[float_part].p_start = start_lba; - map->efi_parts[float_part].p_size = map->efi_last_u_lba - - start_lba - (1024 * 16); - map->efi_parts[float_part].p_tag = V_USR; - if (map->efi_parts[float_part].p_size == UINT_MAX64) { - map->efi_parts[float_part].p_size = 0; - map->efi_parts[float_part].p_start = 0; - map->efi_parts[float_part].p_tag = V_UNASSIGNED; - fmt_print("Warning: No space left for HOG\n"); + if (i64 == 0) { + map->efi_parts[i].p_start = 0; + } else { + map->efi_parts[i].p_start = start_lba; } + map->efi_parts[i].p_size = i64; + start_lba += i64; + } + map->efi_parts[float_part].p_start = start_lba; + map->efi_parts[float_part].p_size = map->efi_last_u_lba - + start_lba - reserved; + map->efi_parts[float_part].p_tag = V_USR; + if (map->efi_parts[float_part].p_size == UINT_MAX64) { + map->efi_parts[float_part].p_size = 0; + map->efi_parts[float_part].p_start = 0; + map->efi_parts[float_part].p_tag = V_UNASSIGNED; + fmt_print("Warning: No space left for HOG\n"); + } - for (i = 0; i < map->efi_nparts; i++) { - if (map->efi_parts[i].p_tag == V_RESERVED) { + for (i = 0; i < map->efi_nparts; i++) { + if (map->efi_parts[i].p_tag == V_RESERVED) { map->efi_parts[i].p_start = map->efi_last_u_lba - - (1024 * 16); - map->efi_parts[i].p_size = (1024 * 16); + reserved; + map->efi_parts[i].p_size = reserved; break; - } } + } } diff --git a/usr/src/cmd/zdb/zdb.c b/usr/src/cmd/zdb/zdb.c index 61cfd74df3..22d6a96b49 100644 --- a/usr/src/cmd/zdb/zdb.c +++ b/usr/src/cmd/zdb/zdb.c @@ -448,7 +448,8 @@ dump_zap(objset_t *os, uint64_t object, void *data, size_t size) strcmp(attr.za_name, DSL_CRYPTO_KEY_HMAC_KEY) == 0 || strcmp(attr.za_name, DSL_CRYPTO_KEY_IV) == 0 || - strcmp(attr.za_name, DSL_CRYPTO_KEY_MAC) == 0) { + strcmp(attr.za_name, DSL_CRYPTO_KEY_MAC) == 0 || + strcmp(attr.za_name, DMU_POOL_CHECKSUM_SALT) == 0) { uint8_t *u8 = prop; for (i = 0; i < attr.za_num_integers; i++) { diff --git a/usr/src/pkg/manifests/system-test-zfstest.mf b/usr/src/pkg/manifests/system-test-zfstest.mf index e1cbd0ca10..f5d7d5d07d 100644 --- a/usr/src/pkg/manifests/system-test-zfstest.mf +++ b/usr/src/pkg/manifests/system-test-zfstest.mf @@ -53,6 +53,7 @@ dir path=opt/zfs-tests/tests/functional/cli_root/zfs_clone dir path=opt/zfs-tests/tests/functional/cli_root/zfs_copies dir path=opt/zfs-tests/tests/functional/cli_root/zfs_create dir path=opt/zfs-tests/tests/functional/cli_root/zfs_destroy +dir path=opt/zfs-tests/tests/functional/cli_root/zfs_diff dir path=opt/zfs-tests/tests/functional/cli_root/zfs_get dir path=opt/zfs-tests/tests/functional/cli_root/zfs_inherit dir path=opt/zfs-tests/tests/functional/cli_root/zfs_load-key @@ -893,6 +894,19 @@ file \ file \ path=opt/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_destroy_common.kshlib \ mode=0444 +file path=opt/zfs-tests/tests/functional/cli_root/zfs_diff/cleanup mode=0555 +file path=opt/zfs-tests/tests/functional/cli_root/zfs_diff/setup mode=0555 +file path=opt/zfs-tests/tests/functional/cli_root/zfs_diff/socket mode=0555 +file path=opt/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_changes \ + mode=0555 +file path=opt/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_cliargs \ + mode=0555 +file path=opt/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_encrypted \ + mode=0555 +file path=opt/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_timestamp \ + mode=0555 +file path=opt/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_types \ + mode=0555 file path=opt/zfs-tests/tests/functional/cli_root/zfs_get/cleanup mode=0555 file path=opt/zfs-tests/tests/functional/cli_root/zfs_get/setup mode=0555 file path=opt/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_001_pos \ diff --git a/usr/src/test/zfs-tests/runfiles/delphix.run b/usr/src/test/zfs-tests/runfiles/delphix.run index 4fb467f234..3acbe9e343 100644 --- a/usr/src/test/zfs-tests/runfiles/delphix.run +++ b/usr/src/test/zfs-tests/runfiles/delphix.run @@ -144,6 +144,11 @@ tests = ['zfs_destroy_001_pos', 'zfs_destroy_002_pos', 'zfs_destroy_003_pos', 'zfs_destroy_013_neg', 'zfs_destroy_014_pos', 'zfs_destroy_015_pos', 'zfs_destroy_016_pos'] +[/opt/zfs-tests/tests/functional/cli_root/zfs_diff] +tests = ['zfs_diff_changes', 'zfs_diff_cliargs', 'zfs_diff_timestamp', + 'zfs_diff_types', 'zfs_diff_encrypted'] +tags = ['functional', 'cli_root', 'zfs_diff'] + [/opt/zfs-tests/tests/functional/cli_root/zfs_get] tests = ['zfs_get_001_pos', 'zfs_get_002_pos', 'zfs_get_003_pos', 'zfs_get_004_pos', 'zfs_get_005_neg', 'zfs_get_006_neg', 'zfs_get_007_neg', diff --git a/usr/src/test/zfs-tests/runfiles/omnios.run b/usr/src/test/zfs-tests/runfiles/omnios.run index 3909b0f0bc..d03cbd9a6d 100644 --- a/usr/src/test/zfs-tests/runfiles/omnios.run +++ b/usr/src/test/zfs-tests/runfiles/omnios.run @@ -145,6 +145,11 @@ tests = ['zfs_destroy_001_pos', 'zfs_destroy_002_pos', 'zfs_destroy_003_pos', 'zfs_destroy_013_neg', 'zfs_destroy_014_pos', 'zfs_destroy_015_pos', 'zfs_destroy_016_pos'] +[/opt/zfs-tests/tests/functional/cli_root/zfs_diff] +tests = ['zfs_diff_changes', 'zfs_diff_cliargs', 'zfs_diff_timestamp', + 'zfs_diff_types', 'zfs_diff_encrypted'] +tags = ['functional', 'cli_root', 'zfs_diff'] + [/opt/zfs-tests/tests/functional/cli_root/zfs_get] tests = ['zfs_get_001_pos', 'zfs_get_002_pos', 'zfs_get_003_pos', 'zfs_get_004_pos', 'zfs_get_005_neg', 'zfs_get_006_neg', 'zfs_get_007_neg', diff --git a/usr/src/test/zfs-tests/runfiles/openindiana.run b/usr/src/test/zfs-tests/runfiles/openindiana.run index 7536e22e7f..3c3675b5aa 100644 --- a/usr/src/test/zfs-tests/runfiles/openindiana.run +++ b/usr/src/test/zfs-tests/runfiles/openindiana.run @@ -145,6 +145,11 @@ tests = ['zfs_destroy_001_pos', 'zfs_destroy_002_pos', 'zfs_destroy_003_pos', 'zfs_destroy_013_neg', 'zfs_destroy_014_pos', 'zfs_destroy_015_pos', 'zfs_destroy_016_pos'] +[/opt/zfs-tests/tests/functional/cli_root/zfs_diff] +tests = ['zfs_diff_changes', 'zfs_diff_cliargs', 'zfs_diff_timestamp', + 'zfs_diff_types', 'zfs_diff_encrypted'] +tags = ['functional', 'cli_root', 'zfs_diff'] + [/opt/zfs-tests/tests/functional/cli_root/zfs_get] tests = ['zfs_get_001_pos', 'zfs_get_002_pos', 'zfs_get_003_pos', 'zfs_get_004_pos', 'zfs_get_005_neg', 'zfs_get_006_neg', 'zfs_get_007_neg', diff --git a/usr/src/test/zfs-tests/runfiles/smartos.run b/usr/src/test/zfs-tests/runfiles/smartos.run index 919621f361..8b326b874f 100644 --- a/usr/src/test/zfs-tests/runfiles/smartos.run +++ b/usr/src/test/zfs-tests/runfiles/smartos.run @@ -107,6 +107,11 @@ tests = ['zfs_destroy_001_pos', 'zfs_destroy_002_pos', 'zfs_destroy_003_pos', 'zfs_destroy_013_neg', 'zfs_destroy_014_pos', 'zfs_destroy_015_pos', 'zfs_destroy_016_pos'] +[/opt/zfs-tests/tests/functional/cli_root/zfs_diff] +tests = ['zfs_diff_changes', 'zfs_diff_cliargs', 'zfs_diff_timestamp', + 'zfs_diff_types', 'zfs_diff_encrypted'] +tags = ['functional', 'cli_root', 'zfs_diff'] + [/opt/zfs-tests/tests/functional/cli_root/zfs_get] tests = ['zfs_get_001_pos', 'zfs_get_002_pos', 'zfs_get_003_pos', 'zfs_get_004_pos', 'zfs_get_005_neg', 'zfs_get_006_neg', 'zfs_get_007_neg', diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/Makefile b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/Makefile new file mode 100644 index 0000000000..5088e03386 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/Makefile @@ -0,0 +1,44 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2019 Joyent, Inc. +# + +include $(SRC)/Makefile.master + +ROOTOPTPKG = $(ROOT)/opt/zfs-tests +TARGETDIR = $(ROOTOPTPKG)/tests/functional/cli_root/zfs_diff + +PROG = socket +OBJS = $(PROG:%=%.o) +SRCS = $(OBJS:%.o=%.c) + +include $(SRC)/cmd/Makefile.cmd + +$(TARGETDIR)/$(PROG) := FILEMODE = 0555 + +CPPFLAGS = -D__EXTENSIONS__ +LDLIBS = -lsocket + +$(PROG): $(OBJS) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) + $(POST_PROCESS) + +install: $(TARGETDIR)/$(PROG) + +clobber: clean + -$(RM) $(PROG) + +clean: + -$(RM) $(OBJS) + +include $(SRC)/test/zfs-tests/Makefile.com diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/cleanup.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/cleanup.ksh new file mode 100755 index 0000000000..1adac153d7 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/cleanup.ksh @@ -0,0 +1,19 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +default_cleanup diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/setup.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/setup.ksh new file mode 100755 index 0000000000..e37841addf --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/setup.ksh @@ -0,0 +1,21 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +DISK=${DISKS%% *} + +default_volume_setup $DISK diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/socket.c b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/socket.c new file mode 100644 index 0000000000..deb2f2b38f --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/socket.c @@ -0,0 +1,59 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. + * Copyright 2019 Joyent, Inc. + */ + +#include <fcntl.h> +#include <sys/un.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* ARGSUSED */ +int +main(int argc, char *argv[]) +{ + struct sockaddr_un sock; + int fd; + char *path; + size_t size; + if (argc != 2) { + fprintf(stderr, "usage: %s /path/to/socket\n", argv[0]); + exit(1); + } + path = argv[1]; + size = sizeof (sock.sun_path); + (void) strncpy(sock.sun_path, (char *)path, size - 1); + sock.sun_path[size - 1] = '\0'; + + sock.sun_family = AF_UNIX; + if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) { + perror("socket"); + return (1); + } + if (bind(fd, (struct sockaddr *)&sock, sizeof (struct sockaddr_un))) { + perror("bind"); + return (1); + } + if (close(fd)) { + perror("close"); + return (1); + } + return (0); +} diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_changes.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_changes.ksh new file mode 100755 index 0000000000..e462615efb --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_changes.ksh @@ -0,0 +1,96 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +# +# DESCRIPTION: +# 'zfs diff' should display changes correctly. +# +# STRATEGY: +# 1. Create a filesystem with both files and directories, then snapshot it +# 2. Generate different types of changes and verify 'zfs diff' displays them +# + +verify_runnable "both" + +function cleanup +{ + log_must zfs destroy -r "$DATASET" + rm -f "$FILEDIFF" +} + +# +# Verify object $path has $change type +# Valid types are: +# * - (The path has been removed) +# * + (The path has been created) +# * M (The path has been modified) +# * R (The path has been renamed) +# +function verify_object_change # <path> <change> +{ + path="$1" + change="$2" + + log_must eval "zfs diff -F $TESTSNAP1 $TESTSNAP2 > $FILEDIFF" + diffchg="$(nawk -v path="$path" '$NF == path { print $1 }' < $FILEDIFF)" + if [[ "$diffchg" != "$change" ]]; then + log_fail "Unexpected change for $path ('$diffchg' != '$change')" + else + log_note "Object $path change is displayed correctly: '$change'" + fi +} + +log_assert "'zfs diff' should display changes correctly." +log_onexit cleanup + +DATASET="$TESTPOOL/$TESTFS/fs" +TESTSNAP1="$DATASET@snap1" +TESTSNAP2="$DATASET@snap2" +FILEDIFF="$TESTDIR/zfs-diff.txt" + +# 1. Create a filesystem with both files and directories, then snapshot it +log_must zfs create $DATASET +MNTPOINT="$(get_prop mountpoint $DATASET)" +log_must touch "$MNTPOINT/fremoved" +log_must touch "$MNTPOINT/frenamed" +log_must touch "$MNTPOINT/fmodified" +log_must mkdir "$MNTPOINT/dremoved" +log_must mkdir "$MNTPOINT/drenamed" +log_must mkdir "$MNTPOINT/dmodified" +log_must zfs snapshot "$TESTSNAP1" + +# 2. Generate different types of changes and verify 'zfs diff' displays them +log_must rm -f "$MNTPOINT/fremoved" +log_must mv "$MNTPOINT/frenamed" "$MNTPOINT/frenamed.new" +log_must touch "$MNTPOINT/fmodified" +log_must rmdir "$MNTPOINT/dremoved" +log_must mv "$MNTPOINT/drenamed" "$MNTPOINT/drenamed.new" +log_must touch "$MNTPOINT/dmodified/file" +log_must touch "$MNTPOINT/fcreated" +log_must mkdir "$MNTPOINT/dcreated" +log_must zfs snapshot "$TESTSNAP2" +verify_object_change "$MNTPOINT/fremoved" "-" +verify_object_change "$MNTPOINT/frenamed.new" "R" +verify_object_change "$MNTPOINT/fmodified" "M" +verify_object_change "$MNTPOINT/fcreated" "+" +verify_object_change "$MNTPOINT/dremoved" "-" +verify_object_change "$MNTPOINT/drenamed.new" "R" +verify_object_change "$MNTPOINT/dmodified" "M" +verify_object_change "$MNTPOINT/dcreated" "+" + +log_pass "'zfs diff' displays changes correctly." diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_cliargs.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_cliargs.ksh new file mode 100755 index 0000000000..c4b42afee4 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_cliargs.ksh @@ -0,0 +1,80 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +# +# DESCRIPTION: +# 'zfs diff' should only work with supported options. +# +# STRATEGY: +# 1. Create two snapshots +# 2. Verify every supported option is accepted +# 3. Verify supported options raise an error with unsupported arguments +# 4. Verify other unsupported options raise an error +# + +verify_runnable "both" + +function cleanup +{ + for snap in $TESTSNAP1 $TESTSNAP2; do + if snapexists "$snap"; then + log_must zfs destroy "$snap" + fi + done +} + +log_assert "'zfs diff' should only work with supported options." +log_onexit cleanup + +typeset goodopts=("" "-F" "-H" "-t" "-FH" "-Ft" "-Ht" "-FHt") +typeset badopts=("-f" "-h" "-h" "-T" "-Fx" "-Ho" "-tT" "-") + +DATASET="$TESTPOOL/$TESTFS" +TESTSNAP1="$DATASET@snap1" +TESTSNAP2="$DATASET@snap2" + +# 1. Create two snapshots +log_must zfs snapshot "$TESTSNAP1" +log_must zfs snapshot "$TESTSNAP2" + +# 2. Verify every supported option is accepted +for opt in ${goodopts[@]} +do + log_must zfs diff $opt "$TESTSNAP1" + log_must zfs diff $opt "$TESTSNAP1" "$DATASET" + log_must zfs diff $opt "$TESTSNAP1" "$TESTSNAP2" +done + +# 3. Verify supported options raise an error with unsupported arguments +for opt in ${goodopts[@]} +do + log_mustnot zfs diff $opt + log_mustnot zfs diff $opt "$DATASET" + log_mustnot zfs diff $opt "$DATASET@noexists" + log_mustnot zfs diff $opt "$DATASET" "$TESTSNAP1" + log_mustnot zfs diff $opt "$TESTSNAP2" "$TESTSNAP1" +done + +# 4. Verify other unsupported options raise an error +for opt in ${badopts[@]} +do + log_mustnot zfs diff $opt "$TESTSNAP1" "$DATASET" + log_mustnot zfs diff $opt "$TESTSNAP1" "$TESTSNAP2" +done + +log_pass "'zfs diff' only works with supported options." diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_encrypted.ksh new file mode 100755 index 0000000000..67f65ac4b2 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_encrypted.ksh @@ -0,0 +1,54 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018, Datto Inc. +# + +. $STF_SUITE/include/libtest.shlib + +# +# DESCRIPTION: +# 'zfs diff' should work with encrypted datasets +# +# STRATEGY: +# 1. Create an encrypted dataset +# 2. Create two snapshots of the dataset +# 3. Perform 'zfs diff -Ft' and verify no errors occur +# 4. Perform the same test on a dataset with large dnodes +# + +verify_runnable "both" + +function cleanup +{ + datasetexists $TESTPOOL/$TESTFS1 && \ + log_must zfs destroy -r $TESTPOOL/$TESTFS1 +} + +log_assert "'zfs diff' should work with encrypted datasets" +log_onexit cleanup + +# 1. Create an encrypted dataset +log_must eval "echo 'password' | zfs create -o encryption=on \ + -o keyformat=passphrase $TESTPOOL/$TESTFS1" +MNTPOINT="$(get_prop mountpoint $TESTPOOL/$TESTFS1)" + +# 2. Create two snapshots of the dataset +log_must zfs snapshot $TESTPOOL/$TESTFS1@snap1 +log_must touch "$MNTPOINT/file" +log_must zfs snapshot $TESTPOOL/$TESTFS1@snap2 + +# 3. Perform 'zfs diff' and verify no errors occur +log_must zfs diff -Ft $TESTPOOL/$TESTFS1@snap1 $TESTPOOL/$TESTFS1@snap2 + +log_pass "'zfs diff' works with encrypted datasets" diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_timestamp.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_timestamp.ksh new file mode 100755 index 0000000000..c171a851e0 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_timestamp.ksh @@ -0,0 +1,100 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +# +# DESCRIPTION: +# 'zfs diff -t' should display inode change time correctly. +# +# STRATEGY: +# 1. Create a snapshot +# 2. Create some files with a random delay and snapshot the filesystem again +# 3. Verify 'zfs diff -t' correctly display timestamps +# + +verify_runnable "both" + +function cleanup +{ + for snap in $TESTSNAP1 $TESTSNAP2; do + if snapexists "$snap"; then + log_must zfs destroy "$snap" + fi + done + find "$MNTPOINT" -type f -delete + rm -f "$FILEDIFF" +} + +# +# Creates $count files in $fspath. Waits a random delay between each file. +# +function create_random # <fspath> <count> +{ + fspath="$1" + typeset -i count="$2" + typeset -i i=0 + + while (( i < count )); do + log_must touch "$fspath/file$i" + sleep $(random 3) + (( i = i + 1 )) + done +} + +log_assert "'zfs diff -t' should display inode change time correctly." +log_onexit cleanup + +DATASET="$TESTPOOL/$TESTFS" +TESTSNAP1="$DATASET@snap1" +TESTSNAP2="$DATASET@snap2" +MNTPOINT="$(get_prop mountpoint $DATASET)" +FILEDIFF="$TESTDIR/zfs-diff.txt" +FILENUM=5 + +# 1. Create a snapshot +log_must zfs snapshot "$TESTSNAP1" + +# 2. Create some files with a random delay and snapshot the filesystem again +create_random "$MNTPOINT" $FILENUM +log_must zfs snapshot "$TESTSNAP2" + +# 3. Verify 'zfs diff -t' correctly display timestamps +typeset -i count=0 +log_must eval "zfs diff -t $TESTSNAP1 $TESTSNAP2 > $FILEDIFF" +nawk '{print substr($1,1,index($1,".")-1)" "$NF}' < "$FILEDIFF" | while read line +do + read ctime file <<< "$line" + + # If path from 'zfs diff' is not a file (could be xattr object) skip it + if [[ ! -f "$file" ]]; then + continue; + fi + + filetime="$(stat -c '%Z' $file)" + if [[ "$filetime" != "$ctime" ]]; then + log_fail "Unexpected ctime for file $file ($filetime != $ctime)" + else + log_note "Correct ctime read on $file: $ctime" + fi + + (( i = i + 1 )) +done +if [[ $i != $FILENUM ]]; then + log_fail "Wrong number of files verified ($i != $FILENUM)" +fi + +log_pass "'zfs diff -t' displays inode change time correctly." diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_types.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_types.ksh new file mode 100755 index 0000000000..91549fe50f --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_types.ksh @@ -0,0 +1,126 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. +# Copyright 2019 Joyent, Inc. +# + +. $STF_SUITE/include/libtest.shlib + +# +# DESCRIPTION: +# 'zfs diff -F' shows different object types correctly. +# +# STRATEGY: +# 1. Prepare a dataset +# 2. Create different objects and verify 'zfs diff -F' shows the correct type +# + +verify_runnable "both" + +function cleanup +{ + log_must zfs destroy -r "$DATASET" + rm -f "$FILEDIFF" +} + +# +# Verify object at $path is of type $symbol using 'zfs diff -F' +# Valid types are: +# * B (Block device) +# * C (Character device) +# * / (Directory) +# * > (Door) +# * | (Named pipe) +# * @ (Symbolic link) +# * P (Event port) +# * = (Socket) +# * F (Regular file) +# +function verify_object_class # <path> <symbol> +{ + path="$1" + symbol="$2" + + log_must eval "zfs diff -F $TESTSNAP1 $TESTSNAP2 > $FILEDIFF" + diffsym="$(nawk -v path="$path" '$NF == path { print $2 }' < $FILEDIFF)" + if [[ "$diffsym" != "$symbol" ]]; then + log_fail "Unexpected type for $path ('$diffsym' != '$symbol')" + else + log_note "Object $path type is correctly displayed as '$symbol'" + fi + + log_must zfs destroy "$TESTSNAP1" + log_must zfs destroy "$TESTSNAP2" +} + +log_assert "'zfs diff -F' should show different object types correctly." +log_onexit cleanup + +DATASET="$TESTPOOL/$TESTFS/fs" +TESTSNAP1="$DATASET@snap1" +TESTSNAP2="$DATASET@snap2" +FILEDIFF="$TESTDIR/zfs-diff.txt" +MAJOR=$(stat -c %t /dev/null) +MINOR=$(stat -c %T /dev/null) + +# 1. Prepare a dataset +log_must zfs create $DATASET +MNTPOINT="$(get_prop mountpoint $DATASET)" +log_must zfs set devices=on $DATASET +log_must zfs set xattr=on $DATASET + +# 2. Create different objects and verify 'zfs diff -F' shows the correct type +# 2. F (Regular file) +log_must zfs snapshot "$TESTSNAP1" +log_must touch "$MNTPOINT/file" +log_must zfs snapshot "$TESTSNAP2" +verify_object_class "$MNTPOINT/file" "F" + +# 2. @ (Symbolic link) +log_must zfs snapshot "$TESTSNAP1" +log_must ln -s "$MNTPOINT/file" "$MNTPOINT/link" +log_must zfs snapshot "$TESTSNAP2" +verify_object_class "$MNTPOINT/link" "@" + +# 2. B (Block device) +log_must zfs snapshot "$TESTSNAP1" +log_must mknod "$MNTPOINT/bdev" b $MAJOR $MINOR +log_must zfs snapshot "$TESTSNAP2" +verify_object_class "$MNTPOINT/bdev" "B" + +# 2. C (Character device) +log_must zfs snapshot "$TESTSNAP1" +log_must mknod "$MNTPOINT/cdev" c $MAJOR $MINOR +log_must zfs snapshot "$TESTSNAP2" +verify_object_class "$MNTPOINT/cdev" "C" + +# 2. | (Named pipe) +log_must zfs snapshot "$TESTSNAP1" +log_must mknod "$MNTPOINT/fifo" p +log_must zfs snapshot "$TESTSNAP2" +verify_object_class "$MNTPOINT/fifo" "|" + +# 2. / (Directory) +log_must zfs snapshot "$TESTSNAP1" +log_must mkdir "$MNTPOINT/dir" +log_must zfs snapshot "$TESTSNAP2" +verify_object_class "$MNTPOINT/dir" "/" + +# 2. = (Socket) +log_must zfs snapshot "$TESTSNAP1" +log_must $STF_SUITE/tests/functional/cli_root/zfs_diff/socket "$MNTPOINT/sock" +log_must zfs snapshot "$TESTSNAP2" +verify_object_class "$MNTPOINT/sock" "=" + +log_pass "'zfs diff -F' shows different object types correctly." diff --git a/usr/src/tools/smatch/Makefile b/usr/src/tools/smatch/Makefile index 1265cf4190..c2882381bd 100644 --- a/usr/src/tools/smatch/Makefile +++ b/usr/src/tools/smatch/Makefile @@ -20,7 +20,7 @@ # PROG = smatch -SPARSE_VERSION = 0.6.1-rc1-il-1 +SPARSE_VERSION = 0.6.1-rc1-il-2 include ../Makefile.tools diff --git a/usr/src/tools/smatch/src/Makefile b/usr/src/tools/smatch/src/Makefile index 495cc6192d..164fa1bd33 100644 --- a/usr/src/tools/smatch/src/Makefile +++ b/usr/src/tools/smatch/src/Makefile @@ -1,4 +1,4 @@ -VERSION=0.6.1-rc1-il-1 +VERSION=0.6.1-rc1-il-2 ######################################################################## # The following variables can be overwritten from the command line @@ -9,7 +9,7 @@ CC ?= gcc LD = $(CC) AR = ar -CFLAGS ?= -O2 -g +CFLAGS ?= -g DESTDIR ?= PREFIX ?= $(HOME) diff --git a/usr/src/tools/smatch/src/check_arm64_tagged.c b/usr/src/tools/smatch/src/check_arm64_tagged.c index e126552e59..d4d00873e1 100644 --- a/usr/src/tools/smatch/src/check_arm64_tagged.c +++ b/usr/src/tools/smatch/src/check_arm64_tagged.c @@ -154,8 +154,13 @@ int rl_range_has_min_value(struct range_list *rl, sval_t sval) static bool rl_is_tagged(struct range_list *rl) { - sval_t invalid = { .type = &ullong_ctype, .value = (1ULL << 56) }; - sval_t invalid_kernel = { .type = &ullong_ctype, .value = (0xff8ULL << 52) }; + sval_t invalid; + sval_t invalid_kernel; + + invalid.type = &ullong_ctype; + invalid.value = 1ULL << 56; + invalid_kernel.type = &ullong_ctype; + invalid_kernel.value = 0xff8ULL << 52; /* * We only care for tagged addresses, thus ignore anything where the diff --git a/usr/src/tools/smatch/src/ident-list.h b/usr/src/tools/smatch/src/ident-list.h index 096b1c2358..4ffd756301 100644 --- a/usr/src/tools/smatch/src/ident-list.h +++ b/usr/src/tools/smatch/src/ident-list.h @@ -31,7 +31,7 @@ IDENT(static); /* C99 keywords */ IDENT(restrict); IDENT(__restrict); IDENT(__restrict__); IDENT(_Bool); -IDENT(_Complex); +IDENT_RESERVED(_Complex); IDENT_RESERVED(_Imaginary); /* C11 keywords */ diff --git a/usr/src/tools/smatch/src/smatch_data/illumos_kernel.skipped_functions b/usr/src/tools/smatch/src/smatch_data/illumos_kernel.skipped_functions index 3617b9b806..029d02aad9 100644 --- a/usr/src/tools/smatch/src/smatch_data/illumos_kernel.skipped_functions +++ b/usr/src/tools/smatch/src/smatch_data/illumos_kernel.skipped_functions @@ -3,6 +3,7 @@ ECDSA_VerifyDigest dtrace_disx86 elf32exec elfexec +emlxs_sli4_process_unsol_rcv iscsi_ioctl lm_idle_chk ld64_sym_validate diff --git a/usr/src/tools/smatch/src/smatch_data/illumos_user.skipped_functions b/usr/src/tools/smatch/src/smatch_data/illumos_user.skipped_functions index f82ff4f38a..2842a7bc96 100644 --- a/usr/src/tools/smatch/src/smatch_data/illumos_user.skipped_functions +++ b/usr/src/tools/smatch/src/smatch_data/illumos_user.skipped_functions @@ -1,8 +1,6 @@ /* - * The below functions cause smatch to fail with "turning off implications after - * 60 seconds" or similar, generally because they're too large for it to handle. - * - * This will disable analysis altogether. + * These are specific functions that are generally too complex for smatch to + * reasonably handle. */ /* libast */ diff --git a/usr/src/tools/smatch/src/smatch_kernel_user_data.c b/usr/src/tools/smatch/src/smatch_kernel_user_data.c index ca4c7cd315..cda3b58d9d 100644 --- a/usr/src/tools/smatch/src/smatch_kernel_user_data.c +++ b/usr/src/tools/smatch/src/smatch_kernel_user_data.c @@ -681,10 +681,15 @@ static void handle_eq_noteq(struct expression *expr) static struct range_list *strip_negatives(struct range_list *rl) { sval_t min = rl_min(rl); - sval_t minus_one = { .type = rl_type(rl), .value = -1 }; - sval_t over = { .type = rl_type(rl), .value = INT_MAX + 1ULL }; + sval_t minus_one; + sval_t over; sval_t max = sval_type_max(rl_type(rl)); + minus_one.type = rl_type(rl); + minus_one.value = -1; + over.type = rl_type(rl); + over.value = INT_MAX + 1ULL; + if (!rl) return NULL; diff --git a/usr/src/uts/common/io/blkdev/blkdev.c b/usr/src/uts/common/io/blkdev/blkdev.c index 3405187f60..2b185dff2b 100644 --- a/usr/src/uts/common/io/blkdev/blkdev.c +++ b/usr/src/uts/common/io/blkdev/blkdev.c @@ -495,20 +495,35 @@ static void bd_errstats_setstr(kstat_named_t *k, char *str, size_t len, char *alt) { char *tmp; + size_t km_len; if (KSTAT_NAMED_STR_PTR(k) == NULL) { - if (len > 0) { - tmp = kmem_alloc(len + 1, KM_SLEEP); - (void) strlcpy(tmp, str, len + 1); - } else { - tmp = alt; - } + if (len > 0) + km_len = strnlen(str, len); + else if (alt != NULL) + km_len = strlen(alt); + else + return; + + tmp = kmem_alloc(km_len + 1, KM_SLEEP); + bcopy(len > 0 ? str : alt, tmp, km_len); + tmp[km_len] = '\0'; kstat_named_setstr(k, tmp); } } static void +bd_errstats_clrstr(kstat_named_t *k) +{ + if (KSTAT_NAMED_STR_PTR(k) == NULL) + return; + + kmem_free(KSTAT_NAMED_STR_PTR(k), KSTAT_NAMED_STR_BUFLEN(k)); + kstat_named_setstr(k, NULL); +} + +static void bd_init_errstats(bd_t *bd, bd_drive_t *drive) { struct bd_errstats *est = bd->d_kerr; @@ -535,6 +550,22 @@ bd_init_errstats(bd_t *bd, bd_drive_t *drive) } static void +bd_fini_errstats(bd_t *bd) +{ + struct bd_errstats *est = bd->d_kerr; + + mutex_enter(&bd->d_errmutex); + + bd_errstats_clrstr(&est->bd_model); + bd_errstats_clrstr(&est->bd_vid); + bd_errstats_clrstr(&est->bd_pid); + bd_errstats_clrstr(&est->bd_revision); + bd_errstats_clrstr(&est->bd_serial); + + mutex_exit(&bd->d_errmutex); +} + +static void bd_queues_free(bd_t *bd) { uint32_t i; @@ -773,6 +804,7 @@ bd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) } if (bd->d_errstats != NULL) { + bd_fini_errstats(bd); kstat_delete(bd->d_errstats); bd->d_errstats = NULL; } else { |
