diff options
42 files changed, 1184 insertions, 219 deletions
diff --git a/usr/src/cmd/diskinfo/diskinfo.c b/usr/src/cmd/diskinfo/diskinfo.c index 84c5a692a7..d5b0c82787 100644 --- a/usr/src/cmd/diskinfo/diskinfo.c +++ b/usr/src/cmd/diskinfo/diskinfo.c @@ -216,25 +216,10 @@ static void enumerate_disks(di_opts_t *opts) { topo_hdl_t *hp = NULL; - dm_descriptor_t *media; - int e, i; int filter[] = { DM_DT_FIXED, -1 }; - dm_descriptor_t *disk, *controller; - nvlist_t *mattrs, *dattrs, *cattrs = NULL; - - uint64_t size, total; - uint32_t blocksize; - double total_in_GiB; - char sizestr[32]; - char slotname[32]; - char statestr[8]; - - char *vid, *pid, *opath, *c, *ctype = NULL; - boolean_t removable; - boolean_t ssd; - char device[MAXPATHLEN]; - di_phys_t phys; - size_t len; + dm_descriptor_t *media; + uint_t i; + int e; e = 0; if ((media = dm_get_descriptors(DM_MEDIA, filter, &e)) == NULL) { @@ -264,6 +249,20 @@ enumerate_disks(di_opts_t *opts) } for (i = 0; media != NULL && media[i] != 0; i++) { + dm_descriptor_t *disk, *controller; + nvlist_t *mattrs, *dattrs; + char *vid, *pid, *opath, *ctype, *pctype, *c; + boolean_t removable, ssd; + char device[MAXPATHLEN]; + di_phys_t phys; + size_t len; + uint64_t size, total; + uint32_t blocksize; + double total_in_GiB; + char sizestr[32]; + char slotname[32]; + char statestr[8]; + if ((disk = dm_get_associated_descriptors(media[i], DM_DRIVE, &e)) == NULL) { continue; @@ -274,37 +273,50 @@ enumerate_disks(di_opts_t *opts) * info with DKIOCGMEDIAINFO which may not be the case for * disks which are failing. */ - if ((mattrs = dm_get_attributes(media[i], &e)) == NULL) { + if ((mattrs = dm_get_attributes(media[i], &e)) == NULL) continue; - } e = nvlist_lookup_uint64(mattrs, DM_SIZE, &size); assert(e == 0); e = nvlist_lookup_uint32(mattrs, DM_BLOCKSIZE, &blocksize); assert(e == 0); - nvlist_free(mattrs); - dattrs = dm_get_attributes(disk[0], &e); + vid = pid = opath = "-"; + removable = B_FALSE; + ssd = B_FALSE; - nvlist_query_string(dattrs, DM_VENDOR_ID, &vid); - nvlist_query_string(dattrs, DM_PRODUCT_ID, &pid); - nvlist_query_string(dattrs, DM_OPATH, &opath); + dattrs = dm_get_attributes(disk[0], &e); + if (dattrs != NULL) { + nvlist_query_string(dattrs, DM_VENDOR_ID, &vid); + nvlist_query_string(dattrs, DM_PRODUCT_ID, &pid); + nvlist_query_string(dattrs, DM_OPATH, &opath); - removable = B_FALSE; - if (nvlist_lookup_boolean(dattrs, DM_REMOVABLE) == 0) - removable = B_TRUE; + if (nvlist_lookup_boolean(dattrs, DM_REMOVABLE) == 0) + removable = B_TRUE; - ssd = B_FALSE; - if (nvlist_lookup_boolean(dattrs, DM_SOLIDSTATE) == 0) - ssd = B_TRUE; + if (nvlist_lookup_boolean(dattrs, DM_SOLIDSTATE) == 0) + ssd = B_TRUE; + } + pctype = "-"; + ctype = NULL; if ((controller = dm_get_associated_descriptors(disk[0], DM_CONTROLLER, &e)) != NULL) { + nvlist_t *cattrs; + cattrs = dm_get_attributes(controller[0], &e); - nvlist_query_string(cattrs, DM_CTYPE, &ctype); - ctype = strdup(ctype); - for (c = ctype; *c != '\0'; c++) - *c = toupper(*c); + if (cattrs != NULL) { + nvlist_query_string(cattrs, DM_CTYPE, &ctype); + ctype = strdup(ctype); + nvlist_free(cattrs); + + if (ctype != NULL) { + for (c = ctype; *c != '\0'; c++) + *c = toupper(*c); + pctype = ctype; + } + } + dm_free_descriptors(controller); } /* @@ -318,8 +330,9 @@ enumerate_disks(di_opts_t *opts) (void) strlcpy(device, opath, sizeof (device)); len = strlen(device); if (device[len - 2] == 's' && - (device[len - 1] >= '0' && device[len - 1] <= '9')) + (device[len - 1] >= '0' && device[len - 1] <= '9')) { device[len - 2] = '\0'; + } if (hp != NULL) { bzero(&phys, sizeof (phys)); @@ -386,25 +399,25 @@ enumerate_disks(di_opts_t *opts) } else if (opts->di_condensed) { if (opts->di_scripted) { printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", - ctype, device, vid, pid, + pctype, device, vid, pid, display_string(phys.dp_serial), sizestr, statestr, slotname); } else { printf("%-7s %-22s %-8s %-16s " "%-20s\n\t%-13s %-4s %s\n", - ctype, device, vid, pid, + pctype, device, vid, pid, display_string(phys.dp_serial), sizestr, statestr, slotname); } } else { if (opts->di_scripted) { printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\n", - ctype, device, vid, pid, sizestr, + pctype, device, vid, pid, sizestr, display_tristate(removable), display_tristate(ssd)); } else { printf("%-7s %-22s %-8s %-16s " - "%-13s %-3s %-3s\n", ctype, device, + "%-13s %-3s %-3s\n", pctype, device, vid, pid, sizestr, display_tristate(removable), display_tristate(ssd)); @@ -412,9 +425,8 @@ enumerate_disks(di_opts_t *opts) } free(ctype); - nvlist_free(cattrs); nvlist_free(dattrs); - dm_free_descriptors(controller); + nvlist_free(mattrs); dm_free_descriptors(disk); } diff --git a/usr/src/lib/libc/amd64/unwind/call_frame_inst.c b/usr/src/lib/libc/amd64/unwind/call_frame_inst.c index 3e23a5e25b..64e112743e 100644 --- a/usr/src/lib/libc/amd64/unwind/call_frame_inst.c +++ b/usr/src/lib/libc/amd64/unwind/call_frame_inst.c @@ -127,7 +127,7 @@ uint64_t interpret_ops(void *data, void *data_end, */ void _Unw_Propagate_Registers(struct _Unwind_Context *old_ctx, - struct _Unwind_Context *new_ctx) + struct _Unwind_Context *new_ctx) { new_ctx->current_regs[SP_RSP] = old_ctx->cfa; new_ctx->pc = old_ctx->ra; @@ -228,7 +228,7 @@ fix_reg(struct _Unwind_Context *ctx, struct register_state *rs, int index) */ uint64_t _Unw_Rollback_Registers(struct eh_frame_fields *f, - struct _Unwind_Context *ctx) + struct _Unwind_Context *ctx) { /* GPRs, RET_ADD, and CF_ADDR */ struct register_state func_state[18]; @@ -361,7 +361,7 @@ static uint64_t get_encoded_val(void **datap, ptrdiff_t reloc, int enc); */ uint64_t _Unw_get_val(void **datap, ptrdiff_t reloc, - enum operand_desc opr, int daf, int caf, int enc) + enum operand_desc opr, int daf, int caf, int enc) { intptr_t data = (intptr_t)*datap; uint64_t res; @@ -453,7 +453,7 @@ _Unw_get_val(void **datap, ptrdiff_t reloc, /* max length of augmentation string is 4 */ rp = (char *)&res; dp = (char *)data; - while (*rp++ = *dp++) + while ((*rp++ = *dp++) != '\0') ; data = (intptr_t)dp; break; @@ -553,11 +553,11 @@ int interpret_op(void **datap, ptrdiff_t reloc, uint64_t interpret_ops(void *data, void *data_end, - ptrdiff_t reloc, - uint64_t start_pc, uint64_t pc, - struct register_state f_state[], - struct register_state f_start_state[], - int daf, int caf, int enc) + ptrdiff_t reloc, + uint64_t start_pc, uint64_t pc, + struct register_state f_state[], + struct register_state f_start_state[], + int daf, int caf, int enc) { void *d = data; uint64_t reached_pc = start_pc; @@ -572,10 +572,10 @@ interpret_ops(void *data, void *data_end, int interpret_op(void **datap, ptrdiff_t reloc, - uint64_t *reached_pc_p, uint64_t pc, - struct register_state f_state[], - struct register_state f_start_state[], - int daf, int caf, int enc) + uint64_t *reached_pc_p, uint64_t pc, + struct register_state f_state[], + struct register_state f_start_state[], + int daf, int caf, int enc) { enum CFA_ops op = separate_op(datap); enum operand_desc opr1 = (cfa_operations[op]).op1; diff --git a/usr/src/lib/libc/port/gen/_xftw.c b/usr/src/lib/libc/port/gen/_xftw.c index b6d32eebd4..eb16988600 100644 --- a/usr/src/lib/libc/port/gen/_xftw.c +++ b/usr/src/lib/libc/port/gen/_xftw.c @@ -200,7 +200,7 @@ fwalk(const char *path, int (*fn)(const char *, const struct stat *, int), * We must ignore "." and "..", but other than that, * just create a path name and call self to check it out. */ - while (direntp = readdir(dirp)) { + while ((direntp = readdir(dirp)) != NULL) { long here; if (strcmp(direntp->d_name, ".") == 0 || diff --git a/usr/src/lib/libc/port/gen/attrat.c b/usr/src/lib/libc/port/gen/attrat.c index d7c7949175..279749c4e1 100644 --- a/usr/src/lib/libc/port/gen/attrat.c +++ b/usr/src/lib/libc/port/gen/attrat.c @@ -181,7 +181,7 @@ cgetattr(int fd, nvlist_t **response) size_t nv_responselen; struct stat buf; - if (error = attrat_init()) + if ((error = attrat_init()) != 0) return (error); if ((error = fstat(fd, &buf)) != 0) return (error); @@ -214,7 +214,7 @@ csetattr(int fd, nvlist_t *request) void *nv_request; size_t nv_requestlen; - if (error = attrat_init()) + if ((error = attrat_init()) != 0) return (error); if ((error = attr_nv_pack(request, &nv_request, &nv_requestlen)) != 0) diff --git a/usr/src/lib/libc/port/gen/catopen.c b/usr/src/lib/libc/port/gen/catopen.c index ece463fc2a..95c3e3f2ed 100644 --- a/usr/src/lib/libc/port/gen/catopen.c +++ b/usr/src/lib/libc/port/gen/catopen.c @@ -194,7 +194,7 @@ process_nls_path(char *name, int oflag) s = _DFLT_LOC_PATH; t = pathname; - while (*t++ = *s++) + while ((*t++ = *s++) != '\0') continue; t--; s = locale; @@ -217,7 +217,7 @@ process_nls_path(char *name, int oflag) */ static char * replace_nls_option(char *s, char *name, char *pathname, char *locale, - char *lang, char *territory, char *codeset) + char *lang, char *territory, char *codeset) { char *t, *u; diff --git a/usr/src/lib/libc/port/gen/ctime.c b/usr/src/lib/libc/port/gen/ctime.c index c2a58b25b3..4f3b228598 100644 --- a/usr/src/lib/libc/port/gen/ctime.c +++ b/usr/src/lib/libc/port/gen/ctime.c @@ -25,9 +25,7 @@ */ /* Copyright (c) 1988 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* All Rights Reserved */ /* * This routine converts time as follows. @@ -117,7 +115,7 @@ __posix_asctime_r(const struct tm *t, char *cbuf) int year = t->tm_year + 1900; cp = cbuf; - for (ncp = Date; *cp++ = *ncp++; /* */) + for (ncp = Date; (*cp++ = *ncp++) != '\0'; /* */) ; ncp = Day + (3 * t->tm_wday); cp = cbuf; diff --git a/usr/src/lib/libc/port/gen/fmtmsg.c b/usr/src/lib/libc/port/gen/fmtmsg.c index 063fe325f8..1bc51cf9aa 100644 --- a/usr/src/lib/libc/port/gen/fmtmsg.c +++ b/usr/src/lib/libc/port/gen/fmtmsg.c @@ -25,7 +25,7 @@ */ /* Copyright (c) 1988 AT&T */ -/* All Rights Reserved */ +/* All Rights Reserved */ /* * fmtmsg.c @@ -251,9 +251,9 @@ static struct sevstr *penvsevs = (struct sevstr *)NULL; static struct sevstr sevstrs[] = { { MM_HALT, "", SV_HALT, &sevstrs[1]}, - { MM_ERROR, "", SV_ERROR, &sevstrs[2]}, - { MM_WARNING, "", SV_WARN, &sevstrs[3]}, - { MM_INFO, "", SV_INF, (struct sevstr *)NULL}, + { MM_ERROR, "", SV_ERROR, &sevstrs[2]}, + { MM_WARNING, "", SV_WARN, &sevstrs[3]}, + { MM_INFO, "", SV_INF, (struct sevstr *)NULL}, }; static struct sevstr *pstdsevs = &sevstrs[0]; @@ -359,7 +359,7 @@ noesc(char *str) if (*p) { q = p++; - while (*q++ = *p++) { + while ((*q++ = *p++) != '\0') { if (*p == '\\') p++; } @@ -628,7 +628,7 @@ sevstrset(void) /* Look for SEV_LEVEL definition */ - if ((value = getenv(SEV_LEVEL)) != (char *)NULL) { + if ((value = getenv(SEV_LEVEL)) != NULL) { /* Allocate space and make a copy of the value of SEV_LEVEL */ if ((sevspace = libc_malloc(strlen(value) + 1)) != NULL) { @@ -636,11 +636,11 @@ sevstrset(void) /* Continue for all severity descriptions */ psev = getauxsevs(sevspace); - plast = (struct sevstr *)NULL; - if (psev != (struct sevstr *)NULL) { + plast = NULL; + if (psev != NULL) { penvsevs = psev; plast = psev; - while (psev = getauxsevs((char *)NULL)) { + while ((psev = getauxsevs(NULL)) != NULL) { plast->sevnext = psev; plast = psev; } @@ -786,13 +786,13 @@ itoa(int n, char *s) * Arguments: * char *buf The buffer in which to format the message * size_t size The size of the buffer - * int verbosity A bit-string that indicates which components + * int verbosity A bit-string that indicates which components * are to be written - * const char *label The address of the label-component - * int severity The severity value of the message - * const char *text The address of the text-component - * const char *action The address of the action-component - * const char *tag The address of the tag-component + * const char *label The address of the label-component + * int severity The severity value of the message + * const char *text The address of the text-component + * const char *action The address of the action-component + * const char *tag The address of the tag-component * * This function formats the message consisting of the label-component, * severity-component, text-component, action-component, and tag- @@ -807,8 +807,8 @@ itoa(int n, char *s) static void writemsg(char *buf, size_t size, - int verbosity, const char *label, int severity, - const char *text, const char *action, const char *tag) + int verbosity, const char *label, int severity, + const char *text, const char *action, const char *tag) { struct sevstr *psev; /* Ptr for severity str list */ char *p; /* General purpose pointer */ @@ -1084,7 +1084,7 @@ writemsg(char *buf, size_t size, int fmtmsg(long class, const char *label, int severity, -const char *text, const char *action, const char *tag) + const char *text, const char *action, const char *tag) { int rtnval; /* Value to return */ FILE *console; /* Ptr to "console" stream */ diff --git a/usr/src/lib/libc/port/gen/getut.c b/usr/src/lib/libc/port/gen/getut.c index a622293d73..024eb76b53 100644 --- a/usr/src/lib/libc/port/gen/getut.c +++ b/usr/src/lib/libc/port/gen/getut.c @@ -25,7 +25,7 @@ */ /* Copyright (c) 1988 AT&T */ -/* All Rights Reserved */ +/* All Rights Reserved */ /* * Compatibility routines to read and write alternate @@ -64,7 +64,7 @@ static void utmp_frec2api(const struct futmp *, struct utmp *); static void utmp_api2frec(const struct utmp *, struct futmp *); -struct utmp *_compat_getutent(void); +struct utmp *_compat_getutent(void); struct utmp *_compat_getutid(const struct utmp *); struct utmp *_compat_getutline(const struct utmp *); struct utmp *_compat_pututline(const struct utmp *); @@ -553,7 +553,7 @@ _compat_modut(struct utmp *utp) /* copy the supplied utmp structure someplace safe */ utmp = *utp; _compat_setutent(); - while (fup = getutent_frec()) { + while ((fup = getutent_frec()) != NULL) { if (idcmp(ucp->ut_id, fup->ut_id)) continue; break; diff --git a/usr/src/lib/libc/port/gen/getutx.c b/usr/src/lib/libc/port/gen/getutx.c index 71b8364600..63decba9b7 100644 --- a/usr/src/lib/libc/port/gen/getutx.c +++ b/usr/src/lib/libc/port/gen/getutx.c @@ -925,7 +925,7 @@ modutx(const struct utmpx *utp) */ (void) memcpy(&utmp, utp, sizeof (utmp)); setutxent(); - while (fup = getutxent_frec()) { + while ((fup = getutxent_frec()) != NULL) { if (idcmp(ucp->ut_id, fup->ut_id)) continue; @@ -1166,7 +1166,7 @@ makeutx(const struct utmpx *utmp) */ (void) memset(saveid, falphanum, IDLEN); - while (ut = getoneutx(&offset)) + while ((ut = getoneutx(&offset)) != NULL) if (idcmp(utmp->ut_id, ut->ut_id)) { continue; } else { diff --git a/usr/src/lib/libc/port/gen/nftw.c b/usr/src/lib/libc/port/gen/nftw.c index f07f9a9f94..a72e955991 100644 --- a/usr/src/lib/libc/port/gen/nftw.c +++ b/usr/src/lib/libc/port/gen/nftw.c @@ -364,7 +364,7 @@ walk(char *component, this.inode = statb.st_ino; oldbase = vp->state.base; vp->state.base = (int)(component - vp->tmppath); - while (dir = readdir(this.fd)) { + while ((dir = readdir(this.fd)) != NULL) { if (dir->d_ino == 0) continue; q = dir->d_name; diff --git a/usr/src/lib/libc/port/gen/nlspath_checks.c b/usr/src/lib/libc/port/gen/nlspath_checks.c index f06b564cb0..986b34047e 100644 --- a/usr/src/lib/libc/port/gen/nlspath_checks.c +++ b/usr/src/lib/libc/port/gen/nlspath_checks.c @@ -229,7 +229,7 @@ nls_safe_open(const char *path, struct stat64 *statbuf, int *trust, int safe) * allows one use, but we don't want to break existing functional code, * even if it's buggy. */ -#define STORE(buf, size, arg, val) if (arg * FORMAT_SIZE + 1 >= size ||\ +#define STORE(buf, size, arg, val) if (arg * FORMAT_SIZE + 1 >= size ||\ (strict ? \ (buf[arg*FORMAT_SIZE] != '\0' && \ buf[arg*FORMAT_SIZE] != val) \ @@ -547,7 +547,8 @@ check_format(const char *org, const char *new, int strict) nlen *= FORMAT_SIZE; - for (n = nfmt; n = memchr(n, 'n', nfmt + nlen - n); + for (n = nfmt; + (n = memchr(n, 'n', nfmt + nlen - n)) != NULL; n++) { int off = (n - nfmt); diff --git a/usr/src/lib/libc/port/gen/nsparse.c b/usr/src/lib/libc/port/gen/nsparse.c index 57c07a7841..5e0301544d 100644 --- a/usr/src/lib/libc/port/gen/nsparse.c +++ b/usr/src/lib/libc/port/gen/nsparse.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "lint.h" #include "file64.h" #include "mtlib.h" @@ -48,7 +46,7 @@ #include <syslog.h> -#define islabel(c) (isalnum(c) || (c) == '_') +#define islabel(c) (isalnum(c) || (c) == '_') #define LIBC_STRDUP(new, existing) \ if ((new = libc_strdup(existing)) == NULL) { \ @@ -112,7 +110,7 @@ static struct cons_cell *concell_list; /* stays with add_concell() */ * not explicitly set by the admin in the conf file, we want the old "resolver * retry a few times" rather than no retries at all. */ -static int dns_tryagain_retry = 3; +static int dns_tryagain_retry = 3; /* * For backward compat (pre "lookup control"), the dns default behavior is @@ -129,11 +127,12 @@ set_dns_default_lkp(struct __nsw_lookup_v1 *lkp) /* * Private interface used by nss_common.c, hence this function is not static + * + * linep Nota Bene: not const char * + * errp Meanings are abused a bit */ struct __nsw_switchconfig_v1 * _nsw_getoneconfig_v1(const char *name, char *linep, enum __nsw_parse_err *errp) - /* linep Nota Bene: not const char * */ - /* errp Meanings are abused a bit */ { struct __nsw_switchconfig_v1 *cfp; struct __nsw_lookup_v1 *lkp, **lkq; @@ -178,7 +177,8 @@ _nsw_getoneconfig_v1(const char *name, char *linep, enum __nsw_parse_err *errp) lkp->actions[i] = __NSW_CONTINUE; /* get criteria for the naming service */ - if (tokenp = skip(&linep, '[')) { /* got criteria */ + tokenp = skip(&linep, '['); + if (tokenp != NULL) { /* got criteria */ /* premature end, illegal char following [ */ if (!islabel(*linep)) @@ -224,12 +224,11 @@ _nsw_getoneconfig_v1(const char *name, char *linep, enum __nsw_parse_err *errp) if (strcasecmp(linep, __NSW_STR_RETURN) == 0) act = __NSW_RETURN; else if (strcasecmp(linep, - __NSW_STR_CONTINUE) == 0) { + __NSW_STR_CONTINUE) == 0) { if (strcasecmp(lkp->service_name, - "dns") == 0 && - strcasecmp(tokenp, - __NSW_STR_TRYAGAIN) - == 0) { + "dns") == 0 && + strcasecmp(tokenp, + __NSW_STR_TRYAGAIN) == 0) { /* * Add one more condition * so it retries only if it's @@ -240,7 +239,7 @@ _nsw_getoneconfig_v1(const char *name, char *linep, enum __nsw_parse_err *errp) } else act = __NSW_CONTINUE; } else if (strcasecmp(linep, - __NSW_STR_FOREVER) == 0) + __NSW_STR_FOREVER) == 0) act = __NSW_TRYAGAIN_FOREVER; else if (alldigits(linep)) { act = __NSW_TRYAGAIN_NTIMES; @@ -253,29 +252,29 @@ _nsw_getoneconfig_v1(const char *name, char *linep, enum __nsw_parse_err *errp) if (__NSW_SUCCESS_ACTION(act) && strcasecmp(tokenp, - __NSW_STR_SUCCESS) == 0) { + __NSW_STR_SUCCESS) == 0) { lkp->actions[__NSW_SUCCESS] = act; } else if (__NSW_NOTFOUND_ACTION(act) && - strcasecmp(tokenp, - __NSW_STR_NOTFOUND) == 0) { + strcasecmp(tokenp, + __NSW_STR_NOTFOUND) == 0) { lkp->actions[__NSW_NOTFOUND] = act; } else if (__NSW_UNAVAIL_ACTION(act) && - strcasecmp(tokenp, - __NSW_STR_UNAVAIL) == 0) { + strcasecmp(tokenp, + __NSW_STR_UNAVAIL) == 0) { lkp->actions[__NSW_UNAVAIL] = act; } else if (__NSW_TRYAGAIN_ACTION(act) && - strcasecmp(tokenp, - __NSW_STR_TRYAGAIN) == 0) { + strcasecmp(tokenp, + __NSW_STR_TRYAGAIN) == 0) { lkp->actions[__NSW_TRYAGAIN] = act; if (strcasecmp(lkp->service_name, - "nis") == 0) + "nis") == 0) lkp->actions[ __NSW_NISSERVDNS_TRYAGAIN] = act; if (act == __NSW_TRYAGAIN_NTIMES) lkp->max_retries = - dns_continue ? - dns_tryagain_retry : ntimes; + dns_continue ? + dns_tryagain_retry : ntimes; } else { /*EMPTY*/ /* @@ -323,11 +322,12 @@ barf_line: /* * Private interface used by nss_common.c, hence this function is not static + * + * linep Nota Bene: not const char * + * errp Meanings are abused a bit */ struct __nsw_switchconfig * _nsw_getoneconfig(const char *name, char *linep, enum __nsw_parse_err *errp) - /* linep Nota Bene: not const char * */ - /* errp Meanings are abused a bit */ { struct __nsw_switchconfig *cfp; struct __nsw_lookup *lkp, **lkq; @@ -370,7 +370,8 @@ _nsw_getoneconfig(const char *name, char *linep, enum __nsw_parse_err *errp) lkp->actions[i] = 0; /* get criteria for the naming service */ - if (tokenp = skip(&linep, '[')) { /* got criteria */ + tokenp = skip(&linep, '['); + if (tokenp != NULL) { /* got criteria */ /* premature end, illegal char following [ */ if (!islabel(*linep)) @@ -410,10 +411,10 @@ _nsw_getoneconfig(const char *name, char *linep, enum __nsw_parse_err *errp) if (strcasecmp(linep, __NSW_STR_RETURN) == 0) act = __NSW_RETURN; else if (strcasecmp(linep, - __NSW_STR_CONTINUE) == 0) + __NSW_STR_CONTINUE) == 0) act = __NSW_CONTINUE; else if (strcasecmp(linep, - __NSW_STR_FOREVER) == 0) + __NSW_STR_FOREVER) == 0) /* * =forever or =N might be in conf file * but old progs won't expect it. @@ -424,16 +425,16 @@ _nsw_getoneconfig(const char *name, char *linep, enum __nsw_parse_err *errp) else goto barf_line; if (strcasecmp(tokenp, - __NSW_STR_SUCCESS) == 0) { + __NSW_STR_SUCCESS) == 0) { lkp->actions[__NSW_SUCCESS] = act; } else if (strcasecmp(tokenp, - __NSW_STR_NOTFOUND) == 0) { + __NSW_STR_NOTFOUND) == 0) { lkp->actions[__NSW_NOTFOUND] = act; } else if (strcasecmp(tokenp, - __NSW_STR_UNAVAIL) == 0) { + __NSW_STR_UNAVAIL) == 0) { lkp->actions[__NSW_UNAVAIL] = act; } else if (strcasecmp(tokenp, - __NSW_STR_TRYAGAIN) == 0) { + __NSW_STR_TRYAGAIN) == 0) { lkp->actions[__NSW_TRYAGAIN] = act; } else { /*EMPTY*/ @@ -521,7 +522,8 @@ __nsw_getconfig_v1(const char *dbase, enum __nsw_parse_err *errp) lmutex_lock(&serialize_config_v1); top: - if (cfp = scrounge_cache_v1(dbase)) { + cfp = scrounge_cache_v1(dbase); + if (cfp != NULL) { *errp = __NSW_CONF_PARSE_SUCCESS; lmutex_unlock(&serialize_config_v1); if (fp != NULL) @@ -545,7 +547,7 @@ top: } *errp = __NSW_CONF_PARSE_NOPOLICY; - while (linep = fgets(lineq, BUFSIZ, fp)) { + while ((linep = fgets(lineq, BUFSIZ, fp)) != NULL) { enum __nsw_parse_err line_err; char *tokenp, *comment; @@ -565,10 +567,12 @@ top: if ((tokenp = skip(&linep, ':')) == NULL) { continue; /* ignore this line */ } - if (cfp = scrounge_cache_v1(tokenp)) { + cfp = scrounge_cache_v1(tokenp); + if (cfp != NULL) { continue; /* ? somehow this database is in the cache */ } - if (cfp = _nsw_getoneconfig_v1(tokenp, linep, &line_err)) { + cfp = _nsw_getoneconfig_v1(tokenp, linep, &line_err); + if (cfp != NULL) { (void) add_concell_v1(cfp); if (strcmp(cfp->dbase, dbase) == 0) { *errp = __NSW_CONF_PARSE_SUCCESS; @@ -619,7 +623,8 @@ __nsw_getconfig(const char *dbase, enum __nsw_parse_err *errp) lmutex_lock(&serialize_config); top: - if (cfp = scrounge_cache(dbase)) { + cfp = scrounge_cache(dbase); + if (cfp != NULL) { *errp = __NSW_CONF_PARSE_SUCCESS; lmutex_unlock(&serialize_config); if (fp != NULL) @@ -642,7 +647,7 @@ top: } *errp = __NSW_CONF_PARSE_NOPOLICY; - while (linep = fgets(lineq, BUFSIZ, fp)) { + while ((linep = fgets(lineq, BUFSIZ, fp)) != NULL) { enum __nsw_parse_err line_err; char *tokenp, *comment; @@ -659,13 +664,16 @@ top: if ((*linep == '\0') || isspace(*linep)) { continue; } - if ((tokenp = skip(&linep, ':')) == NULL) { + tokenp = skip(&linep, ':'); + if (tokenp == NULL) { continue; /* ignore this line */ } - if (cfp = scrounge_cache(tokenp)) { + cfp = scrounge_cache(tokenp); + if (cfp != NULL) { continue; /* ? somehow this database is in the cache */ } - if (cfp = _nsw_getoneconfig(tokenp, linep, &line_err)) { + cfp = _nsw_getoneconfig(tokenp, linep, &line_err); + if (cfp != NULL) { (void) add_concell(cfp); if (strcmp(cfp->dbase, dbase) == 0) { *errp = __NSW_CONF_PARSE_SUCCESS; diff --git a/usr/src/lib/libc/port/gen/rctlops.c b/usr/src/lib/libc/port/gen/rctlops.c index c61eb8ec41..21e5133c18 100644 --- a/usr/src/lib/libc/port/gen/rctlops.c +++ b/usr/src/lib/libc/port/gen/rctlops.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "lint.h" #include <sys/rctl_impl.h> #include <stdlib.h> @@ -60,7 +58,8 @@ rctl_walk(int (*callback)(const char *rctlname, void *walk_data), for (curr_name = ctl_names; curr_name < ctl_names + sz; curr_name += strlen(curr_name) + 1) { - if (ret = callback(curr_name, init_data)) { + ret = callback(curr_name, init_data); + if (ret != 0) { free(ctl_names); return (ret); } diff --git a/usr/src/lib/libc/port/gen/regexpr.c b/usr/src/lib/libc/port/gen/regexpr.c index efa3c2e0f0..90ced76497 100644 --- a/usr/src/lib/libc/port/gen/regexpr.c +++ b/usr/src/lib/libc/port/gen/regexpr.c @@ -25,9 +25,7 @@ */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* All Rights Reserved */ /* * routines to do regular expression matching @@ -294,7 +292,8 @@ re_exec(const char *p1) do { if (*p1 != c) continue; - if (rv = advance(p1, p2)) + rv = advance(p1, p2); + if (rv != 0) return (rv); } while (*p1++); return (0); @@ -303,7 +302,8 @@ re_exec(const char *p1) * regular algorithm */ do { - if (rv = advance(p1, p2)) + rv = advance(p1, p2); + if (rv != 0) return (rv); } while (*p1++); return (0); @@ -381,7 +381,8 @@ advance(const char *lp, char *ep) while (backref(i, lp)) lp += ct; while (lp >= curlp) { - if (rv = advance(lp, ep)) + rv = advance(lp, ep); + if (rv != 0) return (rv); lp -= ct; } @@ -411,7 +412,8 @@ advance(const char *lp, char *ep) star: do { lp--; - if (rv = advance(lp, ep)) + rv = advance(lp, ep); + if (rv != 0) return (rv); } while (lp > curlp); return (0); diff --git a/usr/src/lib/libc/port/i18n/gettext_util.c b/usr/src/lib/libc/port/i18n/gettext_util.c index 2898773e31..d11f71a80d 100644 --- a/usr/src/lib/libc/port/i18n/gettext_util.c +++ b/usr/src/lib/libc/port/i18n/gettext_util.c @@ -67,7 +67,7 @@ static const int category_name_len[] = { * * INPUT * mp - uses the following members: - * msgfile - buffer to store the pathname to the message file + * msgfile - buffer to store the pathname to the message file * binding - directory pathname bound to specified domain * cblen - length of binding * locale - locale name @@ -96,7 +96,7 @@ mk_msgfile(struct msg_pack *mp) p = mp->msgfile; q = mp->binding; - while (*p = *q++) + while ((*p = *q++) != '\0') p++; cblen = (uint32_t)(p - mp->msgfile); if (*(p - 1) != '/') { @@ -126,17 +126,17 @@ mk_msgfile(struct msg_pack *mp) return (NULL); q = mp->locale; - while (*p++ = *q++) + while ((*p++ = *q++) != '\0') ; *(p - 1) = '/'; - while (*p++ = *catstr++) + while ((*p++ = *catstr++) != '\0') ; *(p - 1) = '/'; q = mp->domain; - while (*p = *q++) + while ((*p = *q++) != '\0') p++; q = MSGFILESUFFIX; - while (*p++ = *q++) + while ((*p++ = *q++) != '\0') ; #ifdef GETTEXT_DEBUG diff --git a/usr/src/lib/libc/port/i18n/plural_parser.c b/usr/src/lib/libc/port/i18n/plural_parser.c index 408d1b558d..4b4005ae86 100644 --- a/usr/src/lib/libc/port/i18n/plural_parser.c +++ b/usr/src/lib/libc/port/i18n/plural_parser.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "lint.h" #include <ctype.h> #include <stdio.h> @@ -108,8 +106,7 @@ stack_push(struct stack *stk, struct expr *exp) } static struct expr * -stack_pop(struct stack *stk, - struct expr *exp_a, struct expr *exp_b) +stack_pop(struct stack *stk, struct expr *exp_a, struct expr *exp_b) { if (stk->index == 0) { /* no item */ @@ -123,9 +120,9 @@ stack_pop(struct stack *stk, #ifdef PARSE_DEBUG printf("--- stack_pop ---\n"); printf(" type: %s\n", - type_name[GETTYPE((stk->ptr[stk->index - 1])->op)]); + type_name[GETTYPE((stk->ptr[stk->index - 1])->op)]); printf(" flag: %s\n", - type_name[GETTYPE((stk->ptr[stk->index - 1])->flag)]); + type_name[GETTYPE((stk->ptr[stk->index - 1])->flag)]); printf("-----------------\n"); #endif return (stk->ptr[--stk->index]); @@ -160,7 +157,7 @@ freeexpr(struct expr *e) static struct expr * setop1(unsigned int op, unsigned int num, - struct stack *stk, unsigned int flag) + struct stack *stk, unsigned int flag) { struct expr *newitem; unsigned int type; @@ -187,7 +184,7 @@ setop1(unsigned int op, unsigned int num, static struct expr * setop_reduce(unsigned int n, unsigned int op, struct stack *stk, - struct expr *exp1, struct expr *exp2, struct expr *exp3) + struct expr *exp1, struct expr *exp2, struct expr *exp3) { struct expr *newitem; #ifdef PARSE_DEBUG @@ -199,14 +196,11 @@ setop_reduce(unsigned int n, unsigned int op, struct stack *stk, printf(" op type: %s\n", type_name[type]); switch (n) { case TRINARY: - printf(" exp3 type: %s\n", - type_name[GETTYPE(exp3->op)]); + printf(" exp3 type: %s\n", type_name[GETTYPE(exp3->op)]); case BINARY: - printf(" exp2 type: %s\n", - type_name[GETTYPE(exp2->op)]); + printf(" exp2 type: %s\n", type_name[GETTYPE(exp2->op)]); case UNARY: - printf(" exp1 type: %s\n", - type_name[GETTYPE(exp1->op)]); + printf(" exp1 type: %s\n", type_name[GETTYPE(exp1->op)]); case NARY: break; } @@ -464,8 +458,7 @@ plural_expr(struct expr **e, const char *plural_string) stk = &stkbuf; stk->index = 0; - stk->ptr = (struct expr **)malloc( - sizeof (struct expr *) * MAX_STACK_SIZE); + stk->ptr = malloc(sizeof (struct expr *) * MAX_STACK_SIZE); if (!stk->ptr) { /* malloc failed */ return (-1); @@ -495,7 +488,7 @@ plural_expr(struct expr **e, const char *plural_string) /* parse failed */ #ifdef PARSE_DEBUG printf("ERR: T_EXP is not followed by %s\n", - type_name[type]); + type_name[type]); #endif STACKFREE; return (1); @@ -516,7 +509,7 @@ plural_expr(struct expr **e, const char *plural_string) /* parse failed */ #ifdef PARSE_DEBUG printf("ERR: T_EXP is not followed by %s\n", - type_name[type]); + type_name[type]); #endif STACKFREE; return (1); @@ -536,7 +529,7 @@ plural_expr(struct expr **e, const char *plural_string) /* parse failed */ #ifdef PARSE_DEBUG printf("ERR: T_EXP is not followed by %s\n", - type_name[type]); + type_name[type]); #endif STACKFREE; return (1); @@ -557,7 +550,7 @@ plural_expr(struct expr **e, const char *plural_string) /* parse failed */ #ifdef PARSE_DEBUG printf("ERR: T_EXP is followed by %s\n", - type_name[type]); + type_name[type]); #endif STACKFREE; return (1); @@ -578,7 +571,7 @@ plural_expr(struct expr **e, const char *plural_string) /* parse failed */ #ifdef PARSE_DEBUG printf("ERR: T_EXP is not followed by %s\n", - type_name[type]); + type_name[type]); #endif STACKFREE; return (1); @@ -605,7 +598,7 @@ plural_expr(struct expr **e, const char *plural_string) #ifdef PARSE_DEBUG printf("=========== exp->flag: %s\n", - type_name[ptype]); + type_name[ptype]); #endif if (ptype == T_LPAR) { exp_op = stack_pop(stk, exp, NULL); @@ -621,10 +614,10 @@ plural_expr(struct expr **e, const char *plural_string) } if ((popnum == BINARY) || - (ptype == T_LNOT) || - (ptype == T_CONDC)) { + (ptype == T_LNOT) || + (ptype == T_CONDC)) { result = reduce(&nexp, popnum, - exp, stk); + exp, stk); if (result) return (result); exp = nexp; @@ -634,7 +627,7 @@ plural_expr(struct expr **e, const char *plural_string) freeexpr(exp); STACKFREE; return (1); - } /* for-loop */ + } /* for-loop */ #ifdef PARSE_DEBUG printf("========================= RPAR for loop out\n"); @@ -650,7 +643,7 @@ printf("========================= RPAR for loop out\n"); /* parse failed */ #ifdef PARSE_DEBUG printf("ERR: T_EXP is followed by %s\n", - type_name[type]); + type_name[type]); #endif STACKFREE; return (1); @@ -711,7 +704,7 @@ printf("========================== T_NUM/T_VAR for loop in\n"); fprio = GETPRIO(flag); #ifdef PARSE_DEBUG printf("========= flag: %s\n", - type_name[ftype]); + type_name[ftype]); #endif if ((ftype == T_INIT) || (ftype == T_LPAR)) { exp->flag = flag; @@ -739,10 +732,10 @@ printf("========================== T_NUM/T_VAR for loop in\n"); * T_EQ, T_LAND, T_LOR */ if ((ntype == T_RPAR) || - (nprio <= fprio)) { + (nprio <= fprio)) { /* reduce */ result = reduce(&nexp, BINARY, - exp, stk); + exp, stk); if (result) return (result); exp = nexp; @@ -774,7 +767,7 @@ printf("========================== T_NUM/T_VAR for loop in\n"); if (nprio <= fprio) { /* reduce */ result = reduce(&nexp, TRINARY, - exp, stk); + exp, stk); if (result) return (result); exp = nexp; @@ -803,7 +796,7 @@ printf("======================= T_NUM/T_VAR for loop out\n"); /* parse failed */ STACKFREE; return (1); - } /* while-loop */ + } /* while-loop */ if (GETTYPE(flag) != T_EXP) { /* parse failed */ @@ -823,7 +816,7 @@ printf("======================= T_NUM/T_VAR for loop out\n"); #ifdef PARSE_DEBUG printf("ERR: flag for the result is not T_INIT\n"); printf(" %s observed\n", - type_name[GETTYPE(exp->flag)]); + type_name[GETTYPE(exp->flag)]); #endif freeexpr(exp); STACKFREE; @@ -834,7 +827,7 @@ printf("======================= T_NUM/T_VAR for loop out\n"); * exp still remains in stack. * parse failed */ - while (nexp = stack_pop(stk, NULL, NULL)) + while ((nexp = stack_pop(stk, NULL, NULL)) != NULL) freeexpr(nexp); freeexpr(exp); return (1); @@ -853,8 +846,7 @@ plural_eval(struct expr *exp, unsigned int n) unsigned int e1, e2; unsigned int type, opnum; #ifdef GETTEXT_DEBUG - (void) printf("*************** plural_eval(%p, %d)\n", - exp, n); + (void) printf("*************** plural_eval(%p, %d)\n", exp, n); printexpr(exp, 0); #endif diff --git a/usr/src/lib/libc/port/i18n/wscat.c b/usr/src/lib/libc/port/i18n/wscat.c index eff4beb8a7..263ee6220d 100644 --- a/usr/src/lib/libc/port/i18n/wscat.c +++ b/usr/src/lib/libc/port/i18n/wscat.c @@ -25,9 +25,7 @@ */ /* Copyright (c) 1986 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* All Rights Reserved */ /* * Concatenate s2 on the end of s1. S1's space must be large enough. @@ -49,7 +47,7 @@ wcscat(wchar_t *s1, const wchar_t *s2) while (*s1++) /* find end of s1 */ ; --s1; - while (*s1++ = *s2++) /* copy s2 to s1 */ + while ((*s1++ = *s2++) != 0) /* copy s2 to s1 */ ; return (os1); } diff --git a/usr/src/lib/libc/port/i18n/wscpy.c b/usr/src/lib/libc/port/i18n/wscpy.c index 83c249ab22..a698ab9351 100644 --- a/usr/src/lib/libc/port/i18n/wscpy.c +++ b/usr/src/lib/libc/port/i18n/wscpy.c @@ -24,7 +24,7 @@ */ /* Copyright (c) 1986 AT&T */ -/* All Rights Reserved */ +/* All Rights Reserved */ /* * wcscpy(): copy string s2 to s1. S1 must be large enough. @@ -46,7 +46,7 @@ wcscpy(wchar_t *s1, const wchar_t *s2) { wchar_t *os1 = s1; - while (*s1++ = *s2++) + while ((*s1++ = *s2++) != 0) continue; return (os1); } @@ -60,7 +60,7 @@ wscpy(wchar_t *s1, const wchar_t *s2) wchar_t * wcpcpy(wchar_t *s1, const wchar_t *s2) { - while (*s1++ = *s2++) + while ((*s1++ = *s2++) != 0) continue; return (s1 - 1); } diff --git a/usr/src/lib/libc/port/i18n/wsncat.c b/usr/src/lib/libc/port/i18n/wsncat.c index 6cb78abb07..edcffd7e4f 100644 --- a/usr/src/lib/libc/port/i18n/wsncat.c +++ b/usr/src/lib/libc/port/i18n/wsncat.c @@ -25,9 +25,7 @@ */ /* Copyright (c) 1986 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* All Rights Reserved */ /* * Concatenate s2 on the end of s1. S1's space must be large enough. @@ -51,7 +49,7 @@ wcsncat(wchar_t *s1, const wchar_t *s2, size_t n) ; ++n; --s1; - while (*s1++ = *s2++) /* copy s2 to s1 */ + while ((*s1++ = *s2++) != 0) /* copy s2 to s1 */ if (--n == 0) { /* at most n chars */ *--s1 = 0; break; diff --git a/usr/src/lib/libc/port/regex/wordexp.c b/usr/src/lib/libc/port/regex/wordexp.c index 4c5fb8e5e0..6b34fb4a69 100644 --- a/usr/src/lib/libc/port/regex/wordexp.c +++ b/usr/src/lib/libc/port/regex/wordexp.c @@ -85,7 +85,7 @@ static int append(wordexp_t *, char *); static char * mystpcpy(char *s1, const char *s2) { - while (*s1++ = *s2++) + while ((*s1++ = *s2++) != '\0') ; return (s1-1); } diff --git a/usr/src/lib/smbsrv/libfksmbsrv/common/fake_lookup.c b/usr/src/lib/smbsrv/libfksmbsrv/common/fake_lookup.c index 7cd43cd92e..672b3e666a 100644 --- a/usr/src/lib/smbsrv/libfksmbsrv/common/fake_lookup.c +++ b/usr/src/lib/smbsrv/libfksmbsrv/common/fake_lookup.c @@ -22,10 +22,11 @@ /* * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2022 RackTop Systems, Inc. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ +/* All Rights Reserved */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 @@ -57,6 +58,91 @@ #include <sys/dnlc.h> #include <sys/fs/snode.h> +int +lookupname( + char *fnamep, + enum uio_seg seg, + int followlink, + vnode_t **dirvpp, + vnode_t **compvpp) +{ + return (lookupnameatcred(fnamep, seg, followlink, dirvpp, compvpp, NULL, + CRED())); +} + +/* + * Lookup the user file name, + * Handle allocation and freeing of pathname buffer, return error. + */ +int +lookupnameatcred( + char *fnamep, /* user pathname */ + enum uio_seg seg, /* addr space that name is in */ + int followlink, /* follow sym links */ + vnode_t **dirvpp, /* ret for ptr to parent dir vnode */ + vnode_t **compvpp, /* ret for ptr to component vnode */ + vnode_t *startvp, /* start path search from vp */ + cred_t *cr) /* credential */ +{ + char namebuf[TYPICALMAXPATHLEN]; + struct pathname lookpn; + int error; + + error = pn_get_buf(fnamep, seg, &lookpn, namebuf, sizeof (namebuf)); + if (error == 0) { + error = lookuppnatcred(&lookpn, NULL, followlink, + dirvpp, compvpp, startvp, cr); + } + if (error == ENAMETOOLONG) { + /* + * This thread used a pathname > TYPICALMAXPATHLEN bytes long. + */ + if ((error = pn_get(fnamep, seg, &lookpn)) != 0) + return (error); + error = lookuppnatcred(&lookpn, NULL, followlink, + dirvpp, compvpp, startvp, cr); + pn_free(&lookpn); + } + + return (error); +} + +/* + * Lookup the user file name from a given vp, using a specific credential. + */ +int +lookuppnatcred( + struct pathname *pnp, /* pathname to lookup */ + struct pathname *rpnp, /* if non-NULL, return resolved path */ + int followlink, /* (don't) follow sym links */ + vnode_t **dirvpp, /* ptr for parent vnode */ + vnode_t **compvpp, /* ptr for entry vnode */ + vnode_t *startvp, /* start search from this vp */ + cred_t *cr) /* user credential */ +{ + vnode_t *vp; /* current directory vp */ + vnode_t *rootvp; + + if (pnp->pn_pathlen == 0) + return (ENOENT); + + /* Simplified for fake_... */ + vp = rootvp = rootdir; + + /* + * Skip over leading slashes + */ + if (pnp->pn_path[0] == '/') { + do { + pnp->pn_path++; + pnp->pn_pathlen--; + } while (pnp->pn_path[0] == '/'); + } + + return (lookuppnvp(pnp, rpnp, followlink, dirvpp, + compvpp, rootvp, vp, cr)); +} + /* * Starting at current directory, translate pathname pnp to end. * Leave pathname of final component in pnp, return the vnode diff --git a/usr/src/pkg/manifests/system-bhyve-tests.p5m b/usr/src/pkg/manifests/system-bhyve-tests.p5m index 5ccb080619..d96fa52e80 100644 --- a/usr/src/pkg/manifests/system-bhyve-tests.p5m +++ b/usr/src/pkg/manifests/system-bhyve-tests.p5m @@ -57,6 +57,7 @@ dir path=opt/bhyve-tests/tests/vmm file path=opt/bhyve-tests/tests/vmm/auto_destruct mode=0555 file path=opt/bhyve-tests/tests/vmm/check_iommu mode=0555 file path=opt/bhyve-tests/tests/vmm/cpuid_ioctl mode=0555 +file path=opt/bhyve-tests/tests/vmm/datarw_constraints mode=0555 file path=opt/bhyve-tests/tests/vmm/default_capabs mode=0555 file path=opt/bhyve-tests/tests/vmm/drv_hold mode=0555 file path=opt/bhyve-tests/tests/vmm/fpu_getset mode=0555 diff --git a/usr/src/pkg/manifests/system-test-zfstest.p5m b/usr/src/pkg/manifests/system-test-zfstest.p5m index 17e839569e..d7d3830215 100644 --- a/usr/src/pkg/manifests/system-test-zfstest.p5m +++ b/usr/src/pkg/manifests/system-test-zfstest.p5m @@ -27,6 +27,7 @@ set name=variant.arch value=$(ARCH) dir path=opt/zfs-tests file path=opt/zfs-tests/README mode=0444 dir path=opt/zfs-tests/bin +file path=opt/zfs-tests/bin/btree_test mode=0555 file path=opt/zfs-tests/bin/chg_usr_exec mode=0555 file path=opt/zfs-tests/bin/devname2devid mode=0555 file path=opt/zfs-tests/bin/dir_rd_update mode=0555 @@ -253,6 +254,9 @@ file path=opt/zfs-tests/tests/functional/bootfs/bootfs_007_pos mode=0555 file path=opt/zfs-tests/tests/functional/bootfs/bootfs_008_pos mode=0555 file path=opt/zfs-tests/tests/functional/bootfs/cleanup mode=0555 file path=opt/zfs-tests/tests/functional/bootfs/setup mode=0555 +dir path=opt/zfs-tests/tests/functional/btree +file path=opt/zfs-tests/tests/functional/btree/btree_negative mode=0555 +file path=opt/zfs-tests/tests/functional/btree/btree_positive mode=0555 dir path=opt/zfs-tests/tests/functional/cache file path=opt/zfs-tests/tests/functional/cache/cache.cfg mode=0444 file path=opt/zfs-tests/tests/functional/cache/cache.kshlib mode=0444 diff --git a/usr/src/test/bhyve-tests/runfiles/default.run b/usr/src/test/bhyve-tests/runfiles/default.run index 0bc98232fe..f176fef66c 100644 --- a/usr/src/test/bhyve-tests/runfiles/default.run +++ b/usr/src/test/bhyve-tests/runfiles/default.run @@ -28,6 +28,7 @@ pre = vmm_drv_test_init tests = [ 'auto_destruct', 'cpuid_ioctl', + 'datarw_constraints', 'default_capabs', 'drv_hold', 'fpu_getset', diff --git a/usr/src/test/bhyve-tests/tests/vmm/Makefile b/usr/src/test/bhyve-tests/tests/vmm/Makefile index acab22515b..dd5379add0 100644 --- a/usr/src/test/bhyve-tests/tests/vmm/Makefile +++ b/usr/src/test/bhyve-tests/tests/vmm/Makefile @@ -29,7 +29,8 @@ PROG = mem_partial \ self_destruct \ drv_hold \ cpuid_ioctl \ - default_capabs + default_capabs \ + datarw_constraints SCRIPT = vmm_drv_test_fini vmm_drv_test_init diff --git a/usr/src/test/bhyve-tests/tests/vmm/datarw_constraints.c b/usr/src/test/bhyve-tests/tests/vmm/datarw_constraints.c new file mode 100644 index 0000000000..82b13e2847 --- /dev/null +++ b/usr/src/test/bhyve-tests/tests/vmm/datarw_constraints.c @@ -0,0 +1,111 @@ +/* + * 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 2022 Oxide Computer Company + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> +#include <libgen.h> +#include <sys/stat.h> +#include <errno.h> +#include <err.h> +#include <assert.h> +#include <sys/sysmacros.h> +#include <stdbool.h> + +#include <sys/vmm.h> +#include <sys/vmm_dev.h> +#include <sys/vmm_data.h> +#include <vmmapi.h> + +#include "common.h" + +static void +should_eq_u32(const char *field_name, uint32_t a, uint32_t b) +{ + if (a != b) { + errx(EXIT_FAILURE, "unexpected %s %u != %u", + field_name, a, b); + } +} + +int +main(int argc, char *argv[]) +{ + const char *suite_name = basename(argv[0]); + struct vmctx *ctx; + + ctx = create_test_vm(suite_name); + if (ctx == NULL) { + errx(EXIT_FAILURE, "could not open test VM"); + } + + /* + * Check that vmm_data import/export facility is robust in the face of + * potentially invalid inputs + */ + const int vmfd = vm_get_device_fd(ctx); + + uint8_t buf[sizeof (struct vdi_atpic_v1) + sizeof (int)]; + struct vm_data_xfer vdx = { + .vdx_class = VDC_ATPIC, + .vdx_version = 1, + .vdx_len = sizeof (struct vdi_atpic_v1), + .vdx_data = buf, + }; + + /* Attempt a valid-sized read first */ + if (ioctl(vmfd, VM_DATA_READ, &vdx) != 0) { + err(EXIT_FAILURE, "valid vmm_dat_read failed"); + } + should_eq_u32("vdx_result_len", vdx.vdx_result_len, + sizeof (struct vdi_atpic_v1)); + + /* ... then too-small ... */ + vdx.vdx_len = sizeof (struct vdi_atpic_v1) - sizeof (int); + vdx.vdx_result_len = 0; + if (ioctl(vmfd, VM_DATA_READ, &vdx) == 0) { + errx(EXIT_FAILURE, "invalid vmm_dat_read should have failed"); + } + int error = errno; + if (error != ENOSPC) { + errx(EXIT_FAILURE, "expected ENOSPC errno, got %d", error); + } + /* the "correct" vdx_result_len should still be communicated out */ + should_eq_u32("vdx_result_len", vdx.vdx_result_len, + sizeof (struct vdi_atpic_v1)); + + /* + * ... and too-big to round it out. + * + * This should pass, but still set vdx_result_len to the actual length + */ + vdx.vdx_len = sizeof (struct vdi_atpic_v1) + sizeof (int); + vdx.vdx_result_len = 0; + if (ioctl(vmfd, VM_DATA_READ, &vdx) != 0) { + err(EXIT_FAILURE, "too-large (but valid) vmm_dat_read failed"); + } + should_eq_u32("vdx_result_len", vdx.vdx_result_len, + sizeof (struct vdi_atpic_v1)); + + /* + * The vmm_data_write paths should also be tested, but not until they + * are exposed to the general public without requring mdb -kw settings. + */ + + vm_destroy(ctx); + (void) printf("%s\tPASS\n", suite_name); + return (EXIT_SUCCESS); +} diff --git a/usr/src/test/zfs-tests/cmd/Makefile.subdirs b/usr/src/test/zfs-tests/cmd/Makefile.subdirs index b6cd0d404c..248495b29c 100644 --- a/usr/src/test/zfs-tests/cmd/Makefile.subdirs +++ b/usr/src/test/zfs-tests/cmd/Makefile.subdirs @@ -38,8 +38,6 @@ $(PROG): $(OBJS) install: all $(CMDS) -lint: lint_SRCS - clobber: clean -$(RM) $(PROG) diff --git a/usr/src/test/zfs-tests/cmd/btree_test/Makefile b/usr/src/test/zfs-tests/cmd/btree_test/Makefile new file mode 100644 index 0000000000..d950ca1c36 --- /dev/null +++ b/usr/src/test/zfs-tests/cmd/btree_test/Makefile @@ -0,0 +1,23 @@ +# +# 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 2022 Toomas Soome <tsoome@me.com> +# + +PROG = btree_test + +include $(SRC)/cmd/Makefile.cmd + +CPPFLAGS += -I$(SRC)/uts/common/fs/zfs -DDEBUG +LDLIBS += -lavl -lzpool -lumem + +include ../Makefile.subdirs diff --git a/usr/src/test/zfs-tests/cmd/btree_test/btree_test.c b/usr/src/test/zfs-tests/cmd/btree_test/btree_test.c new file mode 100644 index 0000000000..a5bf976bad --- /dev/null +++ b/usr/src/test/zfs-tests/cmd/btree_test/btree_test.c @@ -0,0 +1,560 @@ +/* + * 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 (c) 2019 by Delphix. All rights reserved. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/avl.h> +#include <sys/btree.h> +#include <sys/time.h> +#include <sys/resource.h> + +#define BUFSIZE 256 + +int seed = 0; +int stress_timeout = 180; +int contents_frequency = 100; +int tree_limit = 64 * 1024; +boolean_t stress_only = B_FALSE; + +static void +usage(int exit_value) +{ + (void) fprintf(stderr, "Usage:\tbtree_test -n <test_name>\n"); + (void) fprintf(stderr, "\tbtree_test -s [-r <seed>] [-l <limit>] " + "[-t timeout>] [-c check_contents]\n"); + (void) fprintf(stderr, "\tbtree_test [-r <seed>] [-l <limit>] " + "[-t timeout>] [-c check_contents]\n"); + (void) fprintf(stderr, "\n With the -n option, run the named " + "negative test. With the -s option,\n"); + (void) fprintf(stderr, " run the stress test according to the " + "other options passed. With\n"); + (void) fprintf(stderr, " neither, run all the positive tests, " + "including the stress test with\n"); + (void) fprintf(stderr, " the default options.\n"); + (void) fprintf(stderr, "\n Options that control the stress test\n"); + (void) fprintf(stderr, "\t-c stress iterations after which to compare " + "tree contents [default: 100]\n"); + (void) fprintf(stderr, "\t-l the largest value to allow in the tree " + "[default: 1M]\n"); + (void) fprintf(stderr, "\t-r random seed [default: from " + "gettimeofday()]\n"); + (void) fprintf(stderr, "\t-t seconds to let the stress test run " + "[default: 180]\n"); + exit(exit_value); +} + +typedef struct int_node { + avl_node_t node; + uint64_t data; +} int_node_t; + +/* + * Utility functions + */ + +static int +avl_compare(const void *v1, const void *v2) +{ + const int_node_t *n1 = v1; + const int_node_t *n2 = v2; + uint64_t a = n1->data; + uint64_t b = n2->data; + + return (TREE_CMP(a, b)); +} + +static int +zfs_btree_compare(const void *v1, const void *v2) +{ + const uint64_t *a = v1; + const uint64_t *b = v2; + + return (TREE_CMP(*a, *b)); +} + +static void +verify_contents(avl_tree_t *avl, zfs_btree_t *bt) +{ + static int count = 0; + zfs_btree_index_t bt_idx = {0}; + int_node_t *node; + uint64_t *data; + + boolean_t forward = count % 2 == 0 ? B_TRUE : B_FALSE; + count++; + + ASSERT3U(avl_numnodes(avl), ==, zfs_btree_numnodes(bt)); + if (forward == B_TRUE) { + node = avl_first(avl); + data = zfs_btree_first(bt, &bt_idx); + } else { + node = avl_last(avl); + data = zfs_btree_last(bt, &bt_idx); + } + + while (node != NULL) { + ASSERT3U(*data, ==, node->data); + if (forward == B_TRUE) { + data = zfs_btree_next(bt, &bt_idx, &bt_idx); + node = AVL_NEXT(avl, node); + } else { + data = zfs_btree_prev(bt, &bt_idx, &bt_idx); + node = AVL_PREV(avl, node); + } + } +} + +static void +verify_node(avl_tree_t *avl, zfs_btree_t *bt, int_node_t *node) +{ + zfs_btree_index_t bt_idx = {0}; + zfs_btree_index_t bt_idx2 = {0}; + int_node_t *inp; + uint64_t data = node->data; + uint64_t *rv = NULL; + + ASSERT3U(avl_numnodes(avl), ==, zfs_btree_numnodes(bt)); + ASSERT3P((rv = (uint64_t *)zfs_btree_find(bt, &data, &bt_idx)), !=, + NULL); + ASSERT3S(*rv, ==, data); + ASSERT3P(zfs_btree_get(bt, &bt_idx), !=, NULL); + ASSERT3S(data, ==, *(uint64_t *)zfs_btree_get(bt, &bt_idx)); + + if ((inp = AVL_NEXT(avl, node)) != NULL) { + ASSERT3P((rv = zfs_btree_next(bt, &bt_idx, &bt_idx2)), !=, + NULL); + ASSERT3P(rv, ==, zfs_btree_get(bt, &bt_idx2)); + ASSERT3S(inp->data, ==, *rv); + } else { + ASSERT3U(data, ==, *(uint64_t *)zfs_btree_last(bt, &bt_idx)); + } + + if ((inp = AVL_PREV(avl, node)) != NULL) { + ASSERT3P((rv = zfs_btree_prev(bt, &bt_idx, &bt_idx2)), !=, + NULL); + ASSERT3P(rv, ==, zfs_btree_get(bt, &bt_idx2)); + ASSERT3S(inp->data, ==, *rv); + } else { + ASSERT3U(data, ==, *(uint64_t *)zfs_btree_first(bt, &bt_idx)); + } +} + +/* + * Tests + */ + +/* Verify that zfs_btree_find works correctly with a NULL index. */ +static int +find_without_index(zfs_btree_t *bt, char *why) +{ + u_longlong_t *p, i = 12345; + + zfs_btree_add(bt, &i); + if ((p = (u_longlong_t *)zfs_btree_find(bt, &i, NULL)) == NULL || + *p != i) { + (void) snprintf(why, BUFSIZE, "Unexpectedly found %llu\n", + p == NULL ? 0 : *p); + return (1); + } + + i++; + + if ((p = (u_longlong_t *)zfs_btree_find(bt, &i, NULL)) != NULL) { + (void) snprintf(why, BUFSIZE, "Found bad value: %llu\n", *p); + return (1); + } + + return (0); +} + +/* Verify simple insertion and removal from the tree. */ +static int +insert_find_remove(zfs_btree_t *bt, char *why) +{ + u_longlong_t *p, i = 12345; + zfs_btree_index_t bt_idx = {0}; + + /* Insert 'i' into the tree, and attempt to find it again. */ + zfs_btree_add(bt, &i); + if ((p = (u_longlong_t *)zfs_btree_find(bt, &i, &bt_idx)) == NULL) { + (void) snprintf(why, BUFSIZE, "Didn't find value in tree\n"); + return (1); + } else if (*p != i) { + (void) snprintf(why, BUFSIZE, "Found (%llu) in tree\n", *p); + return (1); + } + ASSERT3S(zfs_btree_numnodes(bt), ==, 1); + zfs_btree_verify(bt); + + /* Remove 'i' from the tree, and verify it is not found. */ + zfs_btree_remove(bt, &i); + if ((p = (u_longlong_t *)zfs_btree_find(bt, &i, &bt_idx)) != NULL) { + (void) snprintf(why, BUFSIZE, + "Found removed value (%llu)\n", *p); + return (1); + } + ASSERT3S(zfs_btree_numnodes(bt), ==, 0); + zfs_btree_verify(bt); + + return (0); +} + +/* + * Add a number of random entries into a btree and avl tree. Then walk them + * backwards and forwards while emptying the tree, verifying the trees look + * the same. + */ +static int +drain_tree(zfs_btree_t *bt, char *why) +{ + uint64_t *p; + avl_tree_t avl; + int i = 0; + int_node_t *node; + avl_index_t avl_idx = {0}; + zfs_btree_index_t bt_idx = {0}; + + avl_create(&avl, avl_compare, sizeof (int_node_t), + offsetof(int_node_t, node)); + + /* Fill both trees with the same data */ + for (i = 0; i < 64 * 1024; i++) { + void *ret; + + u_longlong_t randval = random(); + if ((p = (uint64_t *)zfs_btree_find(bt, &randval, &bt_idx)) != + NULL) { + continue; + } + zfs_btree_add_idx(bt, &randval, &bt_idx); + + node = malloc(sizeof (int_node_t)); + ASSERT3P(node, !=, NULL); + + node->data = randval; + if ((ret = avl_find(&avl, node, &avl_idx)) != NULL) { + (void) snprintf(why, BUFSIZE, + "Found in avl: %llu\n", randval); + return (1); + } + avl_insert(&avl, node, avl_idx); + } + + /* Remove data from either side of the trees, comparing the data */ + while (avl_numnodes(&avl) != 0) { + uint64_t *data; + + ASSERT3U(avl_numnodes(&avl), ==, zfs_btree_numnodes(bt)); + if (avl_numnodes(&avl) % 2 == 0) { + node = avl_first(&avl); + data = zfs_btree_first(bt, &bt_idx); + } else { + node = avl_last(&avl); + data = zfs_btree_last(bt, &bt_idx); + } + ASSERT3U(node->data, ==, *data); + zfs_btree_remove_idx(bt, &bt_idx); + avl_remove(&avl, node); + + if (avl_numnodes(&avl) == 0) { + break; + } + + node = avl_first(&avl); + ASSERT3U(node->data, ==, + *(uint64_t *)zfs_btree_first(bt, NULL)); + node = avl_last(&avl); + ASSERT3U(node->data, ==, *(uint64_t *)zfs_btree_last(bt, NULL)); + } + ASSERT3S(zfs_btree_numnodes(bt), ==, 0); + + void *avl_cookie = NULL; + while ((node = avl_destroy_nodes(&avl, &avl_cookie)) != NULL) + free(node); + avl_destroy(&avl); + + return (0); +} + +/* + * This test uses an avl and btree, and continually processes new random + * values. Each value is either removed or inserted, depending on whether + * or not it is found in the tree. The test periodically checks that both + * trees have the same data and does consistency checks. This stress + * option can also be run on its own from the command line. + */ +static int +stress_tree(zfs_btree_t *bt, char *why __unused) +{ + avl_tree_t avl; + int_node_t *node; + struct timeval tp; + time_t t0; + int insertions = 0, removals = 0, iterations = 0; + u_longlong_t max = 0, min = UINT64_MAX; + + (void) gettimeofday(&tp, NULL); + t0 = tp.tv_sec; + + avl_create(&avl, avl_compare, sizeof (int_node_t), + offsetof(int_node_t, node)); + + while (1) { + zfs_btree_index_t bt_idx = {0}; + avl_index_t avl_idx = {0}; + + uint64_t randval = random() % tree_limit; + node = malloc(sizeof (*node)); + node->data = randval; + + max = randval > max ? randval : max; + min = randval < min ? randval : min; + + void *ret = avl_find(&avl, node, &avl_idx); + if (ret == NULL) { + insertions++; + avl_insert(&avl, node, avl_idx); + ASSERT3P(zfs_btree_find(bt, &randval, &bt_idx), ==, + NULL); + zfs_btree_add_idx(bt, &randval, &bt_idx); + verify_node(&avl, bt, node); + } else { + removals++; + verify_node(&avl, bt, ret); + zfs_btree_remove(bt, &randval); + avl_remove(&avl, ret); + free(ret); + free(node); + } + + zfs_btree_verify(bt); + + iterations++; + if (iterations % contents_frequency == 0) { + verify_contents(&avl, bt); + } + + zfs_btree_verify(bt); + + (void) gettimeofday(&tp, NULL); + if (tp.tv_sec > t0 + stress_timeout) { + fprintf(stderr, "insertions/removals: %u/%u\nmax/min: " + "%llu/%llu\n", insertions, removals, max, min); + break; + } + } + + void *avl_cookie = NULL; + while ((node = avl_destroy_nodes(&avl, &avl_cookie)) != NULL) + free(node); + avl_destroy(&avl); + + if (stress_only) { + zfs_btree_index_t *idx = NULL; + uint64_t *rv; + + while ((rv = zfs_btree_destroy_nodes(bt, &idx)) != NULL) + ; + zfs_btree_verify(bt); + } + + return (0); +} + +/* + * Verify inserting a duplicate value will cause a crash. + * Note: negative test; return of 0 is a failure. + */ +static int +insert_duplicate(zfs_btree_t *bt) +{ + uint64_t *p, i = 23456; + zfs_btree_index_t bt_idx = {0}; + + if ((p = (uint64_t *)zfs_btree_find(bt, &i, &bt_idx)) != NULL) { + fprintf(stderr, "Found value in empty tree.\n"); + return (0); + } + zfs_btree_add_idx(bt, &i, &bt_idx); + if ((p = (uint64_t *)zfs_btree_find(bt, &i, &bt_idx)) == NULL) { + fprintf(stderr, "Did not find expected value.\n"); + return (0); + } + + /* Crash on inserting a duplicate */ + zfs_btree_add_idx(bt, &i, NULL); + + return (0); +} + +/* + * Verify removing a non-existent value will cause a crash. + * Note: negative test; return of 0 is a failure. + */ +static int +remove_missing(zfs_btree_t *bt) +{ + uint64_t *p, i = 23456; + zfs_btree_index_t bt_idx = {0}; + + if ((p = (uint64_t *)zfs_btree_find(bt, &i, &bt_idx)) != NULL) { + fprintf(stderr, "Found value in empty tree.\n"); + return (0); + } + + /* Crash removing a nonexistent entry */ + zfs_btree_remove(bt, &i); + + return (0); +} + +static int +do_negative_test(zfs_btree_t *bt, char *test_name) +{ + int rval = 0; + struct rlimit rlim = {0}; + + (void) setrlimit(RLIMIT_CORE, &rlim); + + if (strcmp(test_name, "insert_duplicate") == 0) { + rval = insert_duplicate(bt); + } else if (strcmp(test_name, "remove_missing") == 0) { + rval = remove_missing(bt); + } + + /* + * Return 0, since callers will expect non-zero return values for + * these tests, and we should have crashed before getting here anyway. + */ + (void) fprintf(stderr, "Test: %s returned %d.\n", test_name, rval); + return (0); +} + +typedef struct btree_test { + const char *name; + int (*func)(zfs_btree_t *, char *); +} btree_test_t; + +static btree_test_t test_table[] = { + { "insert_find_remove", insert_find_remove }, + { "find_without_index", find_without_index }, + { "drain_tree", drain_tree }, + { "stress_tree", stress_tree }, + { NULL, NULL } +}; + +int +main(int argc, char *argv[]) +{ + char *negative_test = NULL; + int failed_tests = 0; + struct timeval tp; + zfs_btree_t bt; + int c; + + while ((c = getopt(argc, argv, "c:l:n:r:st:")) != -1) { + switch (c) { + case 'c': + contents_frequency = atoi(optarg); + break; + case 'l': + tree_limit = atoi(optarg); + break; + case 'n': + negative_test = optarg; + break; + case 'r': + seed = atoi(optarg); + break; + case 's': + stress_only = B_TRUE; + break; + case 't': + stress_timeout = atoi(optarg); + break; + case 'h': + default: + usage(1); + break; + } + } + argc -= optind; + argv += optind; + optind = 1; + + + if (seed == 0) { + (void) gettimeofday(&tp, NULL); + seed = tp.tv_sec; + } + srandom(seed); + + zfs_btree_init(); + zfs_btree_create(&bt, zfs_btree_compare, sizeof (uint64_t)); + + /* + * This runs the named negative test. None of them should + * return, as they both cause crashes. + */ + if (negative_test) { + return (do_negative_test(&bt, negative_test)); + } + + fprintf(stderr, "Seed: %u\n", seed); + + /* + * This is a stress test that does operations on a btree over the + * requested timeout period, verifying them against identical + * operations in an avl tree. + */ + if (stress_only != 0) { + return (stress_tree(&bt, NULL)); + } + + /* Do the positive tests */ + btree_test_t *test = &test_table[0]; + while (test->name) { + int retval; + uint64_t *rv; + char why[BUFSIZE] = {0}; + zfs_btree_index_t *idx = NULL; + + (void) fprintf(stdout, "%-20s", test->name); + retval = test->func(&bt, why); + + if (retval == 0) { + (void) fprintf(stdout, "ok\n"); + } else { + (void) fprintf(stdout, "failed with %d\n", retval); + if (strlen(why) != 0) + (void) fprintf(stdout, "\t%s\n", why); + why[0] = '\0'; + failed_tests++; + } + + /* Remove all the elements and re-verify the tree */ + while ((rv = zfs_btree_destroy_nodes(&bt, &idx)) != NULL) + ; + zfs_btree_verify(&bt); + + test++; + } + + zfs_btree_verify(&bt); + zfs_btree_fini(); + + return (failed_tests); +} diff --git a/usr/src/test/zfs-tests/include/commands.cfg b/usr/src/test/zfs-tests/include/commands.cfg index 8e9f67627d..dad9372554 100644 --- a/usr/src/test/zfs-tests/include/commands.cfg +++ b/usr/src/test/zfs-tests/include/commands.cfg @@ -10,7 +10,7 @@ # # -# Copyright (c) 2016, 2018 by Delphix. All rights reserved. +# Copyright (c) 2016, 2019 by Delphix. All rights reserved. # Copyright 2020 Joyent, Inc. # @@ -177,7 +177,8 @@ export SBIN_FILES='fdisk zfs zpool' -export ZFSTEST_FILES='chg_usr_exec +export ZFSTEST_FILES='btree_test + chg_usr_exec devname2devid dir_rd_update dos_ro diff --git a/usr/src/test/zfs-tests/runfiles/common.run b/usr/src/test/zfs-tests/runfiles/common.run index c07c97f61e..f58eecec40 100644 --- a/usr/src/test/zfs-tests/runfiles/common.run +++ b/usr/src/test/zfs-tests/runfiles/common.run @@ -74,6 +74,12 @@ tests = ['bootfs_001_pos', 'bootfs_002_neg', 'bootfs_003_pos', 'bootfs_008_pos'] tags = ['functional', 'bootfs'] +[tests/functional/btree] +tests = ['btree_positive', 'btree_negative'] +tags = ['functional', 'btree'] +pre = +post = + [tests/functional/cache] tests = ['cache_001_pos', 'cache_002_pos', 'cache_003_pos', 'cache_004_neg', 'cache_005_neg', 'cache_006_pos', 'cache_007_neg', 'cache_008_neg', diff --git a/usr/src/test/zfs-tests/tests/functional/btree/Makefile b/usr/src/test/zfs-tests/tests/functional/btree/Makefile new file mode 100644 index 0000000000..382bdc881e --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/btree/Makefile @@ -0,0 +1,21 @@ +# +# 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 (c) 2019 by Delphix. All rights reserved. +# + +include $(SRC)/Makefile.master + +ROOTOPTPKG = $(ROOT)/opt/zfs-tests +TARGETDIR = $(ROOTOPTPKG)/tests/functional/btree + +include $(SRC)/test/zfs-tests/Makefile.com diff --git a/usr/src/test/zfs-tests/tests/functional/btree/btree_negative.ksh b/usr/src/test/zfs-tests/tests/functional/btree/btree_negative.ksh new file mode 100755 index 0000000000..399cd5ee98 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/btree/btree_negative.ksh @@ -0,0 +1,38 @@ +#!/usr/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 (c) 2019 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +# +# Description: +# Verify that the btree functions don't allow bad inputs +# +# insert_duplicate - Callers may not add values that are already in the tree +# remove_missing - Callers may not remove values that are not in the tree +# +# Note: These invocations cause btree_test to crash, but the program disables +# core dumps first. As such, we can't use log_mustnot because it explicitly +# looks for return values that correspond to a core dump and cause a test +# failure. + +btree_test -n insert_duplicate +[[ $? -eq 0 ]] && log_fail "Failure from insert_duplicate" + +btree_test -n remove_missing +[[ $? -eq 0 ]] && log_fail "Failure from remove_missing" + +log_pass "Btree negative tests passed" diff --git a/usr/src/test/zfs-tests/tests/functional/btree/btree_positive.ksh b/usr/src/test/zfs-tests/tests/functional/btree/btree_positive.ksh new file mode 100755 index 0000000000..ec58d37a87 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/btree/btree_positive.ksh @@ -0,0 +1,35 @@ +#!/usr/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 (c) 2019 by Delphix. All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +# +# Description: +# The `btree_test` binary runs a series of positive tests when called +# without arguments. +# +# insert_find_remove - Basic functionality test +# find_without_index - Using the find function with a NULL argument +# drain_tree - Fill the tree then empty it using the first and last +# functions +# stress_tree - Allow the tree to have items added and removed for a +# given amount of time +# + +log_must btree_test + +log_pass "Btree positive tests passed" diff --git a/usr/src/uts/common/fs/smbsrv/smb_opipe.c b/usr/src/uts/common/fs/smbsrv/smb_opipe.c index 6742a5c052..0cd4750d49 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_opipe.c +++ b/usr/src/uts/common/fs/smbsrv/smb_opipe.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2018 Nexenta Systems, Inc. All rights reserved. + * Copyright 2022 RackTop Systems, Inc. */ /* @@ -37,6 +38,8 @@ #include <smbsrv/smb_xdr.h> #include <smb/winioctl.h> +static uint32_t smb_opipe_wait(smb_request_t *, smb_fsctl_t *); + /* * Allocate a new opipe and return it, or NULL, in which case * the caller will report "internal error". @@ -148,6 +151,27 @@ smb_opipe_connect(smb_request_t *sr, smb_opipe_t *opipe) return (rc); } +static int +smb_opipe_exists(char *name) +{ + struct sockaddr_un saddr; + vnode_t *vp; /* Underlying filesystem vnode */ + int err; + + bzero(&saddr, sizeof (saddr)); + saddr.sun_family = AF_UNIX; + (void) snprintf(saddr.sun_path, sizeof (saddr.sun_path), + "%s/%s", SMB_PIPE_DIR, name); + + err = lookupname(saddr.sun_path, UIO_SYSSPACE, FOLLOW, NULLVPP, &vp); + if (err == 0) { + VN_RELE(vp); /* release hold from lookup */ + } + + return (err); +} + + /* * Helper for open: encode and send the user info. * @@ -573,9 +597,11 @@ smb_opipe_fsctl(smb_request_t *sr, smb_fsctl_t *fsctl) break; case FSCTL_PIPE_PEEK: + status = NT_STATUS_INVALID_DEVICE_REQUEST; + break; + case FSCTL_PIPE_WAIT: - /* XXX todo */ - status = NT_STATUS_NOT_SUPPORTED; + status = smb_opipe_wait(sr, fsctl); break; default: @@ -655,3 +681,48 @@ smb_opipe_transceive(smb_request_t *sr, smb_fsctl_t *fsctl) return (status); } + +static uint32_t +smb_opipe_wait(smb_request_t *sr, smb_fsctl_t *fsctl) +{ + char *name; + uint64_t timeout; + uint32_t namelen; + int rc; + uint8_t tflag; + + rc = smb_mbc_decodef(fsctl->in_mbc, "qlb.", + &timeout, /* q */ + &namelen, /* l */ + &tflag); /* b */ + if (rc != 0) + return (NT_STATUS_INVALID_PARAMETER); + rc = smb_mbc_decodef(fsctl->in_mbc, "%#U", + sr, /* % */ + namelen, /* # */ + &name); /* U */ + if (rc != 0) + return (NT_STATUS_INVALID_PARAMETER); + + rc = smb_opipe_exists(name); + if (rc != 0) + return (NT_STATUS_OBJECT_NAME_NOT_FOUND); + + /* + * At this point we know the pipe exists. + * + * If the tflag is set, we're supposed to wait for up to + * timeout (100s of milliseconds) for a pipe "instance" + * to become "available" (so pipe open would work). + * However, this implementation has no need to wait, + * so just take a short delay instead. + */ + if (tflag != 0) { + clock_t ticks = MSEC_TO_TICK(timeout * 100); + if (ticks > MSEC_TO_TICK(100)) + ticks = MSEC_TO_TICK(100); + delay(ticks); + } + + return (0); +} diff --git a/usr/src/uts/intel/io/vmm/io/vatpic.c b/usr/src/uts/intel/io/vmm/io/vatpic.c index 3113c0fa48..8cbb26d3d6 100644 --- a/usr/src/uts/intel/io/vmm/io/vatpic.c +++ b/usr/src/uts/intel/io/vmm/io/vatpic.c @@ -803,7 +803,7 @@ vatpic_data_read(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_ATPIC); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_atpic_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_atpic_v1)); struct vatpic *vatpic = datap; struct vdi_atpic_v1 *out = req->vdr_data; @@ -864,7 +864,7 @@ vatpic_data_write(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_ATPIC); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_atpic_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_atpic_v1)); struct vatpic *vatpic = datap; const struct vdi_atpic_v1 *src = req->vdr_data; diff --git a/usr/src/uts/intel/io/vmm/io/vatpit.c b/usr/src/uts/intel/io/vmm/io/vatpit.c index 99c4035e1c..b6218935db 100644 --- a/usr/src/uts/intel/io/vmm/io/vatpit.c +++ b/usr/src/uts/intel/io/vmm/io/vatpit.c @@ -502,7 +502,7 @@ vatpit_data_read(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_ATPIT); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_atpit_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_atpit_v1)); struct vatpit *vatpit = datap; struct vdi_atpit_v1 *out = req->vdr_data; @@ -556,7 +556,7 @@ vatpit_data_write(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_ATPIT); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_atpit_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_atpit_v1)); struct vatpit *vatpit = datap; const struct vdi_atpit_v1 *src = req->vdr_data; diff --git a/usr/src/uts/intel/io/vmm/io/vhpet.c b/usr/src/uts/intel/io/vmm/io/vhpet.c index 979b3aa8fe..d946dbe691 100644 --- a/usr/src/uts/intel/io/vmm/io/vhpet.c +++ b/usr/src/uts/intel/io/vmm/io/vhpet.c @@ -744,7 +744,7 @@ vhpet_data_read(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_HPET); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_hpet_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_hpet_v1)); struct vhpet *vhpet = datap; struct vdi_hpet_v1 *out = req->vdr_data; @@ -789,7 +789,7 @@ static enum vhpet_validation_error vhpet_data_validate(const vmm_data_req_t *req, struct vm *vm) { ASSERT(req->vdr_version == 1 && - req->vdr_len == sizeof (struct vdi_hpet_v1)); + req->vdr_len >= sizeof (struct vdi_hpet_v1)); const struct vdi_hpet_v1 *src = req->vdr_data; /* LegacyReplacement Routing is not supported */ @@ -859,7 +859,7 @@ vhpet_data_write(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_HPET); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_hpet_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_hpet_v1)); struct vhpet *vhpet = datap; diff --git a/usr/src/uts/intel/io/vmm/io/vioapic.c b/usr/src/uts/intel/io/vmm/io/vioapic.c index b4cde71a81..00e56ebb0b 100644 --- a/usr/src/uts/intel/io/vmm/io/vioapic.c +++ b/usr/src/uts/intel/io/vmm/io/vioapic.c @@ -458,7 +458,7 @@ vioapic_data_read(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_IOAPIC); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_ioapic_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_ioapic_v1)); struct vioapic *vioapic = datap; struct vdi_ioapic_v1 *out = req->vdr_data; @@ -480,7 +480,7 @@ vioapic_data_write(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_IOAPIC); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_ioapic_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_ioapic_v1)); struct vioapic *vioapic = datap; const struct vdi_ioapic_v1 *src = req->vdr_data; diff --git a/usr/src/uts/intel/io/vmm/io/vlapic.c b/usr/src/uts/intel/io/vmm/io/vlapic.c index 3127bede2f..e6b5f3be00 100644 --- a/usr/src/uts/intel/io/vmm/io/vlapic.c +++ b/usr/src/uts/intel/io/vmm/io/vlapic.c @@ -1713,7 +1713,7 @@ vlapic_data_read(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_LAPIC); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_lapic_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_lapic_v1)); struct vlapic *vlapic = datap; struct vdi_lapic_v1 *out = req->vdr_data; @@ -1807,7 +1807,7 @@ static enum vlapic_validation_error vlapic_data_validate(const struct vlapic *vlapic, const vmm_data_req_t *req) { ASSERT(req->vdr_version == 1 && - req->vdr_len == sizeof (struct vdi_lapic_v1)); + req->vdr_len >= sizeof (struct vdi_lapic_v1)); const struct vdi_lapic_v1 *src = req->vdr_data; if ((src->vl_esr_pending & ~APIC_VALID_MASK_ESR) != 0 || @@ -1865,7 +1865,7 @@ vlapic_data_write(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_LAPIC); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_lapic_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_lapic_v1)); struct vlapic *vlapic = datap; if (vlapic_data_validate(vlapic, req) != VVE_OK) { diff --git a/usr/src/uts/intel/io/vmm/io/vpmtmr.c b/usr/src/uts/intel/io/vmm/io/vpmtmr.c index cb8713c9d0..514f495874 100644 --- a/usr/src/uts/intel/io/vmm/io/vpmtmr.c +++ b/usr/src/uts/intel/io/vmm/io/vpmtmr.c @@ -161,7 +161,7 @@ vpmtmr_data_read(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_PM_TIMER); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_pm_timer_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_pm_timer_v1)); struct vpmtmr *vpmtmr = datap; struct vdi_pm_timer_v1 *out = req->vdr_data; @@ -177,7 +177,7 @@ vpmtmr_data_write(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_PM_TIMER); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_pm_timer_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_pm_timer_v1)); struct vpmtmr *vpmtmr = datap; const struct vdi_pm_timer_v1 *src = req->vdr_data; diff --git a/usr/src/uts/intel/io/vmm/io/vrtc.c b/usr/src/uts/intel/io/vmm/io/vrtc.c index 906b449ddc..644532f077 100644 --- a/usr/src/uts/intel/io/vmm/io/vrtc.c +++ b/usr/src/uts/intel/io/vmm/io/vrtc.c @@ -975,7 +975,7 @@ vrtc_data_read(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_RTC); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_rtc_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_rtc_v1)); struct vrtc *vrtc = datap; struct vdi_rtc_v1 *out = req->vdr_data; @@ -999,7 +999,7 @@ vrtc_data_write(void *datap, const vmm_data_req_t *req) { VERIFY3U(req->vdr_class, ==, VDC_RTC); VERIFY3U(req->vdr_version, ==, 1); - VERIFY3U(req->vdr_len, ==, sizeof (struct vdi_rtc_v1)); + VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_rtc_v1)); struct vrtc *vrtc = datap; const struct vdi_rtc_v1 *src = req->vdr_data; |