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 | |
| 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
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 { |
