diff options
Diffstat (limited to 'usr/src/cmd')
116 files changed, 4171 insertions, 1462 deletions
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile index 8159ad677b..4f496112e8 100644 --- a/usr/src/cmd/Makefile +++ b/usr/src/cmd/Makefile @@ -446,6 +446,7 @@ COMMON_SUBDIRS= \ utmpd \ uuidgen \ valtools \ + varpd \ vgrind \ vi \ volcheck \ diff --git a/usr/src/cmd/bhyve/README.sync b/usr/src/cmd/bhyve/README.sync index 45a1f759bc..b59e0f399a 100644 --- a/usr/src/cmd/bhyve/README.sync +++ b/usr/src/cmd/bhyve/README.sync @@ -4,12 +4,11 @@ public Git repository at https://git.freebsd.org/src.git The bhyve kernel module and its associated userland consumers have been updated to the latest upstream FreeBSD sources as of: - commit 5ac4ac85ca20ce1f00c84502a65a3291bf416c18 - Author: John Baldwin <jhb@FreeBSD.org> - Date: Wed Sep 15 09:03:17 2021 -0700 + commit 4558c11f1b4dfd7fd505d70b79467eb7f1193f07 + Author: Mark Johnston <markj@FreeBSD.org> + Date: Wed Jan 5 10:08:13 2022 -0500 - Remove an always-true check. - This fixes a -Wtype-limits error from GCC 9. + bhyve: Correct unmapping of the MSI-X table BAR Divergence Notes: diff --git a/usr/src/cmd/bhyve/acpi.c b/usr/src/cmd/bhyve/acpi.c index 76ddf5f5f6..1eb2246b94 100644 --- a/usr/src/cmd/bhyve/acpi.c +++ b/usr/src/cmd/bhyve/acpi.c @@ -77,7 +77,7 @@ __FBSDID("$FreeBSD$"); #include "vmgenc.h" /* - * Define the base address of the ACPI tables, the sizes of some tables, + * Define the base address of the ACPI tables, the sizes of some tables, * and the offsets to the individual tables, */ #define BHYVE_ACPI_BASE 0xf2400 @@ -455,7 +455,7 @@ basl_fwrite_fadt(FILE *fp) EFPRINTF(fp, "[0008]\t\tAddress : 00000000%08X\n", PM1A_EVT_ADDR); EFPRINTF(fp, "\n"); - + EFPRINTF(fp, "[0012]\t\tPM1B Event Block : [Generic Address Structure]\n"); EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); @@ -650,7 +650,7 @@ basl_fwrite_facs(FILE *fp) EFFLUSH(fp); return (0); - + err_exit: return (errno); } @@ -850,7 +850,7 @@ basl_load(struct vmctx *ctx, int fd, uint64_t off) if (fstat(fd, &sb) < 0) return (errno); - + gaddr = paddr_guest2host(ctx, basl_acpi_base + off, sb.st_size); if (gaddr == NULL) return (EFAULT); @@ -884,7 +884,7 @@ basl_compile(struct vmctx *ctx, int (*fwrite_section)(FILE *), uint64_t offset) fmt = basl_verbose_iasl ? "%s -p %s %s" : "/bin/sh -c \"%s -p %s %s\" 1> /dev/null"; - + snprintf(iaslbuf, sizeof(iaslbuf), fmt, BHYVE_ASL_COMPILER, @@ -915,7 +915,7 @@ basl_make_templates(void) err = 0; /* - * + * */ if ((tmpdir = getenv("BHYVE_TMPDIR")) == NULL || *tmpdir == '\0' || (tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0') { diff --git a/usr/src/cmd/bhyve/audio.h b/usr/src/cmd/bhyve/audio.h index 2b559a43e5..88f4dc8709 100644 --- a/usr/src/cmd/bhyve/audio.h +++ b/usr/src/cmd/bhyve/audio.h @@ -28,7 +28,7 @@ * $FreeBSD$ */ -#ifndef _AUDIO_EMUL_H_ +#ifndef _AUDIO_EMUL_H_ #define _AUDIO_EMUL_H_ #include <sys/types.h> diff --git a/usr/src/cmd/bhyve/bhyverun.c b/usr/src/cmd/bhyve/bhyverun.c index 37ec3de164..bf2b784a01 100644 --- a/usr/src/cmd/bhyve/bhyverun.c +++ b/usr/src/cmd/bhyve/bhyverun.c @@ -240,11 +240,11 @@ usage(int code) #endif " %*s [-c [[cpus=]numcpus][,sockets=n][,cores=n][,threads=n]]\n" #ifdef __FreeBSD__ - " %*s [-G port] [-k file] [-l lpc] [-m mem] [-o var=value]\n" + " %*s [-G port] [-k config_file] [-l lpc] [-m mem] [-o var=value]\n" " %*s [-p vcpu:hostcpu] [-r file] [-s pci] [-U uuid] vmname\n" #else - " %*s [-k <file>] [-l <lpc>] [-m mem] [-o <var>=<value>]\n" + " %*s [-k <config_file>] [-l <lpc>] [-m mem] [-o <var>=<value>]\n" " %*s [-s <pci>] [-U uuid] vmname\n" #endif " -A: create ACPI tables\n" @@ -1247,7 +1247,7 @@ do_open(const char *vmname) bool reinit, romboot; #ifndef WITHOUT_CAPSICUM cap_rights_t rights; - const cap_ioctl_t *cmds; + const cap_ioctl_t *cmds; size_t ncmds; #endif @@ -1297,7 +1297,7 @@ do_open(const char *vmname) #ifndef WITHOUT_CAPSICUM cap_rights_init(&rights, CAP_IOCTL, CAP_MMAP_RW); - if (caph_rights_limit(vm_get_device_fd(ctx), &rights) == -1) + if (caph_rights_limit(vm_get_device_fd(ctx), &rights) == -1) errx(EX_OSERR, "Unable to apply rights for sandbox"); vm_get_ioctls(&ncmds); cmds = vm_get_ioctls(NULL); @@ -1307,7 +1307,7 @@ do_open(const char *vmname) errx(EX_OSERR, "Unable to apply rights for sandbox"); free((cap_ioctl_t *)cmds); #endif - + if (reinit) { #ifndef __FreeBSD__ error = vm_reinit(ctx, 0); @@ -1532,7 +1532,7 @@ main(int argc, char *argv[]) set_config_bool("x86.mptable", false); break; case 'h': - usage(0); + usage(0); default: usage(1); } diff --git a/usr/src/cmd/bhyve/block_if.c b/usr/src/cmd/bhyve/block_if.c index 1bb085a8e4..29d55dfdda 100644 --- a/usr/src/cmd/bhyve/block_if.c +++ b/usr/src/cmd/bhyve/block_if.c @@ -143,7 +143,7 @@ struct blockif_ctxt { struct mevent *bc_resize_event; /* Request elements and free/pending/busy queues */ - TAILQ_HEAD(, blockif_elem) bc_freeq; + TAILQ_HEAD(, blockif_elem) bc_freeq; TAILQ_HEAD(, blockif_elem) bc_pendq; TAILQ_HEAD(, blockif_elem) bc_busyq; struct blockif_elem bc_reqs[BLOCKIF_MAXREQ]; @@ -614,7 +614,7 @@ blockif_open(nvlist_t *nvl, const char *ident) #ifndef WITHOUT_CAPSICUM cap_rights_init(&rights, CAP_FSYNC, CAP_IOCTL, CAP_READ, CAP_SEEK, - CAP_WRITE, CAP_FSTAT, CAP_EVENT); + CAP_WRITE, CAP_FSTAT, CAP_EVENT, CAP_FPATHCONF); if (ro) cap_rights_clear(&rights, CAP_FSYNC, CAP_WRITE); diff --git a/usr/src/cmd/bhyve/bootrom.c b/usr/src/cmd/bhyve/bootrom.c index 38a50490eb..cbb05c8c50 100644 --- a/usr/src/cmd/bhyve/bootrom.c +++ b/usr/src/cmd/bhyve/bootrom.c @@ -39,14 +39,17 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <fcntl.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <stdbool.h> #include <vmmapi.h> + #include "bhyverun.h" #include "bootrom.h" #include "debug.h" +#include "mem.h" #define BOOTROM_SIZE (16 * 1024 * 1024) /* 16 MB */ @@ -64,6 +67,56 @@ static vm_paddr_t gpa_base; /* GPA of low end of region. */ static vm_paddr_t gpa_allocbot; /* Low GPA of free region. */ static vm_paddr_t gpa_alloctop; /* High GPA, minus 1, of free region. */ +#define CFI_BCS_WRITE_BYTE 0x10 +#define CFI_BCS_CLEAR_STATUS 0x50 +#define CFI_BCS_READ_STATUS 0x70 +#define CFI_BCS_READ_ARRAY 0xff + +static struct bootrom_var_state { + uint8_t *mmap; + uint64_t gpa; + off_t size; + uint8_t cmd; +} var = { NULL, 0, 0, CFI_BCS_READ_ARRAY }; + +/* + * Emulate just those CFI basic commands that will convince EDK II + * that the Firmware Volume area is writable and persistent. + */ +static int +bootrom_var_mem_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, + int size, uint64_t *val, void *arg1, long arg2) +{ + off_t offset; + + offset = addr - var.gpa; + if (offset + size > var.size || offset < 0 || offset + size <= offset) + return (EINVAL); + + if (dir == MEM_F_WRITE) { + switch (var.cmd) { + case CFI_BCS_WRITE_BYTE: + memcpy(var.mmap + offset, val, size); + var.cmd = CFI_BCS_READ_ARRAY; + break; + default: + var.cmd = *(uint8_t *)val; + } + } else { + switch (var.cmd) { + case CFI_BCS_CLEAR_STATUS: + case CFI_BCS_READ_STATUS: + memset(val, 0, size); + var.cmd = CFI_BCS_READ_ARRAY; + break; + default: + memcpy(val, var.mmap + offset, size); + break; + } + } + return (0); +} + void init_bootrom(struct vmctx *ctx) { @@ -142,10 +195,16 @@ bootrom_loadrom(struct vmctx *ctx, const char *romfile) { struct stat sbuf; ssize_t rlen; - char *ptr; - int fd, i, rv; + off_t rom_size, var_size, total_size; + char *ptr, *varfile; + int fd, varfd, i, rv; rv = -1; + varfd = -1; + + varfile = strdup(romfile); + romfile = strsep(&varfile, ","); + fd = open(romfile, O_RDONLY); if (fd < 0) { EPRINTLN("Error opening bootrom \"%s\": %s", @@ -153,19 +212,56 @@ bootrom_loadrom(struct vmctx *ctx, const char *romfile) goto done; } - if (fstat(fd, &sbuf) < 0) { + if (varfile != NULL) { + varfd = open(varfile, O_RDWR); + if (varfd < 0) { + fprintf(stderr, "Error opening bootrom variable file " + "\"%s\": %s\n", varfile, strerror(errno)); + goto done; + } + } + + if (fstat(fd, &sbuf) < 0) { EPRINTLN("Could not fstat bootrom file \"%s\": %s", - romfile, strerror(errno)); + romfile, strerror(errno)); goto done; - } + } + + rom_size = sbuf.st_size; + if (varfd < 0) { + var_size = 0; + } else { + if (fstat(varfd, &sbuf) < 0) { + fprintf(stderr, "Could not fstat bootrom variable file \"%s\": %s\n", + varfile, strerror(errno)); + goto done; + } + var_size = sbuf.st_size; + } + + if (var_size > BOOTROM_SIZE || + (var_size != 0 && var_size < PAGE_SIZE)) { + fprintf(stderr, "Invalid bootrom variable size %ld\n", + var_size); + goto done; + } + + total_size = rom_size + var_size; + + if (total_size > BOOTROM_SIZE) { + fprintf(stderr, "Invalid bootrom and variable aggregate size " + "%ld\n", total_size); + goto done; + } /* Map the bootrom into the guest address space */ - if (bootrom_alloc(ctx, sbuf.st_size, PROT_READ | PROT_EXEC, - BOOTROM_ALLOC_TOP, &ptr, NULL) != 0) + if (bootrom_alloc(ctx, rom_size, PROT_READ | PROT_EXEC, + BOOTROM_ALLOC_TOP, &ptr, NULL) != 0) { goto done; + } /* Read 'romfile' into the guest address space */ - for (i = 0; i < sbuf.st_size / PAGE_SIZE; i++) { + for (i = 0; i < rom_size / PAGE_SIZE; i++) { rlen = read(fd, ptr + i * PAGE_SIZE, PAGE_SIZE); if (rlen != PAGE_SIZE) { EPRINTLN("Incomplete read of page %d of bootrom " @@ -173,6 +269,31 @@ bootrom_loadrom(struct vmctx *ctx, const char *romfile) goto done; } } + + if (varfd >= 0) { +#ifdef __FreeBSD__ + var.mmap = mmap(NULL, var_size, PROT_READ | PROT_WRITE, + MAP_SHARED, varfd, 0); +#else + var.mmap = (uint8_t *)mmap(NULL, var_size, + PROT_READ | PROT_WRITE, MAP_SHARED, varfd, 0); +#endif + if (var.mmap == MAP_FAILED) + goto done; + var.size = var_size; + var.gpa = (gpa_alloctop - var_size) + 1; + gpa_alloctop = var.gpa - 1; + rv = register_mem(&(struct mem_range){ + .name = "bootrom variable", + .flags = MEM_F_RW, + .handler = bootrom_var_mem_handler, + .base = var.gpa, + .size = var.size, + }); + if (rv != 0) + goto done; + } + rv = 0; done: if (fd >= 0) diff --git a/usr/src/cmd/bhyve/config.c b/usr/src/cmd/bhyve/config.c index db28cc5516..9383e49093 100644 --- a/usr/src/cmd/bhyve/config.c +++ b/usr/src/cmd/bhyve/config.c @@ -228,7 +228,7 @@ _expand_config_value(const char *value, int depth) fputc('%', valfp); vp++; break; - } + } if (vp[1] != '(' || vp[2] == '\0') cp = NULL; else diff --git a/usr/src/cmd/bhyve/config.h b/usr/src/cmd/bhyve/config.h index 9f82afb267..574da966df 100644 --- a/usr/src/cmd/bhyve/config.h +++ b/usr/src/cmd/bhyve/config.h @@ -45,7 +45,7 @@ * Configuration variables are stored in a tree. The full path of a * variable is specified as a dot-separated name similar to sysctl(8) * OIDs. - */ + */ /* * Fetches the value of a configuration variable. If the "raw" value diff --git a/usr/src/cmd/bhyve/fwctl.c b/usr/src/cmd/bhyve/fwctl.c index 0640bc28ba..f0f9aa3aff 100644 --- a/usr/src/cmd/bhyve/fwctl.c +++ b/usr/src/cmd/bhyve/fwctl.c @@ -98,7 +98,7 @@ fwctl_send_rest(uint32_t *data, size_t len) int i; cdata = (uint8_t *) data; - u.w = 0; + u.w = 0; for (i = 0, u.w = 0; i < len; i++) u.c[i] = *cdata++; @@ -472,16 +472,18 @@ fwctl_inb(void) static void fwctl_outw(uint16_t val) { - switch (be_state) { - case IDENT_WAIT: - if (val == 0) { - be_state = IDENT_SEND; - ident_idx = 0; - } - break; - default: - /* ignore */ - break; + if (be_state == DORMANT) { + return; + } + + if (val == 0) { + /* + * The guest wants to read the signature. It's possible that the + * guest is unaware of the fwctl state at this moment. For that + * reason, reset the state machine unconditionally. + */ + be_state = IDENT_SEND; + ident_idx = 0; } } @@ -538,12 +540,32 @@ fwctl_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, return (0); } -INOUT_PORT(fwctl_wreg, FWCTL_OUT, IOPORT_F_INOUT, fwctl_handler); -INOUT_PORT(fwctl_rreg, FWCTL_IN, IOPORT_F_IN, fwctl_handler); void fwctl_init(void) { + struct inout_port iop; + int error; + + bzero(&iop, sizeof(iop)); + iop.name = "fwctl_wreg"; + iop.port = FWCTL_OUT; + iop.size = 1; + iop.flags = IOPORT_F_INOUT; + iop.handler = fwctl_handler; + + error = register_inout(&iop); + assert(error == 0); + + bzero(&iop, sizeof(iop)); + iop.name = "fwctl_rreg"; + iop.port = FWCTL_IN; + iop.size = 1; + iop.flags = IOPORT_F_IN; + iop.handler = fwctl_handler; + + error = register_inout(&iop); + assert(error == 0); ops[OP_GET_LEN] = &fgetlen_info; ops[OP_GET] = &fgetval_info; diff --git a/usr/src/cmd/bhyve/hda_reg.h b/usr/src/cmd/bhyve/hda_reg.h index b3034bf9f4..c309056c6f 100644 --- a/usr/src/cmd/bhyve/hda_reg.h +++ b/usr/src/cmd/bhyve/hda_reg.h @@ -668,7 +668,7 @@ /* Channel Count Control */ #define HDA_CMD_VERB_GET_CONV_CHAN_COUNT 0xf2d -#define HDA_CMD_VERB_SET_CONV_CHAN_COUNT 0x72d +#define HDA_CMD_VERB_SET_CONV_CHAN_COUNT 0x72d #define HDA_CMD_GET_CONV_CHAN_COUNT(cad, nid) \ (HDA_CMD_12BIT((cad), (nid), \ @@ -677,20 +677,20 @@ (HDA_CMD_12BIT((cad), (nid), \ HDA_CMD_VERB_SET_CONV_CHAN_COUNT, (payload))) -#define HDA_CMD_VERB_GET_HDMI_DIP_SIZE 0xf2e +#define HDA_CMD_VERB_GET_HDMI_DIP_SIZE 0xf2e #define HDA_CMD_GET_HDMI_DIP_SIZE(cad, nid, arg) \ (HDA_CMD_12BIT((cad), (nid), \ HDA_CMD_VERB_GET_HDMI_DIP_SIZE, (arg))) -#define HDA_CMD_VERB_GET_HDMI_ELDD 0xf2f +#define HDA_CMD_VERB_GET_HDMI_ELDD 0xf2f #define HDA_CMD_GET_HDMI_ELDD(cad, nid, off) \ (HDA_CMD_12BIT((cad), (nid), \ HDA_CMD_VERB_GET_HDMI_ELDD, (off))) -#define HDA_CMD_VERB_GET_HDMI_DIP_INDEX 0xf30 -#define HDA_CMD_VERB_SET_HDMI_DIP_INDEX 0x730 +#define HDA_CMD_VERB_GET_HDMI_DIP_INDEX 0xf30 +#define HDA_CMD_VERB_SET_HDMI_DIP_INDEX 0x730 #define HDA_CMD_GET_HDMI_DIP_INDEX(cad, nid) \ (HDA_CMD_12BIT((cad), (nid), \ @@ -699,8 +699,8 @@ (HDA_CMD_12BIT((cad), (nid), \ HDA_CMD_VERB_SET_HDMI_DIP_INDEX, (payload))) -#define HDA_CMD_VERB_GET_HDMI_DIP_DATA 0xf31 -#define HDA_CMD_VERB_SET_HDMI_DIP_DATA 0x731 +#define HDA_CMD_VERB_GET_HDMI_DIP_DATA 0xf31 +#define HDA_CMD_VERB_SET_HDMI_DIP_DATA 0x731 #define HDA_CMD_GET_HDMI_DIP_DATA(cad, nid) \ (HDA_CMD_12BIT((cad), (nid), \ @@ -709,8 +709,8 @@ (HDA_CMD_12BIT((cad), (nid), \ HDA_CMD_VERB_SET_HDMI_DIP_DATA, (payload))) -#define HDA_CMD_VERB_GET_HDMI_DIP_XMIT 0xf32 -#define HDA_CMD_VERB_SET_HDMI_DIP_XMIT 0x732 +#define HDA_CMD_VERB_GET_HDMI_DIP_XMIT 0xf32 +#define HDA_CMD_VERB_SET_HDMI_DIP_XMIT 0x732 #define HDA_CMD_GET_HDMI_DIP_XMIT(cad, nid) \ (HDA_CMD_12BIT((cad), (nid), \ @@ -719,11 +719,11 @@ (HDA_CMD_12BIT((cad), (nid), \ HDA_CMD_VERB_SET_HDMI_DIP_XMIT, (payload))) -#define HDA_CMD_VERB_GET_HDMI_CP_CTRL 0xf33 -#define HDA_CMD_VERB_SET_HDMI_CP_CTRL 0x733 +#define HDA_CMD_VERB_GET_HDMI_CP_CTRL 0xf33 +#define HDA_CMD_VERB_SET_HDMI_CP_CTRL 0x733 -#define HDA_CMD_VERB_GET_HDMI_CHAN_SLOT 0xf34 -#define HDA_CMD_VERB_SET_HDMI_CHAN_SLOT 0x734 +#define HDA_CMD_VERB_GET_HDMI_CHAN_SLOT 0xf34 +#define HDA_CMD_VERB_SET_HDMI_CHAN_SLOT 0x734 #define HDA_CMD_GET_HDMI_CHAN_SLOT(cad, nid) \ (HDA_CMD_12BIT((cad), (nid), \ diff --git a/usr/src/cmd/bhyve/mevent.c b/usr/src/cmd/bhyve/mevent.c index a859be6059..576ba3390e 100644 --- a/usr/src/cmd/bhyve/mevent.c +++ b/usr/src/cmd/bhyve/mevent.c @@ -30,11 +30,11 @@ /* * Copyright 2018 Joyent, Inc. - * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2022 OmniOS Community Edition (OmniOSce) Association. */ /* - * Micro event library for FreeBSD, designed for a single i/o thread + * Micro event library for FreeBSD, designed for a single i/o thread * using kqueue, and having events be persistent by default. */ @@ -82,11 +82,15 @@ __FBSDID("$FreeBSD$"); #define EV_ADD EV_ENABLE #define EV_DISABLE 0x02 #define EV_DELETE 0x04 + +static int mevent_file_poll_interval_ms = 5000; #endif static pthread_t mevent_tid; static pthread_once_t mevent_once = PTHREAD_ONCE_INIT; +#ifdef __FreeBSD__ static int mevent_timid = 43; +#endif static int mevent_pipefd[2]; static int mfd; static pthread_mutex_t mevent_lmutex = PTHREAD_MUTEX_INITIALIZER; @@ -112,6 +116,12 @@ struct mevent { boolean_t me_auto_requeue; struct file_obj me_fobj; char *me_fname; + struct { + int mp_fd; + off_t mp_size; + void (*mp_func)(int, enum ev_type, void *); + void *mp_param; + } me_poll; #endif LIST_ENTRY(mevent) me_list; }; @@ -149,7 +159,7 @@ static void mevent_notify(void) { char c = '\0'; - + /* * If calling from outside the i/o thread, write a byte on the * pipe to force the i/o thread to exit the blocking kevent call. @@ -177,7 +187,7 @@ mevent_init(void) cap_rights_init(&rights, CAP_KQUEUE); if (caph_rights_limit(mfd, &rights) == -1) errx(EX_OSERR, "Unable to apply rights for sandbox"); - #endif +#endif LIST_INIT(&change_head); LIST_INIT(&global_head); @@ -213,7 +223,14 @@ mevent_kq_filter(struct mevent *mevp) static int mevent_kq_flags(struct mevent *mevp) { - return (mevp->me_state); + int retval; + + retval = mevp->me_state; + + if (mevp->me_type == EVF_VNODE) + retval |= EV_CLEAR; + + return (retval); } static int @@ -228,6 +245,11 @@ mevent_kq_fflags(struct mevent *mevp) if ((mevp->me_fflags & EVFF_ATTRIB) != 0) retval |= NOTE_ATTRIB; break; + case EVF_READ: + case EVF_WRITE: + case EVF_TIMER: + case EVF_SIGNAL: + break; } return (retval); @@ -370,149 +392,233 @@ mevent_fdpath(int fd) } static void -mevent_update_one(struct mevent *mevp) +mevent_poll_file_attrib(int fd, enum ev_type type, void *param) { - int portfd = mevp->me_notify.portnfy_port; + struct mevent *mevp = param; + struct stat st; - switch (mevp->me_type) { - case EVF_READ: - case EVF_WRITE: - mevp->me_auto_requeue = B_FALSE; + if (fstat(mevp->me_poll.mp_fd, &st) != 0) { + (void) fprintf(stderr, "%s: fstat(%d) \"%s\" failed: %s\n", + __func__, fd, mevp->me_fname, strerror(errno)); + return; + } - switch (mevp->me_state) { - case EV_ENABLE: - { - int events; + if (mevp->me_poll.mp_size != st.st_size || + mevp->me_fobj.fo_ctime.tv_sec != st.st_ctim.tv_sec || + mevp->me_fobj.fo_ctime.tv_nsec != st.st_ctim.tv_nsec) { + mevp->me_poll.mp_size = st.st_size; + mevp->me_fobj.fo_atime = st.st_atim; + mevp->me_fobj.fo_mtime = st.st_mtim; + mevp->me_fobj.fo_ctime = st.st_ctim; - events = (mevp->me_type == EVF_READ) ? POLLIN : POLLOUT; + (*mevp->me_poll.mp_func)(mevp->me_poll.mp_fd, EVF_VNODE, + mevp->me_poll.mp_param); + } +} - if (port_associate(portfd, PORT_SOURCE_FD, mevp->me_fd, - events, mevp) != 0) { - (void) fprintf(stderr, - "port_associate fd %d %p failed: %s\n", - mevp->me_fd, mevp, strerror(errno)); - } - return; +static void +mevent_update_one_readwrite(struct mevent *mevp) +{ + int portfd = mevp->me_notify.portnfy_port; + + mevp->me_auto_requeue = B_FALSE; + + switch (mevp->me_state) { + case EV_ENABLE: + { + const int events = (mevp->me_type == EVF_READ) ? + POLLIN : POLLOUT; + + if (port_associate(portfd, PORT_SOURCE_FD, mevp->me_fd, + events, mevp) != 0) { + (void) fprintf(stderr, + "port_associate fd %d %p failed: %s\n", + mevp->me_fd, mevp, strerror(errno)); } - case EV_DISABLE: - case EV_DELETE: - /* - * A disable that comes in while an event is being - * handled will result in an ENOENT. - */ - if (port_dissociate(portfd, PORT_SOURCE_FD, - mevp->me_fd) != 0 && errno != ENOENT) { - (void) fprintf(stderr, "port_dissociate " - "portfd %d fd %d mevp %p failed: %s\n", - portfd, mevp->me_fd, mevp, strerror(errno)); - } - return; - default: - goto abort; + return; + } + case EV_DISABLE: + case EV_DELETE: + /* + * A disable that comes in while an event is being + * handled will result in an ENOENT. + */ + if (port_dissociate(portfd, PORT_SOURCE_FD, + mevp->me_fd) != 0 && errno != ENOENT) { + (void) fprintf(stderr, "port_dissociate " + "portfd %d fd %d mevp %p failed: %s\n", + portfd, mevp->me_fd, mevp, strerror(errno)); } + return; + default: + (void) fprintf(stderr, "%s: unhandled state %d\n", __func__, + mevp->me_state); + abort(); + } +} - case EVF_TIMER: - mevp->me_auto_requeue = B_TRUE; +static void +mevent_update_one_timer(struct mevent *mevp) +{ + mevp->me_auto_requeue = B_TRUE; - switch (mevp->me_state) { - case EV_ENABLE: - { - struct itimerspec it = { 0 }; + switch (mevp->me_state) { + case EV_ENABLE: + { + struct itimerspec it = { 0 }; - mevp->me_sigev.sigev_notify = SIGEV_PORT; - mevp->me_sigev.sigev_value.sival_ptr = &mevp->me_notify; + mevp->me_sigev.sigev_notify = SIGEV_PORT; + mevp->me_sigev.sigev_value.sival_ptr = &mevp->me_notify; - if (timer_create(CLOCK_REALTIME, &mevp->me_sigev, - &mevp->me_timid) != 0) { - (void) fprintf(stderr, - "timer_create failed: %s", strerror(errno)); - return; - } + if (timer_create(CLOCK_REALTIME, &mevp->me_sigev, + &mevp->me_timid) != 0) { + (void) fprintf(stderr, "timer_create failed: %s", + strerror(errno)); + return; + } - /* The first timeout */ - it.it_value.tv_sec = mevp->me_msecs / MILLISEC; - it.it_value.tv_nsec = - MSEC2NSEC(mevp->me_msecs % MILLISEC); - /* Repeat at the same interval */ - it.it_interval = it.it_value; + /* The first timeout */ + it.it_value.tv_sec = mevp->me_msecs / MILLISEC; + it.it_value.tv_nsec = + MSEC2NSEC(mevp->me_msecs % MILLISEC); + /* Repeat at the same interval */ + it.it_interval = it.it_value; - if (timer_settime(mevp->me_timid, 0, &it, NULL) != 0) { - (void) fprintf(stderr, "timer_settime failed: " - "%s", strerror(errno)); - } - return; + if (timer_settime(mevp->me_timid, 0, &it, NULL) != 0) { + (void) fprintf(stderr, "timer_settime failed: %s", + strerror(errno)); } - case EV_DISABLE: - case EV_DELETE: - if (timer_delete(mevp->me_timid) != 0) { - (void) fprintf(stderr, "timer_delete failed: " - "%s", strerror(errno)); - } - return; - default: - goto abort; + return; + } + case EV_DISABLE: + case EV_DELETE: + if (timer_delete(mevp->me_timid) != 0) { + (void) fprintf(stderr, "timer_delete failed: %s", + strerror(errno)); } + mevp->me_timid = -1; + return; + default: + (void) fprintf(stderr, "%s: unhandled state %d\n", __func__, + mevp->me_state); + abort(); + } +} - case EVF_VNODE: - mevp->me_auto_requeue = B_FALSE; +static void +mevent_update_one_vnode(struct mevent *mevp) +{ + int portfd = mevp->me_notify.portnfy_port; - switch (mevp->me_state) { - case EV_ENABLE: - { - int events = 0; + mevp->me_auto_requeue = B_FALSE; - if ((mevp->me_fflags & EVFF_ATTRIB) != 0) - events |= FILE_ATTRIB; + switch (mevp->me_state) { + case EV_ENABLE: + { + int events = 0; - assert(events != 0); + if ((mevp->me_fflags & EVFF_ATTRIB) != 0) + events |= FILE_ATTRIB; - if (mevp->me_fname == NULL) { - mevp->me_fname = mevent_fdpath(mevp->me_fd); - if (mevp->me_fname == NULL) - return; - } + assert(events != 0); - bzero(&mevp->me_fobj, sizeof (mevp->me_fobj)); - mevp->me_fobj.fo_name = mevp->me_fname; + if (mevp->me_fname == NULL) { + mevp->me_fname = mevent_fdpath(mevp->me_fd); + if (mevp->me_fname == NULL) + return; + } - if (port_associate(portfd, PORT_SOURCE_FILE, - (uintptr_t)&mevp->me_fobj, events, mevp) != 0) { + bzero(&mevp->me_fobj, sizeof (mevp->me_fobj)); + mevp->me_fobj.fo_name = mevp->me_fname; + + if (port_associate(portfd, PORT_SOURCE_FILE, + (uintptr_t)&mevp->me_fobj, events, mevp) != 0) { + /* + * If this file does not support event ports + * (e.g. ZVOLs do not yet have support) + * then convert this to a timer event and poll for + * file attribute changes. + */ + struct stat st; + + if (errno != ENOTSUP) { (void) fprintf(stderr, - "port_associate fd %d (%s) %p failed: %s\n", + "port_associate fd %d (%s) %p failed: %s" + ", polling instead\n", mevp->me_fd, mevp->me_fname, mevp, strerror(errno)); } - return; - } - case EV_DISABLE: - case EV_DELETE: - /* - * A disable that comes in while an event is being - * handled will result in an ENOENT. - */ - if (port_dissociate(portfd, PORT_SOURCE_FILE, - (uintptr_t)&mevp->me_fobj) != 0 && - errno != ENOENT) { - (void) fprintf(stderr, "port_dissociate " - "portfd %d fd %d mevp %p failed: %s\n", - portfd, mevp->me_fd, mevp, strerror(errno)); + + if (fstat(mevp->me_fd, &st) != 0) { + (void) fprintf(stderr, + "fstat(%d) \"%s\" failed: %s\n", + mevp->me_fd, mevp->me_fname, + strerror(errno)); + return; } - free(mevp->me_fname); - mevp->me_fname = NULL; - return; - default: - goto abort; - } + mevp->me_fobj.fo_atime = st.st_atim; + mevp->me_fobj.fo_mtime = st.st_mtim; + mevp->me_fobj.fo_ctime = st.st_ctim; + + mevp->me_poll.mp_fd = mevp->me_fd; + mevp->me_poll.mp_size = st.st_size; + + mevp->me_poll.mp_func = mevp->me_func; + mevp->me_poll.mp_param = mevp->me_param; + mevp->me_func = mevent_poll_file_attrib; + mevp->me_param = mevp; + + mevp->me_type = EVF_TIMER; + mevp->me_timid = -1; + mevp->me_msecs = mevent_file_poll_interval_ms; + mevent_update_one_timer(mevp); + } + return; + } + case EV_DISABLE: + case EV_DELETE: + /* + * A disable that comes in while an event is being + * handled will result in an ENOENT. + */ + if (port_dissociate(portfd, PORT_SOURCE_FILE, + (uintptr_t)&mevp->me_fobj) != 0 && + errno != ENOENT) { + (void) fprintf(stderr, "port_dissociate " + "portfd %d fd %d mevp %p failed: %s\n", + portfd, mevp->me_fd, mevp, strerror(errno)); + } + free(mevp->me_fname); + mevp->me_fname = NULL; + return; default: - /* EVF_SIGNAL not yet implemented. */ - goto abort; + (void) fprintf(stderr, "%s: unhandled state %d\n", __func__, + mevp->me_state); + abort(); } +} -abort: - (void) fprintf(stderr, "%s: unhandled type %d state %d\n", __func__, - mevp->me_type, mevp->me_state); - abort(); +static void +mevent_update_one(struct mevent *mevp) +{ + switch (mevp->me_type) { + case EVF_READ: + case EVF_WRITE: + mevent_update_one_readwrite(mevp); + break; + case EVF_TIMER: + mevent_update_one_timer(mevp); + break; + case EVF_VNODE: + mevent_update_one_vnode(mevp); + break; + case EVF_SIGNAL: /* EVF_SIGNAL not yet implemented. */ + default: + (void) fprintf(stderr, "%s: unhandled event type %d\n", + __func__, mevp->me_type); + abort(); + } } static void @@ -625,13 +731,16 @@ mevent_add_state(int tfd, enum ev_type type, if (type == EVF_TIMER) { mevp->me_msecs = tfd; +#ifdef __FreeBSD__ mevp->me_timid = mevent_timid++; +#else + mevp->me_timid = -1; +#endif } else mevp->me_fd = tfd; mevp->me_type = type; mevp->me_func = func; mevp->me_param = param; - mevp->me_state = state; mevp->me_fflags = fflags; @@ -859,7 +968,7 @@ mevent_dispatch(void) if (ret == -1 && errno != EINTR) { perror("Error return from kevent monitor"); } - + /* * Handle reported events */ @@ -882,5 +991,5 @@ mevent_dispatch(void) /* Handle reported event */ mevent_handle_pe(&pev); #endif /* __FreeBSD__ */ - } + } } diff --git a/usr/src/cmd/bhyve/mevent.h b/usr/src/cmd/bhyve/mevent.h index a26293867a..8c3db9db54 100644 --- a/usr/src/cmd/bhyve/mevent.h +++ b/usr/src/cmd/bhyve/mevent.h @@ -44,7 +44,7 @@ enum ev_type { struct mevent; -struct mevent *mevent_add(int fd, enum ev_type type, +struct mevent *mevent_add(int fd, enum ev_type type, void (*func)(int, enum ev_type, void *), void *param); struct mevent *mevent_add_flags(int fd, enum ev_type type, int fflags, diff --git a/usr/src/cmd/bhyve/mevent_test.c b/usr/src/cmd/bhyve/mevent_test.c index dad8b7773e..37072c5515 100644 --- a/usr/src/cmd/bhyve/mevent_test.c +++ b/usr/src/cmd/bhyve/mevent_test.c @@ -132,7 +132,7 @@ timer_callback(int fd, enum ev_type type, void *param) #ifdef MEVENT_ECHO struct esync { pthread_mutex_t e_mt; - pthread_cond_t e_cond; + pthread_cond_t e_cond; }; static void diff --git a/usr/src/cmd/bhyve/mptbl.c b/usr/src/cmd/bhyve/mptbl.c index fc82faad89..923e0f42f5 100644 --- a/usr/src/cmd/bhyve/mptbl.c +++ b/usr/src/cmd/bhyve/mptbl.c @@ -180,7 +180,7 @@ mpt_build_bus_entries(bus_entry_ptr mpeb) memset(mpeb, 0, sizeof(*mpeb)); mpeb->type = MPCT_ENTRY_BUS; - mpeb->bus_id = 1; + mpeb->bus_id = 1; memcpy(mpeb->bus_type, MPE_BUSNAME_ISA, MPE_BUSNAME_LEN); } @@ -243,7 +243,7 @@ mpt_build_ioint_entries(int_entry_ptr mpie, int id) /* * The following config is taken from kernel mptable.c - * mptable_parse_default_config_ints(...), for now + * mptable_parse_default_config_ints(...), for now * just use the default config, tweek later if needed. */ @@ -287,7 +287,7 @@ mpt_build_ioint_entries(int_entry_ptr mpie, int id) /* Next, generate entries for any PCI INTx interrupts. */ for (bus = 0; bus <= PCI_BUSMAX; bus++) - pci_walk_lintr(bus, mpt_generate_pci_int, &mpie); + pci_walk_lintr(bus, mpt_generate_pci_int, &mpie); } void diff --git a/usr/src/cmd/bhyve/net_backends.c b/usr/src/cmd/bhyve/net_backends.c index 426f330319..329405964e 100644 --- a/usr/src/cmd/bhyve/net_backends.c +++ b/usr/src/cmd/bhyve/net_backends.c @@ -538,7 +538,7 @@ ng_init(struct net_backend *be, const char *devname, /* * The default ng_socket(4) buffer's size is too low. * Calculate the minimum value between NG_SBUF_MAX_SIZE - * and kern.ipc.maxsockbuf. + * and kern.ipc.maxsockbuf. */ msbsz = sizeof(maxsbsz); if (sysctlbyname("kern.ipc.maxsockbuf", &maxsbsz, &msbsz, diff --git a/usr/src/cmd/bhyve/pci_ahci.c b/usr/src/cmd/bhyve/pci_ahci.c index 2416edd166..6f99795ca4 100644 --- a/usr/src/cmd/bhyve/pci_ahci.c +++ b/usr/src/cmd/bhyve/pci_ahci.c @@ -1932,7 +1932,7 @@ ata_ioreq_cb(struct blockif_req *br, int err) if (!err && aior->more) { if (dsm) ahci_handle_dsm_trim(p, slot, cfis, aior->done); - else + else ahci_handle_rw(p, slot, cfis, aior->done); goto out; } @@ -2465,7 +2465,7 @@ pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) sc->ports = p; ret = 1; goto open_fail; - } + } sc->port[p].bctx = bctxt; sc->port[p].pr_sc = sc; sc->port[p].port = p; diff --git a/usr/src/cmd/bhyve/pci_e82545.c b/usr/src/cmd/bhyve/pci_e82545.c index 9f456f06f2..25cf0a48e7 100644 --- a/usr/src/cmd/bhyve/pci_e82545.c +++ b/usr/src/cmd/bhyve/pci_e82545.c @@ -263,7 +263,7 @@ struct e82545_softc { uint32_t esc_FCTTV; /* x0170 flow ctl tx timer */ uint32_t esc_LEDCTL; /* x0E00 LED control */ uint32_t esc_PBA; /* x1000 pkt buffer allocation */ - + /* Interrupt control */ int esc_irq_asserted; uint32_t esc_ICR; /* x00C0 cause read/clear */ @@ -293,12 +293,12 @@ struct e82545_softc { uint32_t esc_TIDV; /* x3820 intr delay */ uint32_t esc_TXDCTL; /* x3828 desc control */ uint32_t esc_TADV; /* x382C intr absolute delay */ - + /* L2 frame acceptance */ struct eth_uni esc_uni[16]; /* 16 x unicast MAC addresses */ uint32_t esc_fmcast[128]; /* Multicast filter bit-match */ uint32_t esc_fvlan[128]; /* VLAN 4096-bit filter */ - + /* Receive */ struct e1000_rx_desc *esc_rxdesc; pthread_cond_t esc_rx_cond; @@ -319,7 +319,7 @@ struct e82545_softc { uint32_t esc_RADV; /* x282C intr absolute delay */ uint32_t esc_RSRPD; /* x2C00 recv small packet detect */ uint32_t esc_RXCSUM; /* x5000 receive cksum ctl */ - + /* IO Port register access */ uint32_t io_addr; @@ -577,7 +577,7 @@ e82545_icr_assert(struct e82545_softc *sc, uint32_t bits) uint32_t new; DPRINTF("icr assert: 0x%x", bits); - + /* * An interrupt is only generated if bits are set that * aren't already in the ICR, these bits are unmasked, @@ -653,7 +653,7 @@ e82545_intr_write(struct e82545_softc *sc, uint32_t offset, uint32_t value) { DPRINTF("intr_write: off %x, val %x", offset, value); - + switch (offset) { case E1000_ICR: e82545_icr_deassert(sc, value); @@ -687,7 +687,7 @@ e82545_intr_read(struct e82545_softc *sc, uint32_t offset) retval = 0; DPRINTF("intr_read: off %x", offset); - + switch (offset) { case E1000_ICR: retval = sc->esc_ICR; @@ -733,10 +733,10 @@ e82545_rx_update_rdba(struct e82545_softc *sc) /* XXX verify desc base/len within phys mem range */ sc->esc_rdba = (uint64_t)sc->esc_RDBAH << 32 | sc->esc_RDBAL; - + /* Cache host mapping of guest descriptor array */ sc->esc_rxdesc = paddr_guest2host(sc->esc_ctx, - sc->esc_rdba, sc->esc_RDLEN); + sc->esc_rdba, sc->esc_RDLEN); } static void @@ -791,7 +791,7 @@ static void e82545_tx_ctl(struct e82545_softc *sc, uint32_t val) { int on; - + on = ((val & E1000_TCTL_EN) == E1000_TCTL_EN); /* ignore TCTL_EN settings that don't change state */ @@ -1031,7 +1031,7 @@ e82545_txdesc_type(uint32_t lower) int type; type = 0; - + if (lower & E1000_TXD_CMD_DEXT) type = lower & E1000_TXD_MASK; @@ -1087,7 +1087,7 @@ e82545_transmit(struct e82545_softc *sc, uint16_t head, uint16_t tail, struct ck_info ckinfo[2]; struct iovec *iov; union e1000_tx_udesc *dsc; - int desc, dtype, len, ntype, iovcnt, tlen, tcp, tso; + int desc, dtype, len, ntype, iovcnt, tcp, tso; int mss, paylen, seg, tiovcnt, left, now, nleft, nnow, pv, pvoff; unsigned hdrlen, vlen; uint32_t tcpsum, tcpseq; @@ -1095,7 +1095,6 @@ e82545_transmit(struct e82545_softc *sc, uint16_t head, uint16_t tail, ckinfo[0].ck_valid = ckinfo[1].ck_valid = 0; iovcnt = 0; - tlen = 0; ntype = 0; tso = 0; ohead = head; @@ -1153,7 +1152,6 @@ e82545_transmit(struct e82545_softc *sc, uint16_t head, uint16_t tail, if ((dsc->td.lower.data & E1000_TXD_CMD_EOP) != 0 && (dsc->td.lower.data & E1000_TXD_CMD_IFCS) == 0) len -= 2; - tlen += len; if (iovcnt < I82545_MAX_TXSEGS) { iov[iovcnt].iov_base = paddr_guest2host( sc->esc_ctx, dsc->td.buffer_addr, len); @@ -1608,14 +1606,14 @@ e82545_read_ra(struct e82545_softc *sc, int reg) eu->eu_eth.octet[0]; } - return (retval); + return (retval); } static void e82545_write_register(struct e82545_softc *sc, uint32_t offset, uint32_t value) { int ridx; - + if (offset & 0x3) { DPRINTF("Unaligned register write offset:0x%x value:0x%x", offset, value); return; @@ -1761,7 +1759,7 @@ e82545_write_register(struct e82545_softc *sc, uint32_t offset, uint32_t value) break; case E1000_VFTA ... (E1000_VFTA + (127*4)): sc->esc_fvlan[(offset - E1000_VFTA) >> 2] = value; - break; + break; case E1000_EECD: { //DPRINTF("EECD write 0x%x -> 0x%x", sc->eeprom_control, value); @@ -1816,7 +1814,7 @@ e82545_write_register(struct e82545_softc *sc, uint32_t offset, uint32_t value) return; } case E1000_MANC: - case E1000_STATUS: + case E1000_STATUS: return; default: DPRINTF("Unknown write register: 0x%x value:%x", offset, value); @@ -1909,7 +1907,7 @@ e82545_read_register(struct e82545_softc *sc, uint32_t offset) case E1000_RSRPD: retval = sc->esc_RSRPD; break; - case E1000_RXCSUM: + case E1000_RXCSUM: retval = sc->esc_RXCSUM; break; case E1000_TXCW: @@ -1958,7 +1956,7 @@ e82545_read_register(struct e82545_softc *sc, uint32_t offset) break; case E1000_VFTA ... (E1000_VFTA + (127*4)): retval = sc->esc_fvlan[(offset - E1000_VFTA) >> 2]; - break; + break; case E1000_EECD: //DPRINTF("EECD read %x", sc->eeprom_control); retval = sc->eeprom_control; @@ -2154,7 +2152,7 @@ e82545_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, { struct e82545_softc *sc; uint64_t retval; - + //DPRINTF("Read bar:%d offset:0x%lx size:%d", baridx, offset, size); sc = pi->pi_arg; retval = 0; @@ -2226,7 +2224,7 @@ e82545_reset(struct e82545_softc *sc, int drvr) } sc->esc_LEDCTL = 0x07061302; sc->esc_PBA = 0x00100030; - + /* start nvm in opcode mode. */ sc->nvm_opaddr = 0; sc->nvm_mode = E82545_NVM_MODE_OPADDR; @@ -2240,7 +2238,7 @@ e82545_reset(struct e82545_softc *sc, int drvr) sc->esc_ICS = 0; sc->esc_IMS = 0; sc->esc_IMC = 0; - + /* L2 filters */ if (!drvr) { memset(sc->esc_fvlan, 0, sizeof(sc->esc_fvlan)); @@ -2256,7 +2254,7 @@ e82545_reset(struct e82545_softc *sc, int drvr) for (i = 0; i < 16; i++) sc->esc_uni[i].eu_valid = 0; } - + /* receive */ if (!drvr) { sc->esc_RDBAL = 0; @@ -2324,7 +2322,7 @@ e82545_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) pci_set_cfgdata8(pi, PCIR_HDRTYPE, PCIM_HDRTYPE_NORMAL); pci_set_cfgdata8(pi, PCIR_INTPIN, 0x1); - + /* TODO: this card also supports msi, but the freebsd driver for it * does not, so I have not implemented it. */ pci_lintr_request(pi); diff --git a/usr/src/cmd/bhyve/pci_emul.c b/usr/src/cmd/bhyve/pci_emul.c index ce218b8185..3cbf01158a 100644 --- a/usr/src/cmd/bhyve/pci_emul.c +++ b/usr/src/cmd/bhyve/pci_emul.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include <sys/linker_set.h> #include <ctype.h> +#include <err.h> #include <errno.h> #include <pthread.h> #include <stdio.h> @@ -56,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include <strings.h> #include <assert.h> #include <stdbool.h> +#include <sysexits.h> #include <machine/vmm.h> #include <vmmapi.h> @@ -80,6 +82,8 @@ __FBSDID("$FreeBSD$"); #define MAXSLOTS (PCI_SLOTMAX + 1) #define MAXFUNCS (PCI_FUNCMAX + 1) +#define GB (1024 * 1024 * 1024UL) + struct funcinfo { nvlist_t *fi_config; struct pci_devemu *fi_pde; @@ -111,6 +115,17 @@ SET_DECLARE(pci_devemu_set, struct pci_devemu); static uint64_t pci_emul_iobase; static uint64_t pci_emul_membase32; static uint64_t pci_emul_membase64; +static uint64_t pci_emul_memlim64; + +struct pci_bar_allocation { + TAILQ_ENTRY(pci_bar_allocation) chain; + struct pci_devinst *pdi; + int idx; + enum pcibar_type type; + uint64_t size; +}; +TAILQ_HEAD(pci_bar_list, pci_bar_allocation) pci_bars = TAILQ_HEAD_INITIALIZER( + pci_bars); #define PCI_EMUL_IOBASE 0x2000 #define PCI_EMUL_IOLIMIT 0x10000 @@ -119,10 +134,13 @@ static uint64_t pci_emul_membase64; #define PCI_EMUL_ECFG_SIZE (MAXBUSES * 1024 * 1024) /* 1MB per bus */ SYSRES_MEM(PCI_EMUL_ECFG_BASE, PCI_EMUL_ECFG_SIZE); +/* + * OVMF always uses 0xC0000000 as base address for 32 bit PCI MMIO. Don't + * change this address without changing it in OVMF. + */ +#define PCI_EMUL_MEMBASE32 0xC0000000 #define PCI_EMUL_MEMLIMIT32 PCI_EMUL_ECFG_BASE - -#define PCI_EMUL_MEMBASE64 0xD000000000UL -#define PCI_EMUL_MEMLIMIT64 0xFD00000000UL +#define PCI_EMUL_MEMSIZE64 (32*GB) static struct pci_devemu *pci_emul_finddev(const char *name); static void pci_lintr_route(struct pci_devinst *pi); @@ -643,12 +661,6 @@ int pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, enum pcibar_type type, uint64_t size) { - uint64_t *baseptr = NULL; - uint64_t limit = 0, lobits = 0; - uint64_t addr, mask, bar; - uint16_t cmd, enbit; - int error; - assert(idx >= 0 && idx <= PCI_BARMAX); if ((size & (size - 1)) != 0) @@ -663,17 +675,88 @@ pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, enum pcibar_type type, size = 16; } + /* + * To reduce fragmentation of the MMIO space, we allocate the BARs by + * size. Therefore, don't allocate the BAR yet. We create a list of all + * BAR allocation which is sorted by BAR size. When all PCI devices are + * initialized, we will assign an address to the BARs. + */ + + /* create a new list entry */ + struct pci_bar_allocation *const new_bar = malloc(sizeof(*new_bar)); + memset(new_bar, 0, sizeof(*new_bar)); + new_bar->pdi = pdi; + new_bar->idx = idx; + new_bar->type = type; + new_bar->size = size; + + /* + * Search for a BAR which size is lower than the size of our newly + * allocated BAR. + */ + struct pci_bar_allocation *bar = NULL; + TAILQ_FOREACH(bar, &pci_bars, chain) { + if (bar->size < size) { + break; + } + } + + if (bar == NULL) { + /* + * Either the list is empty or new BAR is the smallest BAR of + * the list. Append it to the end of our list. + */ + TAILQ_INSERT_TAIL(&pci_bars, new_bar, chain); + } else { + /* + * The found BAR is smaller than our new BAR. For that reason, + * insert our new BAR before the found BAR. + */ + TAILQ_INSERT_BEFORE(bar, new_bar, chain); + } + + /* + * pci_passthru devices synchronize their physical and virtual command + * register on init. For that reason, the virtual cmd reg should be + * updated as early as possible. + */ + uint16_t enbit = 0; + switch (type) { + case PCIBAR_IO: + enbit = PCIM_CMD_PORTEN; + break; + case PCIBAR_MEM64: + case PCIBAR_MEM32: + enbit = PCIM_CMD_MEMEN; + break; + default: + enbit = 0; + break; + } + + const uint16_t cmd = pci_get_cfgdata16(pdi, PCIR_COMMAND); + pci_set_cfgdata16(pdi, PCIR_COMMAND, cmd | enbit); + + return (0); +} + +static int +pci_emul_assign_bar(struct pci_devinst *const pdi, const int idx, + const enum pcibar_type type, const uint64_t size) +{ + int error; + uint64_t *baseptr, limit, addr, mask, lobits, bar; + switch (type) { case PCIBAR_NONE: baseptr = NULL; - addr = mask = lobits = enbit = 0; + addr = mask = lobits = 0; break; case PCIBAR_IO: baseptr = &pci_emul_iobase; limit = PCI_EMUL_IOLIMIT; mask = PCIM_BAR_IO_BASE; lobits = PCIM_BAR_IO_SPACE; - enbit = PCIM_CMD_PORTEN; break; case PCIBAR_MEM64: /* @@ -685,7 +768,7 @@ pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, enum pcibar_type type, */ if (size > 128 * 1024 * 1024) { baseptr = &pci_emul_membase64; - limit = PCI_EMUL_MEMLIMIT64; + limit = pci_emul_memlim64; mask = PCIM_BAR_MEM_BASE; lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 | PCIM_BAR_MEM_PREFETCH; @@ -695,14 +778,12 @@ pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, enum pcibar_type type, mask = PCIM_BAR_MEM_BASE; lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64; } - enbit = PCIM_CMD_MEMEN; break; case PCIBAR_MEM32: baseptr = &pci_emul_membase32; limit = PCI_EMUL_MEMLIMIT32; mask = PCIM_BAR_MEM_BASE; lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32; - enbit = PCIM_CMD_MEMEN; break; default: printf("pci_emul_alloc_base: invalid bar type %d\n", type); @@ -722,6 +803,15 @@ pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, enum pcibar_type type, pdi->pi_bar[idx].type = type; pdi->pi_bar[idx].addr = addr; pdi->pi_bar[idx].size = size; + /* + * passthru devices are using same lobits as physical device they set + * this property + */ + if (pdi->pi_bar[idx].lobits != 0) { + lobits = pdi->pi_bar[idx].lobits; + } else { + pdi->pi_bar[idx].lobits = lobits; + } /* Initialize the BAR register in config space */ bar = (addr & mask) | lobits; @@ -733,9 +823,6 @@ pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, enum pcibar_type type, pci_set_cfgdata32(pdi, PCIR_BAR(idx + 1), bar >> 32); } - cmd = pci_get_cfgdata16(pdi, PCIR_COMMAND); - if ((cmd & enbit) != enbit) - pci_set_cfgdata16(pdi, PCIR_COMMAND, cmd | enbit); register_bar(pdi, idx); return (0); @@ -1147,7 +1234,8 @@ pci_ecfg_base(void) } #define BUSIO_ROUNDUP 32 -#define BUSMEM_ROUNDUP (1024 * 1024) +#define BUSMEM32_ROUNDUP (1024 * 1024) +#define BUSMEM64_ROUNDUP (512 * 1024 * 1024) int init_pci(struct vmctx *ctx) @@ -1164,9 +1252,15 @@ init_pci(struct vmctx *ctx) int bus, slot, func; int error; + if (vm_get_lowmem_limit(ctx) > PCI_EMUL_MEMBASE32) + errx(EX_OSERR, "Invalid lowmem limit"); + pci_emul_iobase = PCI_EMUL_IOBASE; - pci_emul_membase32 = vm_get_lowmem_limit(ctx); - pci_emul_membase64 = PCI_EMUL_MEMBASE64; + pci_emul_membase32 = PCI_EMUL_MEMBASE32; + + pci_emul_membase64 = 4*GB + vm_get_highmem_size(ctx); + pci_emul_membase64 = roundup2(pci_emul_membase64, PCI_EMUL_MEMSIZE64); + pci_emul_memlim64 = pci_emul_membase64 + PCI_EMUL_MEMSIZE64; for (bus = 0; bus < MAXBUSES; bus++) { snprintf(node_name, sizeof(node_name), "pci.%d", bus); @@ -1184,6 +1278,7 @@ init_pci(struct vmctx *ctx) bi->membase32 = pci_emul_membase32; bi->membase64 = pci_emul_membase64; + /* first run: init devices */ for (slot = 0; slot < MAXSLOTS; slot++) { si = &bi->slotinfo[slot]; for (func = 0; func < MAXFUNCS; func++) { @@ -1223,6 +1318,16 @@ init_pci(struct vmctx *ctx) } } + /* second run: assign BARs and free list */ + struct pci_bar_allocation *bar; + struct pci_bar_allocation *bar_tmp; + TAILQ_FOREACH_SAFE(bar, &pci_bars, chain, bar_tmp) { + pci_emul_assign_bar(bar->pdi, bar->idx, bar->type, + bar->size); + free(bar); + } + TAILQ_INIT(&pci_bars); + /* * Add some slop to the I/O and memory resources decoded by * this bus to give a guest some flexibility if it wants to @@ -1232,14 +1337,14 @@ init_pci(struct vmctx *ctx) pci_emul_iobase = roundup2(pci_emul_iobase, BUSIO_ROUNDUP); bi->iolimit = pci_emul_iobase; - pci_emul_membase32 += BUSMEM_ROUNDUP; + pci_emul_membase32 += BUSMEM32_ROUNDUP; pci_emul_membase32 = roundup2(pci_emul_membase32, - BUSMEM_ROUNDUP); + BUSMEM32_ROUNDUP); bi->memlimit32 = pci_emul_membase32; - pci_emul_membase64 += BUSMEM_ROUNDUP; + pci_emul_membase64 += BUSMEM64_ROUNDUP; pci_emul_membase64 = roundup2(pci_emul_membase64, - BUSMEM_ROUNDUP); + BUSMEM64_ROUNDUP); bi->memlimit64 = pci_emul_membase64; } @@ -1267,8 +1372,8 @@ init_pci(struct vmctx *ctx) /* * The guest physical memory map looks like the following: * [0, lowmem) guest system memory - * [lowmem, lowmem_limit) memory hole (may be absent) - * [lowmem_limit, 0xE0000000) PCI hole (32-bit BAR allocation) + * [lowmem, 0xC0000000) memory hole (may be absent) + * [0xC0000000, 0xE0000000) PCI hole (32-bit BAR allocation) * [0xE0000000, 0xF0000000) PCI extended config window * [0xF0000000, 4GB) LAPIC, IOAPIC, HPET, firmware * [4GB, 4GB + highmem) @@ -1954,7 +2059,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, case PCIBAR_IO: addr = *eax & mask; addr &= 0xffff; - bar = addr | PCIM_BAR_IO_SPACE; + bar = addr | pi->pi_bar[idx].lobits; /* * Register the new BAR value for interception */ @@ -1965,7 +2070,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, break; case PCIBAR_MEM32: addr = bar = *eax & mask; - bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32; + bar |= pi->pi_bar[idx].lobits; if (addr != pi->pi_bar[idx].addr) { update_bar_address(pi, addr, idx, PCIBAR_MEM32); @@ -1973,8 +2078,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, break; case PCIBAR_MEM64: addr = bar = *eax & mask; - bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 | - PCIM_BAR_MEM_PREFETCH; + bar |= pi->pi_bar[idx].lobits; if (addr != (uint32_t)pi->pi_bar[idx].addr) { update_bar_address(pi, addr, idx, PCIBAR_MEM64); @@ -2026,7 +2130,7 @@ pci_emul_cfgaddr(struct vmctx *ctx, int vcpu, int in, int port, int bytes, } else { x = *eax; cfgenable = (x & CONF1_ENABLE) == CONF1_ENABLE; - cfgoff = x & PCI_REGMAX; + cfgoff = (x & PCI_REGMAX) & ~0x03; cfgfunc = (x >> 8) & PCI_FUNCMAX; cfgslot = (x >> 11) & PCI_SLOTMAX; cfgbus = (x >> 16) & PCI_BUSMAX; diff --git a/usr/src/cmd/bhyve/pci_emul.h b/usr/src/cmd/bhyve/pci_emul.h index cc3a8c048c..d01d2a7596 100644 --- a/usr/src/cmd/bhyve/pci_emul.h +++ b/usr/src/cmd/bhyve/pci_emul.h @@ -99,6 +99,7 @@ struct pcibar { enum pcibar_type type; /* io or memory */ uint64_t size; uint64_t addr; + uint8_t lobits; }; #define PI_NAMESZ 40 @@ -109,7 +110,7 @@ struct msix_table_entry { uint32_t vector_control; } __packed; -/* +/* * In case the structure is modified to hold extra information, use a define * for the size that should be emulated. */ @@ -155,10 +156,12 @@ struct pci_devinst { int table_count; uint32_t pba_offset; int pba_size; - int function_mask; + int function_mask; struct msix_table_entry *table; /* allocated at runtime */ void *pba_page; int pba_page_offset; + uint8_t *mapped_addr; + size_t mapped_size; } pi_msix; void *pi_arg; /* devemu-private data */ @@ -257,21 +260,21 @@ void pci_write_dsdt(void); uint64_t pci_ecfg_base(void); int pci_bus_configured(int bus); -static __inline void +static __inline void pci_set_cfgdata8(struct pci_devinst *pi, int offset, uint8_t val) { assert(offset <= PCI_REGMAX); *(uint8_t *)(pi->pi_cfgdata + offset) = val; } -static __inline void +static __inline void pci_set_cfgdata16(struct pci_devinst *pi, int offset, uint16_t val) { assert(offset <= (PCI_REGMAX - 1) && (offset & 1) == 0); *(uint16_t *)(pi->pi_cfgdata + offset) = val; } -static __inline void +static __inline void pci_set_cfgdata32(struct pci_devinst *pi, int offset, uint32_t val) { assert(offset <= (PCI_REGMAX - 3) && (offset & 3) == 0); diff --git a/usr/src/cmd/bhyve/pci_fbuf.c b/usr/src/cmd/bhyve/pci_fbuf.c index 76041f8667..fad064ebf8 100644 --- a/usr/src/cmd/bhyve/pci_fbuf.c +++ b/usr/src/cmd/bhyve/pci_fbuf.c @@ -231,11 +231,11 @@ pci_fbuf_baraddr(struct vmctx *ctx, struct pci_devinst *pi, int baridx, return; sc = pi->pi_arg; - if (!enabled && sc->fbaddr != 0) { + if (!enabled) { if (vm_munmap_memseg(ctx, sc->fbaddr, FB_SIZE) != 0) EPRINTLN("pci_fbuf: munmap_memseg failed"); sc->fbaddr = 0; - } else if (sc->fb_base != NULL && sc->fbaddr == 0) { + } else { prot = PROT_READ | PROT_WRITE; if (vm_mmap_memseg(ctx, address, VM_FRAMEBUFFER, 0, FB_SIZE, prot) != 0) EPRINTLN("pci_fbuf: mmap_memseg failed"); @@ -383,9 +383,9 @@ pci_fbuf_render(struct bhyvegc *gc, void *arg) static int pci_fbuf_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) { - int error, prot; + int error; struct pci_fbuf_softc *sc; - + if (fbuf_sc != NULL) { EPRINTLN("Only one frame buffer device is allowed."); return (-1); @@ -401,6 +401,13 @@ pci_fbuf_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_DISPLAY); pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_DISPLAY_VGA); + sc->fb_base = vm_create_devmem( + ctx, VM_FRAMEBUFFER, "framebuffer", FB_SIZE); + if (sc->fb_base == MAP_FAILED) { + error = -1; + goto done; + } + error = pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, DMEMSZ); assert(error == 0); @@ -410,7 +417,6 @@ pci_fbuf_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) error = pci_emul_add_msicap(pi, PCI_FBUF_MSI_MSGS); assert(error == 0); - sc->fbaddr = pi->pi_bar[1].addr; sc->memregs.fbsize = FB_SIZE; sc->memregs.width = COLS_DEFAULT; sc->memregs.height = ROWS_DEFAULT; @@ -431,27 +437,9 @@ pci_fbuf_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) goto done; } - sc->fb_base = vm_create_devmem(ctx, VM_FRAMEBUFFER, "framebuffer", FB_SIZE); - if (sc->fb_base == MAP_FAILED) { - error = -1; - goto done; - } DPRINTF(DEBUG_INFO, ("fbuf frame buffer base: %p [sz %lu]", sc->fb_base, FB_SIZE)); - /* - * Map the framebuffer into the guest address space. - * XXX This may fail if the BAR is different than a prior - * run. In this case flag the error. This will be fixed - * when a change_memseg api is available. - */ - prot = PROT_READ | PROT_WRITE; - if (vm_mmap_memseg(ctx, sc->fbaddr, VM_FRAMEBUFFER, 0, FB_SIZE, prot) != 0) { - EPRINTLN("pci_fbuf: mapseg failed - try deleting VM and restarting"); - error = -1; - goto done; - } - console_init(sc->memregs.width, sc->memregs.height, sc->fb_base); console_fb_register(pci_fbuf_render, sc); diff --git a/usr/src/cmd/bhyve/pci_hda.h b/usr/src/cmd/bhyve/pci_hda.h index 65a85f6d60..a34366dedc 100644 --- a/usr/src/cmd/bhyve/pci_hda.h +++ b/usr/src/cmd/bhyve/pci_hda.h @@ -28,7 +28,7 @@ * $FreeBSD$ */ -#ifndef _HDA_EMUL_H_ +#ifndef _HDA_EMUL_H_ #define _HDA_EMUL_H_ #include <stdio.h> diff --git a/usr/src/cmd/bhyve/pci_lpc.c b/usr/src/cmd/bhyve/pci_lpc.c index 2387f382c5..189623b5fc 100644 --- a/usr/src/cmd/bhyve/pci_lpc.c +++ b/usr/src/cmd/bhyve/pci_lpc.c @@ -164,7 +164,7 @@ lpc_uart_intr_assert(void *arg) static void lpc_uart_intr_deassert(void *arg) { - /* + /* * The COM devices on the LPC bus generate edge triggered interrupts, * so nothing more to do here. */ diff --git a/usr/src/cmd/bhyve/pci_nvme.c b/usr/src/cmd/bhyve/pci_nvme.c index 49fbf54b70..73e8ab0371 100644 --- a/usr/src/cmd/bhyve/pci_nvme.c +++ b/usr/src/cmd/bhyve/pci_nvme.c @@ -5,7 +5,7 @@ * Copyright (c) 2018 Leon Dang * Copyright (c) 2020 Chuck Tuffli * - * Function crc16 Copyright (c) 2017, Fedor Uporov + * Function crc16 Copyright (c) 2017, Fedor Uporov * Obtained from function ext2_crc16() in sys/fs/ext2fs/ext2_csum.c * * Redistribution and use in source and binary forms, with or without @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$"); #include <assert.h> #include <pthread.h> +#include <pthread_np.h> #include <semaphore.h> #include <stdbool.h> #include <stddef.h> @@ -253,11 +254,39 @@ struct nvme_feature_obj { #define NVME_FID_MAX (NVME_FEAT_ENDURANCE_GROUP_EVENT_CONFIGURATION + 1) +typedef enum { + PCI_NVME_AE_TYPE_ERROR = 0, + PCI_NVME_AE_TYPE_SMART, + PCI_NVME_AE_TYPE_NOTICE, + PCI_NVME_AE_TYPE_IO_CMD = 6, + PCI_NVME_AE_TYPE_VENDOR = 7, + PCI_NVME_AE_TYPE_MAX /* Must be last */ +} pci_nvme_async_type; + +/* Asynchronous Event Requests */ struct pci_nvme_aer { STAILQ_ENTRY(pci_nvme_aer) link; uint16_t cid; /* Command ID of the submitted AER */ }; +typedef enum { + PCI_NVME_AE_INFO_NS_ATTR_CHANGED = 0, + PCI_NVME_AE_INFO_FW_ACTIVATION, + PCI_NVME_AE_INFO_TELEMETRY_CHANGE, + PCI_NVME_AE_INFO_ANA_CHANGE, + PCI_NVME_AE_INFO_PREDICT_LATENCY_CHANGE, + PCI_NVME_AE_INFO_LBA_STATUS_ALERT, + PCI_NVME_AE_INFO_ENDURANCE_GROUP_CHANGE, + PCI_NVME_AE_INFO_MAX, +} pci_nvme_async_info; + +/* Asynchronous Event Notifications */ +struct pci_nvme_aen { + pci_nvme_async_type atype; + uint32_t event_data; + bool posted; +}; + struct pci_nvme_softc { struct pci_devinst *nsc_pi; @@ -270,6 +299,7 @@ struct pci_nvme_softc { struct nvme_error_information_entry err_log; struct nvme_health_information_page health_log; struct nvme_firmware_page fw_log; + struct nvme_ns_list ns_log; struct pci_nvme_blockstore nvstore; @@ -305,10 +335,21 @@ struct pci_nvme_softc { uint32_t write_dunits_remainder; STAILQ_HEAD(, pci_nvme_aer) aer_list; + pthread_mutex_t aer_mtx; uint32_t aer_count; + struct pci_nvme_aen aen[PCI_NVME_AE_TYPE_MAX]; + pthread_t aen_tid; + pthread_mutex_t aen_mtx; + pthread_cond_t aen_cond; }; +static void pci_nvme_cq_update(struct pci_nvme_softc *sc, + struct nvme_completion_queue *cq, + uint32_t cdw0, + uint16_t cid, + uint16_t sqid, + uint16_t status); static struct pci_nvme_ioreq *pci_nvme_get_ioreq(struct pci_nvme_softc *); static void pci_nvme_release_ioreq(struct pci_nvme_softc *, struct pci_nvme_ioreq *); static void pci_nvme_io_done(struct blockif_req *, int); @@ -363,6 +404,8 @@ static void nvme_feature_iv_config(struct pci_nvme_softc *, struct nvme_command *, struct nvme_completion *); +static void *aen_thr(void *arg); + static __inline void cpywithpad(char *dst, size_t dst_size, const char *src, char pad) { @@ -471,6 +514,18 @@ pci_nvme_init_ctrldata(struct pci_nvme_softc *sc) cd->ver = 0x00010300; cd->oacs = 1 << NVME_CTRLR_DATA_OACS_FORMAT_SHIFT; +#ifndef __FreeBSD__ + /* + * Reported upstream against https://reviews.freebsd.org/D32953 + * which introduced support for the namespace attribute changed AEN + * and the corresponding changed namespace log page, without setting + * the bit in oaes. A future sync will likely include this + * definition in usr/src/contrib/bhyve/dev/nvme/nvme.h once it's + * fixed there. + */ +#define NVME_CTRLR_DATA_OAES_NSCHANGE_SHIFT (8) + cd->oaes = 1 << NVME_CTRLR_DATA_OAES_NSCHANGE_SHIFT; +#endif cd->acl = 2; cd->aerl = 4; @@ -559,15 +614,23 @@ crc16(uint16_t crc, const void *buffer, unsigned int len) } static void -pci_nvme_init_nsdata(struct pci_nvme_softc *sc, - struct nvme_namespace_data *nd, uint32_t nsid, - struct pci_nvme_blockstore *nvstore) +pci_nvme_init_nsdata_size(struct pci_nvme_blockstore *nvstore, + struct nvme_namespace_data *nd) { /* Get capacity and block size information from backing store */ nd->nsze = nvstore->size / nvstore->sectsz; nd->ncap = nd->nsze; nd->nuse = nd->nsze; +} + +static void +pci_nvme_init_nsdata(struct pci_nvme_softc *sc, + struct nvme_namespace_data *nd, uint32_t nsid, + struct pci_nvme_blockstore *nvstore) +{ + + pci_nvme_init_nsdata_size(nvstore, nd); if (nvstore->type == NVME_STOR_BLOCKIF) nvstore->deallocate = blockif_candelete(nvstore->ctx); @@ -603,6 +666,7 @@ pci_nvme_init_logpages(struct pci_nvme_softc *sc) memset(&sc->err_log, 0, sizeof(sc->err_log)); memset(&sc->health_log, 0, sizeof(sc->health_log)); memset(&sc->fw_log, 0, sizeof(sc->fw_log)); + memset(&sc->ns_log, 0, sizeof(sc->ns_log)); /* Set read/write remainder to round up according to spec */ sc->read_dunits_remainder = 999; @@ -626,6 +690,8 @@ pci_nvme_init_features(struct pci_nvme_softc *sc) sc->feat[NVME_FEAT_NUMBER_OF_QUEUES].set = nvme_feature_num_queues; sc->feat[NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION].set = nvme_feature_iv_config; + /* Enable all AENs by default */ + sc->feat[NVME_FEAT_ASYNC_EVENT_CONFIGURATION].cdw11 = 0x31f; sc->feat[NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG].get = nvme_feature_invalid_cb; sc->feat[NVME_FEAT_PREDICTABLE_LATENCY_MODE_WINDOW].get = @@ -633,7 +699,7 @@ pci_nvme_init_features(struct pci_nvme_softc *sc) } static void -pci_nvme_aer_init(struct pci_nvme_softc *sc) +pci_nvme_aer_reset(struct pci_nvme_softc *sc) { STAILQ_INIT(&sc->aer_list); @@ -641,29 +707,35 @@ pci_nvme_aer_init(struct pci_nvme_softc *sc) } static void +pci_nvme_aer_init(struct pci_nvme_softc *sc) +{ + + pthread_mutex_init(&sc->aer_mtx, NULL); + pci_nvme_aer_reset(sc); +} + +static void pci_nvme_aer_destroy(struct pci_nvme_softc *sc) { struct pci_nvme_aer *aer = NULL; + pthread_mutex_lock(&sc->aer_mtx); while (!STAILQ_EMPTY(&sc->aer_list)) { aer = STAILQ_FIRST(&sc->aer_list); STAILQ_REMOVE_HEAD(&sc->aer_list, link); free(aer); } + pthread_mutex_unlock(&sc->aer_mtx); - pci_nvme_aer_init(sc); + pci_nvme_aer_reset(sc); } -#ifdef __FreeBSD__ static bool pci_nvme_aer_available(struct pci_nvme_softc *sc) { - return (!STAILQ_EMPTY(&sc->aer_list)); + return (sc->aer_count != 0); } -#else -/* This is kept behind an ifdef while it's unused to appease the compiler. */ -#endif static bool pci_nvme_aer_limit_reached(struct pci_nvme_softc *sc) @@ -694,11 +766,13 @@ pci_nvme_aer_add(struct pci_nvme_softc *sc, uint16_t cid) if (aer == NULL) return (-1); - sc->aer_count++; - /* Save the Command ID for use in the completion message */ aer->cid = cid; + + pthread_mutex_lock(&sc->aer_mtx); + sc->aer_count++; STAILQ_INSERT_TAIL(&sc->aer_list, aer, link); + pthread_mutex_unlock(&sc->aer_mtx); return (0); } @@ -709,24 +783,219 @@ pci_nvme_aer_add(struct pci_nvme_softc *sc, uint16_t cid) * Returns a pointer to an AER previously submitted by the host or NULL if * no AER's exist. Caller is responsible for freeing the returned struct. */ -#ifdef __FreeBSD__ static struct pci_nvme_aer * pci_nvme_aer_get(struct pci_nvme_softc *sc) { struct pci_nvme_aer *aer = NULL; + pthread_mutex_lock(&sc->aer_mtx); aer = STAILQ_FIRST(&sc->aer_list); if (aer != NULL) { STAILQ_REMOVE_HEAD(&sc->aer_list, link); sc->aer_count--; } - + pthread_mutex_unlock(&sc->aer_mtx); + return (aer); } -#else -/* This is kept behind an ifdef while it's unused to appease the compiler. */ + +static void +pci_nvme_aen_reset(struct pci_nvme_softc *sc) +{ + uint32_t atype; + + memset(sc->aen, 0, PCI_NVME_AE_TYPE_MAX * sizeof(struct pci_nvme_aen)); + + for (atype = 0; atype < PCI_NVME_AE_TYPE_MAX; atype++) { + sc->aen[atype].atype = atype; + } +} + +static void +pci_nvme_aen_init(struct pci_nvme_softc *sc) +{ + char nstr[80]; + + pci_nvme_aen_reset(sc); + + pthread_mutex_init(&sc->aen_mtx, NULL); + pthread_create(&sc->aen_tid, NULL, aen_thr, sc); + snprintf(nstr, sizeof(nstr), "nvme-aen-%d:%d", sc->nsc_pi->pi_slot, + sc->nsc_pi->pi_func); + pthread_set_name_np(sc->aen_tid, nstr); +} + +static void +pci_nvme_aen_destroy(struct pci_nvme_softc *sc) +{ + + pci_nvme_aen_reset(sc); +} + +/* Notify the AEN thread of pending work */ +static void +pci_nvme_aen_notify(struct pci_nvme_softc *sc) +{ + + pthread_cond_signal(&sc->aen_cond); +} + +/* + * Post an Asynchronous Event Notification + */ +static int32_t +pci_nvme_aen_post(struct pci_nvme_softc *sc, pci_nvme_async_type atype, + uint32_t event_data) +{ + struct pci_nvme_aen *aen; + + if (atype >= PCI_NVME_AE_TYPE_MAX) { + return(EINVAL); + } + + pthread_mutex_lock(&sc->aen_mtx); + aen = &sc->aen[atype]; + + /* Has the controller already posted an event of this type? */ + if (aen->posted) { + pthread_mutex_unlock(&sc->aen_mtx); + return(EALREADY); + } + + aen->event_data = event_data; + aen->posted = true; + pthread_mutex_unlock(&sc->aen_mtx); + + pci_nvme_aen_notify(sc); + + return(0); +} + +static void +pci_nvme_aen_process(struct pci_nvme_softc *sc) +{ + struct pci_nvme_aer *aer; + struct pci_nvme_aen *aen; + pci_nvme_async_type atype; + uint32_t mask; + uint16_t status; + uint8_t lid; + +#ifndef __FreeBSD__ + lid = 0; #endif + assert(pthread_mutex_isowned_np(&sc->aen_mtx)); + for (atype = 0; atype < PCI_NVME_AE_TYPE_MAX; atype++) { + aen = &sc->aen[atype]; + /* Previous iterations may have depleted the available AER's */ + if (!pci_nvme_aer_available(sc)) { + DPRINTF("%s: no AER", __func__); + break; + } + + if (!aen->posted) { + DPRINTF("%s: no AEN posted for atype=%#x", __func__, atype); + continue; + } + + status = NVME_SC_SUCCESS; + + /* Is the event masked? */ + mask = + sc->feat[NVME_FEAT_ASYNC_EVENT_CONFIGURATION].cdw11; + + DPRINTF("%s: atype=%#x mask=%#x event_data=%#x", __func__, atype, mask, aen->event_data); + switch (atype) { + case PCI_NVME_AE_TYPE_ERROR: + lid = NVME_LOG_ERROR; + break; + case PCI_NVME_AE_TYPE_SMART: + mask &= 0xff; + if ((mask & aen->event_data) == 0) + continue; + lid = NVME_LOG_HEALTH_INFORMATION; + break; + case PCI_NVME_AE_TYPE_NOTICE: + if (aen->event_data >= PCI_NVME_AE_INFO_MAX) { + EPRINTLN("%s unknown AEN notice type %u", + __func__, aen->event_data); + status = NVME_SC_INTERNAL_DEVICE_ERROR; + break; + } + mask >>= 8; + if (((1 << aen->event_data) & mask) == 0) + continue; + switch (aen->event_data) { + case PCI_NVME_AE_INFO_NS_ATTR_CHANGED: + lid = NVME_LOG_CHANGED_NAMESPACE; + break; + case PCI_NVME_AE_INFO_FW_ACTIVATION: + lid = NVME_LOG_FIRMWARE_SLOT; + break; + case PCI_NVME_AE_INFO_TELEMETRY_CHANGE: + lid = NVME_LOG_TELEMETRY_CONTROLLER_INITIATED; + break; + case PCI_NVME_AE_INFO_ANA_CHANGE: + lid = NVME_LOG_ASYMMETRIC_NAMESPAVE_ACCESS; //TODO spelling + break; + case PCI_NVME_AE_INFO_PREDICT_LATENCY_CHANGE: + lid = NVME_LOG_PREDICTABLE_LATENCY_EVENT_AGGREGATE; + break; + case PCI_NVME_AE_INFO_LBA_STATUS_ALERT: + lid = NVME_LOG_LBA_STATUS_INFORMATION; + break; + case PCI_NVME_AE_INFO_ENDURANCE_GROUP_CHANGE: + lid = NVME_LOG_ENDURANCE_GROUP_EVENT_AGGREGATE; + break; + default: + lid = 0; + } + break; + default: + /* bad type?!? */ + EPRINTLN("%s unknown AEN type %u", __func__, atype); + status = NVME_SC_INTERNAL_DEVICE_ERROR; + break; + } + + aer = pci_nvme_aer_get(sc); + assert(aer != NULL); + + DPRINTF("%s: CID=%#x CDW0=%#x", __func__, aer->cid, (lid << 16) | (aen->event_data << 8) | atype); + pci_nvme_cq_update(sc, &sc->compl_queues[0], + (lid << 16) | (aen->event_data << 8) | atype, /* cdw0 */ + aer->cid, + 0, /* SQID */ + status); + + aen->event_data = 0; + aen->posted = false; + + pci_generate_msix(sc->nsc_pi, 0); + } +} + +static void * +aen_thr(void *arg) +{ + struct pci_nvme_softc *sc; + + sc = arg; + + pthread_mutex_lock(&sc->aen_mtx); + for (;;) { + pci_nvme_aen_process(sc); + pthread_cond_wait(&sc->aen_cond, &sc->aen_mtx); + } +#ifdef __FreeBSD__ + pthread_mutex_unlock(&sc->aen_mtx); + + pthread_exit(NULL); +#endif + return (NULL); +} + static void pci_nvme_reset_locked(struct pci_nvme_softc *sc) { @@ -767,6 +1036,7 @@ pci_nvme_reset_locked(struct pci_nvme_softc *sc) sc->num_q_is_set = false; pci_nvme_aer_destroy(sc); + pci_nvme_aen_destroy(sc); } static void @@ -792,7 +1062,7 @@ pci_nvme_init_controller(struct vmctx *ctx, struct pci_nvme_softc *sc) DPRINTF("%s mapping Admin-SQ guest 0x%lx, host: %p", __func__, sc->regs.asq, sc->submit_queues[0].qbase); - acqs = ((sc->regs.aqa >> NVME_AQA_REG_ACQS_SHIFT) & + acqs = ((sc->regs.aqa >> NVME_AQA_REG_ACQS_SHIFT) & NVME_AQA_REG_ACQS_MASK) + 1; sc->compl_queues[0].size = acqs; sc->compl_queues[0].qbase = vm_map_gpa(ctx, sc->regs.acq, @@ -973,7 +1243,7 @@ nvme_opc_create_io_sq(struct pci_nvme_softc* sc, struct nvme_command* command, DPRINTF("%s completed creating IOSQ qid %u", __func__, qid); } else { - /* + /* * Guest sent non-cont submission queue request. * This setting is unsupported by this emulation. */ @@ -1128,6 +1398,13 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, MIN(logsize, sizeof(sc->fw_log)), NVME_COPY_TO_PRP); break; + case NVME_LOG_CHANGED_NAMESPACE: + nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1, + command->prp2, (uint8_t *)&sc->ns_log, + MIN(logsize, sizeof(sc->ns_log)), + NVME_COPY_TO_PRP); + memset(&sc->ns_log, 0, sizeof(sc->ns_log)); + break; default: DPRINTF("%s get log page %x command not supported", __func__, logpage); @@ -1425,8 +1702,13 @@ nvme_opc_set_features(struct pci_nvme_softc *sc, struct nvme_command *command, if (feat->set) feat->set(sc, feat, command, compl); - if (compl->status == NVME_SC_SUCCESS) + DPRINTF("%s: status=%#x cdw11=%#x", __func__, compl->status, command->cdw11); + if (compl->status == NVME_SC_SUCCESS) { feat->cdw11 = command->cdw11; + if ((fid == NVME_FEAT_ASYNC_EVENT_CONFIGURATION) && + (command->cdw11 != 0)) + pci_nvme_aen_notify(sc); + } return (0); } @@ -1544,7 +1826,8 @@ static int nvme_opc_async_event_req(struct pci_nvme_softc* sc, struct nvme_command* command, struct nvme_completion* compl) { - DPRINTF("%s async event request 0x%x", __func__, command->cdw11); + DPRINTF("%s async event request count=%u aerl=%u cid=%#x", __func__, + sc->aer_count, sc->ctrldata.aerl, command->cid); /* Don't exceed the Async Event Request Limit (AERL). */ if (pci_nvme_aer_limit_reached(sc)) { @@ -1565,6 +1848,7 @@ nvme_opc_async_event_req(struct pci_nvme_softc* sc, * there is an event reflective of the request to get event. */ compl->status = NVME_NO_STATUS; + pci_nvme_aen_notify(sc); return (0); } @@ -1587,7 +1871,7 @@ pci_nvme_handle_admin_cmd(struct pci_nvme_softc* sc, uint64_t value) sqhead = sq->head; DPRINTF("sqhead %u, tail %u", sqhead, sq->tail); - + while (sqhead != atomic_load_acq_short(&sq->tail)) { cmd = &(sq->qbase)[sqhead]; compl.cdw0 = 0; @@ -2056,6 +2340,7 @@ nvme_opc_write_read(struct pci_nvme_softc *sc, lba = ((uint64_t)cmd->cdw11 << 32) | cmd->cdw10; nblocks = (cmd->cdw12 & 0xFFFF) + 1; + if (pci_nvme_out_of_range(nvstore, lba, nblocks)) { WPRINTF("%s command would exceed LBA range", __func__); pci_nvme_status_genc(status, NVME_SC_LBA_OUT_OF_RANGE); @@ -2755,6 +3040,28 @@ pci_nvme_parse_config(struct pci_nvme_softc *sc, nvlist_t *nvl) return (0); } +static void +pci_nvme_resized(struct blockif_ctxt *bctxt, void *arg, size_t new_size) +{ + struct pci_nvme_softc *sc; + struct pci_nvme_blockstore *nvstore; + struct nvme_namespace_data *nd; + + sc = arg; + nvstore = &sc->nvstore; + nd = &sc->nsdata; + + nvstore->size = new_size; + pci_nvme_init_nsdata_size(nvstore, nd); + + /* Add changed NSID to list */ + sc->ns_log.ns[0] = 1; + sc->ns_log.ns[1] = 0; + + pci_nvme_aen_post(sc, PCI_NVME_AE_TYPE_NOTICE, + PCI_NVME_AE_INFO_NS_ATTR_CHANGED); +} + static int pci_nvme_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) { @@ -2820,6 +3127,7 @@ pci_nvme_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) pthread_mutex_init(&sc->mtx, NULL); sem_init(&sc->iosemlock, 0, sc->ioslots); + blockif_register_resize_callback(sc->nvstore.ctx, pci_nvme_resized, sc); pci_nvme_init_queues(sc, sc->max_queues, sc->max_queues); /* @@ -2832,6 +3140,7 @@ pci_nvme_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) pci_nvme_init_features(sc); pci_nvme_aer_init(sc); + pci_nvme_aen_init(sc); pci_nvme_reset(sc); diff --git a/usr/src/cmd/bhyve/pci_passthru.c b/usr/src/cmd/bhyve/pci_passthru.c index 55e2f66e99..aea278c0c8 100644 --- a/usr/src/cmd/bhyve/pci_passthru.c +++ b/usr/src/cmd/bhyve/pci_passthru.c @@ -344,15 +344,14 @@ cfginitmsi(struct passthru_softc *sc) #endif /* Make sure one of the capabilities is present */ - if (sc->psc_msi.capoff == 0 && sc->psc_msix.capoff == 0) { + if (sc->psc_msi.capoff == 0 && sc->psc_msix.capoff == 0) return (-1); - } else { + else return (0); - } } static uint64_t -passthru_msix_table_read(struct passthru_softc *sc, uint64_t offset, int size) +msix_table_read(struct passthru_softc *sc, uint64_t offset, int size) { struct pci_devinst *pi; struct msix_table_entry *entry; @@ -362,30 +361,30 @@ passthru_msix_table_read(struct passthru_softc *sc, uint64_t offset, int size) uint64_t *src64; uint64_t data; size_t entry_offset; - int index; + uint32_t table_offset; + int index, table_count; pi = sc->psc_pi; - if (offset >= pi->pi_msix.pba_offset && - offset < pi->pi_msix.pba_offset + pi->pi_msix.pba_size) { - switch(size) { + + table_offset = pi->pi_msix.table_offset; + table_count = pi->pi_msix.table_count; + if (offset < table_offset || + offset >= table_offset + table_count * MSIX_TABLE_ENTRY_SIZE) { + switch (size) { case 1: - src8 = (uint8_t *)(pi->pi_msix.pba_page + offset - - pi->pi_msix.pba_page_offset); + src8 = (uint8_t *)(pi->pi_msix.mapped_addr + offset); data = *src8; break; case 2: - src16 = (uint16_t *)(pi->pi_msix.pba_page + offset - - pi->pi_msix.pba_page_offset); + src16 = (uint16_t *)(pi->pi_msix.mapped_addr + offset); data = *src16; break; case 4: - src32 = (uint32_t *)(pi->pi_msix.pba_page + offset - - pi->pi_msix.pba_page_offset); + src32 = (uint32_t *)(pi->pi_msix.mapped_addr + offset); data = *src32; break; case 8: - src64 = (uint64_t *)(pi->pi_msix.pba_page + offset - - pi->pi_msix.pba_page_offset); + src64 = (uint64_t *)(pi->pi_msix.mapped_addr + offset); data = *src64; break; default: @@ -394,32 +393,28 @@ passthru_msix_table_read(struct passthru_softc *sc, uint64_t offset, int size) return (data); } - if (offset < pi->pi_msix.table_offset) - return (-1); - - offset -= pi->pi_msix.table_offset; + offset -= table_offset; index = offset / MSIX_TABLE_ENTRY_SIZE; - if (index >= pi->pi_msix.table_count) - return (-1); + assert(index < table_count); entry = &pi->pi_msix.table[index]; entry_offset = offset % MSIX_TABLE_ENTRY_SIZE; - switch(size) { + switch (size) { case 1: - src8 = (uint8_t *)((void *)entry + entry_offset); + src8 = (uint8_t *)((uint8_t *)entry + entry_offset); data = *src8; break; case 2: - src16 = (uint16_t *)((void *)entry + entry_offset); + src16 = (uint16_t *)((uint8_t *)entry + entry_offset); data = *src16; break; case 4: - src32 = (uint32_t *)((void *)entry + entry_offset); + src32 = (uint32_t *)((uint8_t *)entry + entry_offset); data = *src32; break; case 8: - src64 = (uint64_t *)((void *)entry + entry_offset); + src64 = (uint64_t *)((uint8_t *)entry + entry_offset); data = *src64; break; default: @@ -430,8 +425,8 @@ passthru_msix_table_read(struct passthru_softc *sc, uint64_t offset, int size) } static void -passthru_msix_table_write(struct vmctx *ctx, int vcpu, - struct passthru_softc *sc, uint64_t offset, int size, uint64_t data) +msix_table_write(struct vmctx *ctx, int vcpu, struct passthru_softc *sc, + uint64_t offset, int size, uint64_t data) { struct pci_devinst *pi; struct msix_table_entry *entry; @@ -440,46 +435,39 @@ passthru_msix_table_write(struct vmctx *ctx, int vcpu, uint32_t *dest32; uint64_t *dest64; size_t entry_offset; - uint32_t vector_control; - int index; + uint32_t table_offset, vector_control; + int index, table_count; pi = sc->psc_pi; - if (offset >= pi->pi_msix.pba_offset && - offset < pi->pi_msix.pba_offset + pi->pi_msix.pba_size) { - switch(size) { + + table_offset = pi->pi_msix.table_offset; + table_count = pi->pi_msix.table_count; + if (offset < table_offset || + offset >= table_offset + table_count * MSIX_TABLE_ENTRY_SIZE) { + switch (size) { case 1: - dest8 = (uint8_t *)(pi->pi_msix.pba_page + offset - - pi->pi_msix.pba_page_offset); + dest8 = (uint8_t *)(pi->pi_msix.mapped_addr + offset); *dest8 = data; break; case 2: - dest16 = (uint16_t *)(pi->pi_msix.pba_page + offset - - pi->pi_msix.pba_page_offset); + dest16 = (uint16_t *)(pi->pi_msix.mapped_addr + offset); *dest16 = data; break; case 4: - dest32 = (uint32_t *)(pi->pi_msix.pba_page + offset - - pi->pi_msix.pba_page_offset); + dest32 = (uint32_t *)(pi->pi_msix.mapped_addr + offset); *dest32 = data; break; case 8: - dest64 = (uint64_t *)(pi->pi_msix.pba_page + offset - - pi->pi_msix.pba_page_offset); + dest64 = (uint64_t *)(pi->pi_msix.mapped_addr + offset); *dest64 = data; break; - default: - break; } return; } - if (offset < pi->pi_msix.table_offset) - return; - - offset -= pi->pi_msix.table_offset; + offset -= table_offset; index = offset / MSIX_TABLE_ENTRY_SIZE; - if (index >= pi->pi_msix.table_count) - return; + assert(index < table_count); entry = &pi->pi_msix.table[index]; entry_offset = offset % MSIX_TABLE_ENTRY_SIZE; @@ -504,65 +492,64 @@ passthru_msix_table_write(struct vmctx *ctx, int vcpu, } static int -init_msix_table(struct vmctx *ctx, struct passthru_softc *sc, uint64_t base) +init_msix_table(struct vmctx *ctx, struct passthru_softc *sc) { - int idx; - size_t remaining __unused; - uint32_t table_size, table_offset; - uint32_t pba_size, pba_offset; - vm_paddr_t start __unused; struct pci_devinst *pi = sc->psc_pi; + uint32_t table_size, table_offset; + int i; - assert(pci_msix_table_bar(pi) >= 0 && pci_msix_pba_bar(pi) >= 0); + i = pci_msix_table_bar(pi); + assert(i >= 0); + + /* + * Map the region of the BAR containing the MSI-X table. This is + * necessary for two reasons: + * 1. The PBA may reside in the first or last page containing the MSI-X + * table. + * 2. While PCI devices are not supposed to use the page(s) containing + * the MSI-X table for other purposes, some do in practice. + */ /* - * If the MSI-X table BAR maps memory intended for - * other uses, it is at least assured that the table - * either resides in its own page within the region, - * or it resides in a page shared with only the PBA. + * Mapping pptfd provides access to the BAR containing the MSI-X + * table. See ppt_devmap() in usr/src/uts/i86pc/io/vmm/io/ppt.c + * + * This maps the whole BAR and then mprotect(PROT_NONE) is used below + * to prevent access to pages that don't contain the MSI-X table. + * When porting this, it was tempting to just map the MSI-X table pages + * but that would mean updating everywhere that assumes that + * pi->pi_msix.mapped_addr points to the start of the BAR. For now, + * keep closer to upstream. */ + pi->pi_msix.mapped_size = sc->psc_bar[i].size; + pi->pi_msix.mapped_addr = (uint8_t *)mmap(NULL, pi->pi_msix.mapped_size, + PROT_READ | PROT_WRITE, MAP_SHARED, sc->pptfd, 0); + if (pi->pi_msix.mapped_addr == MAP_FAILED) { + warn("Failed to map MSI-X table BAR on %d", sc->pptfd); + return (-1); + } + table_offset = rounddown2(pi->pi_msix.table_offset, 4096); table_size = pi->pi_msix.table_offset - table_offset; table_size += pi->pi_msix.table_count * MSIX_TABLE_ENTRY_SIZE; table_size = roundup2(table_size, 4096); - idx = pi->pi_msix.table_bar; - start = pi->pi_bar[idx].addr; - remaining = pi->pi_bar[idx].size; - - if (pi->pi_msix.pba_bar == pi->pi_msix.table_bar) { - pba_offset = pi->pi_msix.pba_offset; - pba_size = pi->pi_msix.pba_size; - if (pba_offset >= table_offset + table_size || - table_offset >= pba_offset + pba_size) { - /* - * If the PBA does not share a page with the MSI-x - * tables, no PBA emulation is required. - */ - pi->pi_msix.pba_page = NULL; - pi->pi_msix.pba_page_offset = 0; - } else { - /* - * The PBA overlaps with either the first or last - * page of the MSI-X table region. Map the - * appropriate page. - */ - if (pba_offset <= table_offset) - pi->pi_msix.pba_page_offset = table_offset; - else - pi->pi_msix.pba_page_offset = table_offset + - table_size - 4096; - pi->pi_msix.pba_page = mmap(NULL, 4096, PROT_READ | - PROT_WRITE, MAP_SHARED, sc->pptfd, - pi->pi_msix.pba_page_offset); - if (pi->pi_msix.pba_page == MAP_FAILED) { - warn("Failed to map PBA page for MSI-X on %d", - sc->pptfd); - return (-1); - } - } - } + /* + * Unmap any pages not containing the table, we do not need to emulate + * accesses to them. Avoid releasing address space to help ensure that + * a buggy out-of-bounds access causes a crash. + */ + if (table_offset != 0) + if (mprotect((caddr_t)pi->pi_msix.mapped_addr, table_offset, + PROT_NONE) != 0) + warn("Failed to unmap MSI-X table BAR region"); + if (table_offset + table_size != pi->pi_msix.mapped_size) + if (mprotect((caddr_t) + pi->pi_msix.mapped_addr + table_offset + table_size, + pi->pi_msix.mapped_size - (table_offset + table_size), + PROT_NONE) != 0) + warn("Failed to unmap MSI-X table BAR region"); return (0); } @@ -598,18 +585,22 @@ cfginitbar(struct vmctx *ctx, struct passthru_softc *sc) sc->psc_bar[i].type = bartype; sc->psc_bar[i].size = size; sc->psc_bar[i].addr = base; + sc->psc_bar[i].lobits = 0; /* Allocate the BAR in the guest I/O or MMIO space */ error = pci_emul_alloc_bar(pi, i, bartype, size); if (error) return (-1); - /* The MSI-X table needs special handling */ - if (i == pci_msix_table_bar(pi)) { - error = init_msix_table(ctx, sc, base); - if (error) - return (-1); + /* Use same lobits as physical bar */ + uint8_t lobits = read_config(sc, PCIR_BAR(i), 0x01); + if (bartype == PCIBAR_MEM32 || bartype == PCIBAR_MEM64) { + lobits &= ~PCIM_BAR_MEM_BASE; + } else { + lobits &= ~PCIM_BAR_IO_BASE; } + sc->psc_bar[i].lobits = lobits; + pi->pi_bar[i].lobits = lobits; /* * 64-bit BAR takes up two slots so skip the next one. @@ -627,6 +618,7 @@ static int cfginit(struct vmctx *ctx, struct passthru_softc *sc) { struct pci_devinst *pi = sc->psc_pi; + int error; if (cfginitmsi(sc) != 0) { warnx("failed to initialize MSI for PCI %d", sc->pptfd); @@ -638,9 +630,24 @@ cfginit(struct vmctx *ctx, struct passthru_softc *sc) return (-1); } - pci_set_cfgdata16(pi, PCIR_COMMAND, read_config(sc, PCIR_COMMAND, 2)); + write_config(sc, PCIR_COMMAND, 2, pci_get_cfgdata16(pi, PCIR_COMMAND)); - return (0); + /* + * We need to do this after PCIR_COMMAND got possibly updated, e.g., + * a BAR was enabled. + */ + if (pci_msix_table_bar(pi) >= 0) { + error = init_msix_table(ctx, sc); + if (error != 0) { + warnx("failed to initialize MSI-X table for PCI %d", + sc->pptfd); + goto done; + } + } + + error = 0; /* success */ +done: + return (error); } static int @@ -694,10 +701,7 @@ passthru_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) goto done; /* initialize config space */ - if ((error = cfginit(ctx, sc)) != 0) - goto done; - - error = 0; /* success */ + error = cfginit(ctx, sc); done: if (error) { free(sc); @@ -744,7 +748,7 @@ msixcap_access(struct passthru_softc *sc, int coff) static int passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int coff, int bytes, uint32_t *rv) + int coff, int bytes, uint32_t *rv) { struct passthru_softc *sc; @@ -753,7 +757,8 @@ passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, /* * PCI BARs and MSI capability is emulated. */ - if (bar_access(coff) || msicap_access(sc, coff)) + if (bar_access(coff) || msicap_access(sc, coff) || + msixcap_access(sc, coff)) return (-1); /* @@ -795,7 +800,7 @@ passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, static int passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int coff, int bytes, uint32_t val) + int coff, int bytes, uint32_t val) { int error, msix_table_entries, i; struct passthru_softc *sc; @@ -872,12 +877,12 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, static void passthru_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t offset, int size, uint64_t value) + uint64_t offset, int size, uint64_t value) { struct passthru_softc *sc = pi->pi_arg; if (baridx == pci_msix_table_bar(pi)) { - passthru_msix_table_write(ctx, vcpu, sc, offset, size, value); + msix_table_write(ctx, vcpu, sc, offset, size, value); } else { struct ppt_bar_io pbi; @@ -893,13 +898,13 @@ passthru_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, static uint64_t passthru_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t offset, int size) + uint64_t offset, int size) { struct passthru_softc *sc = pi->pi_arg; uint64_t val; if (baridx == pci_msix_table_bar(pi)) { - val = passthru_msix_table_read(sc, offset, size); + val = msix_table_read(sc, offset, size); } else { struct ppt_bar_io pbi; @@ -920,7 +925,7 @@ passthru_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, static void passthru_msix_addr(struct vmctx *ctx, struct pci_devinst *pi, int baridx, - int enabled, uint64_t address) + int enabled, uint64_t address) { struct passthru_softc *sc; size_t remaining; @@ -960,7 +965,7 @@ passthru_msix_addr(struct vmctx *ctx, struct pci_devinst *pi, int baridx, static void passthru_mmio_addr(struct vmctx *ctx, struct pci_devinst *pi, int baridx, - int enabled, uint64_t address) + int enabled, uint64_t address) { struct passthru_softc *sc; diff --git a/usr/src/cmd/bhyve/pci_virtio_9p.c b/usr/src/cmd/bhyve/pci_virtio_9p.c index 8c975ac1dc..9808fee46d 100644 --- a/usr/src/cmd/bhyve/pci_virtio_9p.c +++ b/usr/src/cmd/bhyve/pci_virtio_9p.c @@ -159,7 +159,7 @@ pci_vt9p_get_buffer(struct l9p_request *req, struct iovec *iov, size_t *niov, { struct pci_vt9p_request *preq = req->lr_aux; size_t n = preq->vsr_niov - preq->vsr_respidx; - + memcpy(iov, preq->vsr_iov + preq->vsr_respidx, n * sizeof(struct iovec)); *niov = n; @@ -350,7 +350,7 @@ pci_vt9p_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) sc->vsc_config->tag_len = (uint16_t)strlen(sharename); memcpy(sc->vsc_config->tag, sharename, sc->vsc_config->tag_len); - + if (l9p_backend_fs_init(&sc->vsc_fs_backend, rootfd, ro) != 0) { errno = ENXIO; return (1); diff --git a/usr/src/cmd/bhyve/pci_virtio_block.c b/usr/src/cmd/bhyve/pci_virtio_block.c index b2fc84118f..30998161f0 100644 --- a/usr/src/cmd/bhyve/pci_virtio_block.c +++ b/usr/src/cmd/bhyve/pci_virtio_block.c @@ -434,7 +434,7 @@ pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) { char bident[sizeof("XX:X:X")]; struct blockif_ctxt *bctxt; - const char *path; + const char *path, *serial; MD5_CTX mdctx; u_char digest[16]; struct pci_vtblk_softc *sc; @@ -485,26 +485,23 @@ pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) /* sc->vbsc_vq.vq_notify = we have no per-queue notify */ /* - * Create an identifier for the backing file. Use parts of the - * md5 sum of the filename + * If an explicit identifier is not given, create an + * identifier using parts of the md5 sum of the filename. */ - path = get_config_value_node(nvl, "path"); - MD5Init(&mdctx); - MD5Update(&mdctx, path, strlen(path)); - MD5Final(digest, &mdctx); - snprintf(sc->vbsc_ident, VTBLK_BLK_ID_BYTES, - "BHYVE-%02X%02X-%02X%02X-%02X%02X", - digest[0], digest[1], digest[2], digest[3], digest[4], digest[5]); - -#ifndef __FreeBSD__ - const char *serial; - + bzero(sc->vbsc_ident, VTBLK_BLK_ID_BYTES); if ((serial = get_config_value_node(nvl, "serial")) != NULL || (serial = get_config_value_node(nvl, "ser")) != NULL) { - bzero(sc->vbsc_ident, VTBLK_BLK_ID_BYTES); strlcpy(sc->vbsc_ident, serial, VTBLK_BLK_ID_BYTES); + } else { + path = get_config_value_node(nvl, "path"); + MD5Init(&mdctx); + MD5Update(&mdctx, path, strlen(path)); + MD5Final(digest, &mdctx); + snprintf(sc->vbsc_ident, VTBLK_BLK_ID_BYTES, + "BHYVE-%02X%02X-%02X%02X-%02X%02X", + digest[0], digest[1], digest[2], digest[3], digest[4], + digest[5]); } -#endif /* setup virtio block config space */ sc->vbsc_cfg.vbc_capacity = size / VTBLK_BSIZE; /* 512-byte units */ @@ -593,6 +590,6 @@ struct pci_devemu pci_de_vblk = { .pe_init = pci_vtblk_init, .pe_legacy_config = blockif_legacy_config, .pe_barwrite = vi_pci_write, - .pe_barread = vi_pci_read + .pe_barread = vi_pci_read, }; PCI_EMUL_SET(pci_de_vblk); diff --git a/usr/src/cmd/bhyve/pci_virtio_console.c b/usr/src/cmd/bhyve/pci_virtio_console.c index ba0ca48dbf..998d5e1d4c 100644 --- a/usr/src/cmd/bhyve/pci_virtio_console.c +++ b/usr/src/cmd/bhyve/pci_virtio_console.c @@ -618,7 +618,7 @@ pci_vtcon_control_send(struct pci_vtcon_softc *sc, vq_relchain(vq, req.idx, sizeof(struct pci_vtcon_control) + len); vq_endchains(vq, 1); } - + static void pci_vtcon_notify_tx(void *vsc, struct vqueue_info *vq) @@ -723,7 +723,7 @@ pci_vtcon_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) sc->vsc_config = calloc(1, sizeof(struct pci_vtcon_config)); sc->vsc_config->max_nr_ports = VTCON_MAXPORTS; sc->vsc_config->cols = 80; - sc->vsc_config->rows = 25; + sc->vsc_config->rows = 25; vi_softc_linkup(&sc->vsc_vs, &vtcon_vi_consts, sc, pi, sc->vsc_queues); sc->vsc_vs.vs_mtx = &sc->vsc_mtx; diff --git a/usr/src/cmd/bhyve/pci_virtio_net.c b/usr/src/cmd/bhyve/pci_virtio_net.c index 28c11b87c5..b7094484aa 100644 --- a/usr/src/cmd/bhyve/pci_virtio_net.c +++ b/usr/src/cmd/bhyve/pci_virtio_net.c @@ -116,7 +116,7 @@ struct pci_vtnet_softc { int resetting; /* protected by tx_mtx */ uint64_t vsc_features; /* negotiated features */ - + pthread_mutex_t rx_mtx; int rx_merge; /* merged rx bufs in use */ @@ -654,9 +654,9 @@ pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) sc->vsc_consts.vc_hv_caps |= VIRTIO_NET_F_MRG_RXBUF | netbe_get_cap(sc->vsc_be); - /* + /* * Since we do not actually support multiqueue, - * set the maximum virtqueue pairs to 1. + * set the maximum virtqueue pairs to 1. */ sc->vsc_config.max_virtqueue_pairs = 1; @@ -669,7 +669,7 @@ pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) /* Link is always up. */ sc->vsc_config.status = 1; - + vi_softc_linkup(&sc->vsc_vs, &sc->vsc_consts, sc, pi, sc->vsc_queues); sc->vsc_vs.vs_mtx = &sc->vsc_mtx; @@ -686,12 +686,12 @@ pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) sc->rx_merge = 0; sc->vhdrlen = sizeof(struct virtio_net_rxhdr) - 2; - pthread_mutex_init(&sc->rx_mtx, NULL); + pthread_mutex_init(&sc->rx_mtx, NULL); - /* + /* * Initialize tx semaphore & spawn TX processing thread. * As of now, only one thread for TX desc processing is - * spawned. + * spawned. */ sc->tx_in_progress = 0; pthread_mutex_init(&sc->tx_mtx, NULL); diff --git a/usr/src/cmd/bhyve/pci_virtio_scsi.c b/usr/src/cmd/bhyve/pci_virtio_scsi.c index f4a701c0e2..b080749f79 100644 --- a/usr/src/cmd/bhyve/pci_virtio_scsi.c +++ b/usr/src/cmd/bhyve/pci_virtio_scsi.c @@ -628,7 +628,7 @@ pci_vtscsi_requestq_notify(void *vsc, struct vqueue_info *vq) } static int -pci_vtscsi_init_queue(struct pci_vtscsi_softc *sc, +pci_vtscsi_init_queue(struct pci_vtscsi_softc *sc, struct pci_vtscsi_queue *queue, int num) { struct pci_vtscsi_worker *worker; diff --git a/usr/src/cmd/bhyve/pci_xhci.c b/usr/src/cmd/bhyve/pci_xhci.c index bbccc7f0bf..97ce582772 100644 --- a/usr/src/cmd/bhyve/pci_xhci.c +++ b/usr/src/cmd/bhyve/pci_xhci.c @@ -485,7 +485,7 @@ pci_xhci_portregs_write(struct pci_xhci_softc *sc, uint64_t offset, p->portsc &= XHCI_PS_PED | XHCI_PS_PLS_MASK | XHCI_PS_SPEED_MASK | XHCI_PS_PIC_MASK; - + if (XHCI_DEVINST_PTR(sc, port)) p->portsc |= XHCI_PS_CCS; @@ -541,7 +541,7 @@ pci_xhci_portregs_write(struct pci_xhci_softc *sc, uint64_t offset, break; } break; - case 4: + case 4: /* Port power management status and control register */ p->portpmsc = value; break; @@ -595,7 +595,7 @@ pci_xhci_trb_next(struct pci_xhci_softc *sc, struct xhci_trb *curtrb, if (XHCI_TRB_3_TYPE_GET(curtrb->dwTrb3) == XHCI_TRB_TYPE_LINK) { if (guestaddr) *guestaddr = curtrb->qwTrb0 & ~0xFUL; - + next = XHCI_GADDR(sc, curtrb->qwTrb0 & ~0xFUL); } else { if (guestaddr) @@ -1260,7 +1260,7 @@ pci_xhci_cmd_set_tr(struct pci_xhci_softc *sc, uint32_t slot, cmderr = pci_xhci_find_stream(sc, ep_ctx, streamid, &sctx); if (sctx != NULL) { assert(devep->ep_sctx != NULL); - + devep->ep_sctx[streamid].qwSctx0 = trb->qwTrb0; devep->ep_sctx_trbs[streamid].ringaddr = trb->qwTrb0 & ~0xF; @@ -1379,7 +1379,7 @@ pci_xhci_complete_commands(struct pci_xhci_softc *sc) while (1) { sc->opregs.cr_p = trb; - + type = XHCI_TRB_3_TYPE_GET(trb->dwTrb3); if ((trb->dwTrb3 & XHCI_TRB_3_CYCLE_BIT) != @@ -1474,7 +1474,7 @@ pci_xhci_complete_commands(struct pci_xhci_softc *sc) } if (type != XHCI_TRB_TYPE_LINK) { - /* + /* * insert command completion event and assert intr */ evtrb.qwTrb0 = crcr; @@ -1602,7 +1602,7 @@ pci_xhci_xfer_complete(struct pci_xhci_softc *sc, struct usb_data_xfer *xfer, if (XHCI_TRB_3_TYPE_GET(trbflags) == XHCI_TRB_TYPE_EVENT_DATA) { DPRINTF(("pci_xhci EVENT_DATA edtla %u", edtla)); evtrb.qwTrb0 = trb->qwTrb0; - evtrb.dwTrb2 = (edtla & 0xFFFFF) | + evtrb.dwTrb2 = (edtla & 0xFFFFF) | XHCI_TRB_2_ERROR_SET(err); evtrb.dwTrb3 |= XHCI_TRB_3_ED_BIT; edtla = 0; @@ -2569,7 +2569,7 @@ pci_xhci_init_port(struct pci_xhci_softc *sc, int portn) if (dev) { port->portsc = XHCI_PS_CCS | /* connected */ XHCI_PS_PP; /* port power */ - + if (dev->dev_ue->ue_usbver == 2) { port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_POLL) | XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed); @@ -2578,7 +2578,7 @@ pci_xhci_init_port(struct pci_xhci_softc *sc, int portn) XHCI_PS_PED | /* enabled */ XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed); } - + DPRINTF(("Init port %d 0x%x", portn, port->portsc)); } else { port->portsc = XHCI_PS_PLS_SET(UPS_PORT_LS_RX_DET) | XHCI_PS_PP; diff --git a/usr/src/cmd/bhyve/rtc.c b/usr/src/cmd/bhyve/rtc.c index 0f63156adb..9125b4f86a 100644 --- a/usr/src/cmd/bhyve/rtc.c +++ b/usr/src/cmd/bhyve/rtc.c @@ -75,7 +75,7 @@ rtc_time(struct vmctx *ctx) void rtc_init(struct vmctx *ctx) -{ +{ size_t himem; size_t lomem; int err; diff --git a/usr/src/cmd/bhyve/smbiostbl.c b/usr/src/cmd/bhyve/smbiostbl.c index 6fd8cbac81..8c3cd6332d 100644 --- a/usr/src/cmd/bhyve/smbiostbl.c +++ b/usr/src/cmd/bhyve/smbiostbl.c @@ -53,9 +53,9 @@ __FBSDID("$FreeBSD$"); #define SMBIOS_BASE 0xF1000 -#define FIRMWARE_VERSION "13.0" +#define FIRMWARE_VERSION "14.0" /* The SMBIOS specification defines the date format to be mm/dd/yyyy */ -#define FIRMWARE_RELEASE_DATE "11/10/2020" +#define FIRMWARE_RELEASE_DATE "10/10/2021" /* BHYVE_ACPI_BASE - SMBIOS_BASE) */ #define SMBIOS_MAX_LENGTH (0xF2400 - 0xF1000) diff --git a/usr/src/cmd/bhyve/test/tests/mevent/Makefile b/usr/src/cmd/bhyve/test/tests/mevent/Makefile index 363deb02cc..9d93e17f5a 100644 --- a/usr/src/cmd/bhyve/test/tests/mevent/Makefile +++ b/usr/src/cmd/bhyve/test/tests/mevent/Makefile @@ -12,6 +12,7 @@ # # Copyright 2018 Joyent, Inc. # Copyright 2022 Oxide Computer Company +# Copyright 2022 OmniOS Community Edition (OmniOSce) Association. # TESTSUBDIR = mevent @@ -19,7 +20,9 @@ PROG = \ lists_delete \ read_disable \ read_pause \ - read_requeue + read_requeue \ + vnode_file \ + vnode_zvol SUPOBJS = mevent.o testlib.o @@ -34,8 +37,12 @@ install: $(TESTDIR) $(CMDS) $(CMDS): $(PROG) +vnode_zvol := LDLIBS += -lzfs -lnvpair + include ../../Makefile.targ %: %.o $(SUPOBJS) $(LINK.c) -o $@ $< $(SUPOBJS) $(LDLIBS) $(POST_PROCESS) + +mevent.o: ../../../mevent.c diff --git a/usr/src/cmd/bhyve/test/tests/mevent/mevent.c b/usr/src/cmd/bhyve/test/tests/mevent/mevent.c index 971cf4aa77..51c94a4c09 100644 --- a/usr/src/cmd/bhyve/test/tests/mevent/mevent.c +++ b/usr/src/cmd/bhyve/test/tests/mevent/mevent.c @@ -55,3 +55,9 @@ test_mevent_count_lists(int *ret_global, int *ret_change, int *ret_del_pending) *ret_change = change; *ret_del_pending = del_pending; } + +void +set_mevent_file_poll_interval_ms(int ms) +{ + mevent_file_poll_interval_ms = ms; +} diff --git a/usr/src/cmd/bhyve/test/tests/mevent/testlib.h b/usr/src/cmd/bhyve/test/tests/mevent/testlib.h index 7e5ca2e9c9..1639f29f87 100644 --- a/usr/src/cmd/bhyve/test/tests/mevent/testlib.h +++ b/usr/src/cmd/bhyve/test/tests/mevent/testlib.h @@ -71,6 +71,7 @@ #define ASSERT_INT_EQ(msg, got, exp) ASSERT_CMP(msg, got, ==, exp, "%d") #define ASSERT_INT_NEQ(msg, got, exp) ASSERT_CMP(msg, got, !=, exp, "%d") #define ASSERT_INT64_EQ(msg, got, exp) ASSERT_CMP(msg, got, ==, exp, "%ld") +#define ASSERT_INT64_NEQ(msg, got, exp) ASSERT_CMP(msg, got, !=, exp, "%ld") #define ASSERT_PTR_EQ(msg, got, exp) ASSERT_CMP(msg, got, ==, exp, "%p") #define ASSERT_PTR_NEQ(msg, got, exp) ASSERT_CMP(msg, got, !=, exp, "%p") @@ -89,5 +90,6 @@ extern boolean_t testlib_verbose; extern void start_test(const char *, uint32_t); extern void start_event_thread(void); extern void test_mevent_count_lists(int *, int *, int *); +extern void set_mevent_file_poll_interval_ms(int); #endif /* _TESTLIB_H_ */ diff --git a/usr/src/cmd/bhyve/test/tests/mevent/vnode_file.c b/usr/src/cmd/bhyve/test/tests/mevent/vnode_file.c new file mode 100644 index 0000000000..850ac1be27 --- /dev/null +++ b/usr/src/cmd/bhyve/test/tests/mevent/vnode_file.c @@ -0,0 +1,141 @@ +/* + * 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 Joyent, Inc. + * Copyright 2022 OmniOS Community Edition (OmniOSce) Association. + */ + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include "testlib.h" +#include "mevent.h" + +static char *cookie = "Chocolate chip with fudge stripes"; + +static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; + +static void +callback(int fd, enum ev_type ev, void *arg) +{ + static off_t size = 0; + struct stat st; + + ASSERT_INT_EQ(("bad event"), ev, EVF_VNODE); + ASSERT_PTR_EQ(("bad cookie"), arg, cookie); + + if (fstat(fd, &st) != 0) + FAIL_ERRNO("fstat failed"); + + ASSERT_INT64_NEQ(("File size has not changed"), size, st.st_size); + size = st.st_size; + + pthread_mutex_lock(&mtx); + pthread_cond_signal(&cv); + VERBOSE(("wakeup")); + pthread_mutex_unlock(&mtx); +} + +static void +test_fd(int fd, char *tag) +{ + struct mevent *evp; + int err; + + evp = mevent_add_flags(fd, EVF_VNODE, EVFF_ATTRIB, callback, cookie); + ASSERT_PTR_NEQ(("%s: mevent_add", tag), evp, NULL); + + for (uint_t i = 0; cookie[i] != '\0'; i++) { + ssize_t written; + + pthread_mutex_lock(&mtx); + + if (i > 0) { + /* + * Check that no events are emitted for writes which do + * not alter the size. + */ + if (lseek(fd, -1, SEEK_CUR) == -1) + FAIL_ERRNO("lseek"); + if (write(fd, "X", 1) == -1) + FAIL_ERRNO("write"); + } + + written = write(fd, cookie + i, 1); + if (written < 0) + FAIL_ERRNO("bad write"); + ASSERT_INT64_EQ(("write byte %d of cookie", i), written, 1); + + /* Wait for the size change to be processed */ + pthread_cond_wait(&cv, &mtx); + pthread_mutex_unlock(&mtx); + /* + * This is a bit unsatisfactory but we need to allow time + * for mevent to re-associate the port or the next write could + * be missed. + */ + usleep(500); + } + + err = mevent_disable(evp); + ASSERT_INT_EQ(("%s: mevent_disable: %s", tag, strerror(err)), err, 0); + + (void) printf("PASS %s - %s\n", testlib_prog, tag); +} + +int +main(int argc, const char **argv) +{ + start_test(argv[0], 5); + start_event_thread(); + int fd; + + /* Test with a temporary file in /tmp */ + char *template = strdup("/tmp/mevent.vnode.XXXXXX"); + ASSERT_PTR_NEQ(("strdup"), template, NULL); + fd = mkstemp(template); + if (fd == -1) + FAIL_ERRNO("Couldn't create temporary file with mkstemp"); + + VERBOSE(("Opened temporary file at '%s'", template)); + + test_fd(fd, "temporary file"); + + /* Test with a file which is unlinked from the filesystem */ + FILE *fp = tmpfile(); + ASSERT_PTR_NEQ(("tmpfile"), fp, NULL); + + fd = fileno(fp); + if (fd == -1) + FAIL_ERRNO("Couldn't get file descriptor for temporary file"); + + test_fd(fd, "anon file"); + + /* + * Defer to here to avoid generating a new event before the disable has + * been processed and the port deassociated. + */ + unlink(template); + free(template); + + PASS(); +} diff --git a/usr/src/cmd/bhyve/test/tests/mevent/vnode_zvol.c b/usr/src/cmd/bhyve/test/tests/mevent/vnode_zvol.c new file mode 100644 index 0000000000..8e99d7ba0d --- /dev/null +++ b/usr/src/cmd/bhyve/test/tests/mevent/vnode_zvol.c @@ -0,0 +1,259 @@ +/* + * 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 Joyent, Inc. + * Copyright 2022 OmniOS Community Edition (OmniOSce) Association. + */ + +#include <errno.h> +#include <fcntl.h> +#include <libzfs.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <unistd.h> +#include <zone.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include "testlib.h" +#include "mevent.h" + +#define MB (1024 * 1024) + +static char *cookie = "Chocolate chip with fudge stripes"; + +static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; + +static void +callback(int fd, enum ev_type ev, void *arg) +{ + static off_t size = 0; + struct stat st; + + ASSERT_INT_EQ(("bad event"), ev, EVF_VNODE); + ASSERT_PTR_EQ(("bad cookie"), arg, cookie); + + if (fstat(fd, &st) != 0) + FAIL_ERRNO("fstat failed"); + + ASSERT_INT64_NEQ(("Size has not changed"), size, st.st_size); + size = st.st_size; + + pthread_mutex_lock(&mtx); + pthread_cond_signal(&cv); + VERBOSE(("wakeup")); + pthread_mutex_unlock(&mtx); +} + +static void +destroy_zpool(libzfs_handle_t *zfshdl, zpool_handle_t *poolhdl, + zfs_handle_t *volhdl) +{ + if (volhdl != NULL) { + if (zfs_destroy(volhdl, B_FALSE) != 0) { + FAIL(("Failed to destroy ZVOL - %s", + libzfs_error_description(zfshdl))); + } + } + + if (poolhdl != NULL) { + if (zpool_destroy(poolhdl, testlib_prog) != 0) { + FAIL(("Failed to destroy ZPOOL - %s", + libzfs_error_description(zfshdl))); + } + } +} + +static void +create_zpool(libzfs_handle_t *zfshdl, const char *pool, const char *file) +{ + nvlist_t *nvroot, *props; + nvlist_t *vdevs[1]; + + nvroot = fnvlist_alloc(); + props = fnvlist_alloc(); + vdevs[0] = fnvlist_alloc(); + + fnvlist_add_string(vdevs[0], ZPOOL_CONFIG_PATH, file); + fnvlist_add_string(vdevs[0], ZPOOL_CONFIG_TYPE, VDEV_TYPE_FILE); + fnvlist_add_uint64(vdevs[0], ZPOOL_CONFIG_IS_LOG, 0); + + fnvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT); + fnvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, vdevs, 1); + + fnvlist_add_string(props, + zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), ZFS_MOUNTPOINT_NONE); + + if (zpool_create(zfshdl, pool, nvroot, NULL, props) != 0) { + FAIL(("Failed to create ZPOOL %s using %s - %s", + pool, file, libzfs_error_description(zfshdl))); + } + + VERBOSE(("Created ZFS pool %s", pool)); +} + +static bool +create_zvol(libzfs_handle_t *zfshdl, const char *vol) +{ + nvlist_t *volprops; + int err; + + volprops = fnvlist_alloc(); + fnvlist_add_uint64(volprops, + zfs_prop_to_name(ZFS_PROP_VOLSIZE), 1 * MB); + + err = zfs_create(zfshdl, vol, ZFS_TYPE_VOLUME, volprops); + if (err != 0) { + (void) printf("Failed to create ZVOL %s - %s", + vol, libzfs_error_description(zfshdl)); + return (false); + } + + VERBOSE(("Created ZVOL %s", vol)); + return (true); +} + +int +main(int argc, const char **argv) +{ + libzfs_handle_t *zfshdl; + char *template, *pool, *vol, *backend; + struct mevent *evp; + zpool_handle_t *poolhdl = NULL; + zfs_handle_t *volhdl = NULL; + int err, fd; + + start_test(argv[0], 10); + set_mevent_file_poll_interval_ms(1000); + + if (getzoneid() != GLOBAL_ZONEID) + FAIL(("Can only be run in the global zone")); + + if ((zfshdl = libzfs_init()) == NULL) + FAIL_ERRNO("Could not open ZFS library"); + + template = strdup("/tmp/mevent.vnode.zvol.XXXXXX"); + ASSERT_PTR_NEQ(("strdup"), template, NULL); + fd = mkstemp(template); + if (fd == -1) + FAIL_ERRNO("Couldn't create temporary file with mkstemp"); + VERBOSE(("Opened temporary file at '%s'", template)); + + err = asprintf(&pool, "mevent_test_%d", getpid()); + ASSERT_INT_NEQ(("asprintf pool"), err, -1); + + err = asprintf(&vol, "%s/test_zvol_%d", pool, getpid()); + ASSERT_INT_NEQ(("asprintf vol"), err, -1); + + err = asprintf(&backend, "/dev/zvol/rdsk/%s", vol); + ASSERT_INT_NEQ(("asprintf backend"), err, -1); + + err = ftruncate(fd, 64 * MB); + if (err != 0) + FAIL_ERRNO("ftruncate"); + (void) close(fd); + fd = -1; + + /* + * Create the pool as late as possible to reduce the risk of leaving + * a test pool hanging around. + */ + create_zpool(zfshdl, pool, template); + + if ((poolhdl = zpool_open(zfshdl, pool)) == NULL) { + (void) printf("Could not open ZPOOL - %s\n", + libzfs_error_description(zfshdl)); + err = EXIT_FAIL; + goto out; + } + + if (!create_zvol(zfshdl, vol)) { + err = EXIT_FAIL; + goto out; + } + + if ((volhdl = zfs_open(zfshdl, vol, ZFS_TYPE_VOLUME)) == NULL) { + (void) printf("Could not open ZFS volume - %s\n", + libzfs_error_description(zfshdl)); + err = EXIT_FAIL; + goto out; + } + + if ((fd = open(backend, O_RDWR)) == -1) { + (void) printf("Failed to open '%s': %s\n", + backend, strerror(errno)); + err = EXIT_FAIL; + goto out; + } + VERBOSE(("Opened backend %s", backend)); + + start_event_thread(); + + evp = mevent_add_flags(fd, EVF_VNODE, EVFF_ATTRIB, callback, cookie); + if (evp == NULL) { + (void) printf("mevent_add returned NULL\n"); + err = EXIT_FAIL; + goto out; + } + + for (uint_t i = 2; i < 4; i++) { + ssize_t written; + char buf[64]; + + /* + * Check that a write to the volume does not trigger an event. + */ + if (lseek(fd, 0, SEEK_SET) == -1) + FAIL_ERRNO("lseek"); + written = write(fd, cookie, strlen(cookie)); + if (written < 0) + FAIL_ERRNO("bad write"); + ASSERT_INT64_EQ(("write cookie", i), written, strlen(cookie)); + + (void) snprintf(buf, sizeof (buf), "%llu", i * MB); + VERBOSE(("Setting volsize to %s", buf)); + + if (zfs_prop_set(volhdl, + zfs_prop_to_name(ZFS_PROP_VOLSIZE), buf) != 0) { + (void) printf("Failed to increase ZFS volume size\n"); + pthread_mutex_unlock(&mtx); + err = EXIT_FAIL; + goto out; + } + + /* Wait for the size change to be processed */ + pthread_mutex_lock(&mtx); + pthread_cond_wait(&cv, &mtx); + pthread_mutex_unlock(&mtx); + } + + (void) mevent_disable(evp); + + err = EXIT_PASS; + +out: + + (void) close(fd); + destroy_zpool(zfshdl, poolhdl, volhdl); + (void) libzfs_fini(zfshdl); + (void) unlink(template); + + if (err == EXIT_PASS) + PASS(); + + exit(err); +} diff --git a/usr/src/cmd/bhyve/uart_emul.c b/usr/src/cmd/bhyve/uart_emul.c index a04229b288..7ada0e76ee 100644 --- a/usr/src/cmd/bhyve/uart_emul.c +++ b/usr/src/cmd/bhyve/uart_emul.c @@ -221,7 +221,7 @@ rxfifo_reset(struct uart_softc *sc, int size) struct fifo *fifo; ssize_t nread; int error; - + fifo = &sc->rxfifo; bzero(fifo, sizeof(struct fifo)); fifo->size = size; diff --git a/usr/src/cmd/bhyve/usb_mouse.c b/usr/src/cmd/bhyve/usb_mouse.c index 340fdc0cb0..21e8873c5f 100644 --- a/usr/src/cmd/bhyve/usb_mouse.c +++ b/usr/src/cmd/bhyve/usb_mouse.c @@ -533,8 +533,8 @@ umouse_request(void *scarg, struct usb_data_xfer *xfer) eshort = data->blen > 0; break; - case UREQ(UR_GET_STATUS, UT_READ_INTERFACE): - case UREQ(UR_GET_STATUS, UT_READ_ENDPOINT): + case UREQ(UR_GET_STATUS, UT_READ_INTERFACE): + case UREQ(UR_GET_STATUS, UT_READ_ENDPOINT): DPRINTF(("umouse: (UR_GET_STATUS, UT_READ_INTERFACE)")); if (data != NULL && len > 1) { USETW(udata, 0); @@ -757,7 +757,7 @@ umouse_data_handler(void *scarg, struct usb_data_xfer *xfer, int dir, sc->polling = 0; pthread_mutex_unlock(&sc->mtx); - } else { + } else { USB_DATA_SET_ERRCODE(data, USB_STALL); err = USB_ERR_STALLED; } diff --git a/usr/src/cmd/bhyvectl/Makefile b/usr/src/cmd/bhyvectl/Makefile index 01d331c823..486f39da31 100644 --- a/usr/src/cmd/bhyvectl/Makefile +++ b/usr/src/cmd/bhyvectl/Makefile @@ -35,6 +35,9 @@ CPPFLAGS = -I$(COMPAT)/bhyve -I$(CONTRIB)/bhyve \ -I$(SRC)/uts/i86pc LDLIBS += -lvmmapi +# Force c99 for everything +CSTD= $(CSTD_GNU99) + CERRWARN += -_gcc=-Wno-uninitialized # main() is too hairy for smatch diff --git a/usr/src/cmd/bhyvectl/bhyvectl.c b/usr/src/cmd/bhyvectl/bhyvectl.c index 4fc6ddc251..cbe779a4ea 100644 --- a/usr/src/cmd/bhyvectl/bhyvectl.c +++ b/usr/src/cmd/bhyvectl/bhyvectl.c @@ -39,7 +39,7 @@ * * Copyright 2015 Pluribus Networks Inc. * Copyright 2019 Joyent, Inc. - * Copyright 2021 Oxide Computer Company + * Copyright 2022 Oxide Computer Company */ #include <sys/cdefs.h> @@ -51,6 +51,9 @@ __FBSDID("$FreeBSD$"); #include <sys/errno.h> #include <sys/mman.h> #include <sys/cpuset.h> +#ifndef __FreeBSD__ +#include <sys/fp.h> +#endif /* __FreeBSD__ */ #include <stdio.h> #include <stdlib.h> @@ -312,6 +315,7 @@ static int get_cpu_topology; #ifndef __FreeBSD__ static int pmtmr_port; static int wrlock_cycle; +static int get_fpu; #endif /* @@ -1534,6 +1538,7 @@ setup_options(bool cpu_intel) #ifndef __FreeBSD__ { "pmtmr-port", REQ_ARG, 0, PMTMR_PORT }, { "wrlock-cycle", NO_ARG, &wrlock_cycle, 1 }, + { "get-fpu", NO_ARG, &get_fpu, 1 }, #endif }; @@ -1752,6 +1757,93 @@ show_memseg(struct vmctx *ctx) } } +#ifndef __FreeBSD__ +static int +show_fpu(struct vmctx *ctx, int vcpu) +{ + int res, fd; + + struct vm_fpu_desc_entry entries[64]; + struct vm_fpu_desc desc = { + .vfd_entry_data = entries, + .vfd_num_entries = 64, + }; + fd = vm_get_device_fd(ctx); + res = ioctl(fd, VM_DESC_FPU_AREA, &desc); + if (res != 0) { + return (errno); + } + for (uint_t i = 0; i < desc.vfd_num_entries; i++) { + const struct vm_fpu_desc_entry *entry = &entries[i]; + + /* confirm that AVX fields are where we expect */ + if (entry->vfde_feature == XFEATURE_AVX) { + if (entry->vfde_size != 0x100 || + entry->vfde_off != 0x240) { + (void) fprintf(stderr, + "show_fpu: unexpected AVX size/placement " + "- size:%x off:%x\n", + entry->vfde_size, entry->vfde_off); + return (EINVAL); + } + } + } + void *buf = malloc(desc.vfd_req_size); + if (buf == NULL) { + return (ENOMEM); + } + struct vm_fpu_state req = { + .vcpuid = vcpu, + .buf = buf, + .len = desc.vfd_req_size, + }; + res = ioctl(fd, VM_GET_FPU, &req); + if (res != 0) { + res = errno; + free(buf); + return (res); + } + + const struct xsave_state *state = buf; + const struct fxsave_state *fx = &state->xs_fxsave; + (void) printf("fpu_fcw[%d]\t\t0x%04x\n", vcpu, fx->fx_fcw); + (void) printf("fpu_fsw[%d]\t\t0x%04x\n", vcpu, fx->fx_fsw); + (void) printf("fpu_ftw[%d]\t\t0x%04x\n", vcpu, fx->fx_fctw); + (void) printf("fpu_fop[%d]\t\t0x%04x\n", vcpu, fx->fx_fop); + (void) printf("fpu_rip[%d]\t\t0x%016lx\n", vcpu, fx->fx_rip); + (void) printf("fpu_rdp[%d]\t\t0x%016lx\n", vcpu, fx->fx_rdp); + (void) printf("fpu_mxcsr[%d]\t\t0x%08x\n", vcpu, fx->fx_mxcsr); + (void) printf("fpu_mxcsr_mask[%d]\t0x%08x\n", vcpu, + fx->fx_mxcsr_mask); + /* ST/MMX regs */ + for (uint_t i = 0; i < 8; i++) { + (void) printf("fpu_st%u[%d]\t\t0x%08x%08x%08x%08x\n", vcpu, i, + fx->fx_st[i].__fpr_pad[0], fx->fx_st[i].__fpr_pad[1], + fx->fx_st[i].__fpr_pad[2], fx->fx_st[i].__fpr_pad[3]); + } + /* SSE regs */ + for (uint_t i = 0; i < 16; i++) { + (void) printf("fpu_xmm%u[%d]\t\t0x%08x%08x%08x%08x\n", + i, vcpu, + fx->fx_xmm[i]._l[0], fx->fx_xmm[i]._l[1], + fx->fx_xmm[i]._l[2], fx->fx_xmm[i]._l[3]); + } + + if (state->xs_header.xsh_xstate_bv & XFEATURE_AVX) { + /* AVX regs */ + for (uint_t i = 0; i < 16; i++) { + (void) printf("fpu_ymm%u[%d]\t\t0x%08x%08x%08x%08x\n", + i, vcpu, + state->xs_ymm[i]._l[0], state->xs_ymm[i]._l[1], + state->xs_ymm[i]._l[2], state->xs_ymm[i]._l[3]); + } + } + + free(buf); + return (0); +} +#endif /*__FreeBSD__ */ + int main(int argc, char *argv[]) { @@ -2150,6 +2242,12 @@ main(int argc, char *argv[]) if (!error) error = get_all_segments(ctx, vcpu); +#ifndef __FreeBSD__ + if (!error && (get_fpu || get_all)) { + error = show_fpu(ctx, vcpu); + } +#endif /* __FreeBSD__ */ + if (!error) { if (cpu_intel) error = get_misc_vmcs(ctx, vcpu); diff --git a/usr/src/cmd/cmd-inet/etc/services b/usr/src/cmd/cmd-inet/etc/services index 37514ac0a7..4562baff66 100644 --- a/usr/src/cmd/cmd-inet/etc/services +++ b/usr/src/cmd/cmd-inet/etc/services @@ -1,6 +1,7 @@ # # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2015 Joyent, Inc. # # CDDL HEADER START # @@ -33,7 +34,7 @@ systat 11/tcp users daytime 13/tcp daytime 13/udp netstat 15/tcp -qotd 17/tcp # Quote of the Day +qotd 17/tcp # Quote of the Day chargen 19/tcp ttytst source chargen 19/udp ttytst source ftp-data 20/tcp @@ -80,7 +81,7 @@ imap3 220/tcp imap3 220/udp clearcase 371/tcp clearcase 371/udp -ldap 389/tcp # Lightweight Directory Access Protocol +ldap 389/tcp # Lightweight Directory Access Protocol ldap 389/udp # Lightweight Directory Access Protocol https 443/tcp https 443/udp @@ -227,6 +228,7 @@ eklogin 2105/tcp # Kerberos encrypted rlogin lockd 4045/udp # NFS lock daemon/manager lockd 4045/tcp ipsec-nat-t 4500/udp # IPsec NAT-Traversal +vxlan 4789/udp # Virtual eXtensible Local Area Network (VXLAN) mdns 5353/udp # Multicast DNS mdns 5353/tcp vnc-server 5900/tcp # VNC Server diff --git a/usr/src/cmd/cmd-inet/usr.lib/in.ndpd/ndp.xml b/usr/src/cmd/cmd-inet/usr.lib/in.ndpd/ndp.xml index e90b3ba149..4459def5c8 100644 --- a/usr/src/cmd/cmd-inet/usr.lib/in.ndpd/ndp.xml +++ b/usr/src/cmd/cmd-inet/usr.lib/in.ndpd/ndp.xml @@ -76,7 +76,7 @@ value='solaris.smf.manage.routing' /> </property_group> - <!-- Properties in this group are used by routeadm (1M) --> + <!-- Properties in this group are used by routeadm(8) --> <property_group name='routeadm' type='application'> <stability value='Unstable' /> <!-- @@ -94,7 +94,7 @@ </property_group> - <!-- Properties in this group are modifiable via routeadm (1M) --> + <!-- Properties in this group are modifiable via routeadm(8) --> <property_group name='routing' type='application'> <stability value='Evolving' /> diff --git a/usr/src/cmd/cmd-inet/usr.lib/in.ripngd/ripng.xml b/usr/src/cmd/cmd-inet/usr.lib/in.ripngd/ripng.xml index 17b697fe95..fbfc77bee1 100644 --- a/usr/src/cmd/cmd-inet/usr.lib/in.ripngd/ripng.xml +++ b/usr/src/cmd/cmd-inet/usr.lib/in.ripngd/ripng.xml @@ -95,7 +95,7 @@ privileges='basic,proc_owner,proc_fork,proc_exec,proc_info,proc_session,file_cho value='solaris.smf.manage.routing' /> </property_group> - <!-- Properties in this group are used by routeadm (1M) --> + <!-- Properties in this group are used by routeadm(8) --> <property_group name='routeadm' type='application'> <stability value='Unstable' /> <!-- Identifies service as a routing service --> @@ -106,7 +106,7 @@ privileges='basic,proc_owner,proc_fork,proc_exec,proc_info,proc_session,file_cho value='solaris.smf.value.routing' /> </property_group> - <!-- Properties in this group are modifiable via routeadm (1M) --> + <!-- Properties in this group are modifiable via routeadm(8) --> <property_group name='routing' type='application'> <stability value='Evolving' /> diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.rdisc/rdisc.xml b/usr/src/cmd/cmd-inet/usr.sbin/in.rdisc/rdisc.xml index 3cdd0cd35c..2ef0b8701b 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.rdisc/rdisc.xml +++ b/usr/src/cmd/cmd-inet/usr.sbin/in.rdisc/rdisc.xml @@ -78,7 +78,7 @@ privileges='basic,proc_owner,proc_fork,proc_exec,proc_info,proc_session,file_cho value='solaris.smf.manage.routing' /> </property_group> - <!-- Properties in this group are used by routeadm (1M) --> + <!-- Properties in this group are used by routeadm(8) --> <property_group name='routeadm' type='application'> <stability value='Unstable' /> <propval name='protocol' type='astring' value='ipv4' /> @@ -89,7 +89,7 @@ privileges='basic,proc_owner,proc_fork,proc_exec,proc_info,proc_session,file_cho </property_group> - <!-- Properties in this group are modifiable via routeadm (1M) --> + <!-- Properties in this group are modifiable via routeadm(8) --> <property_group name='routing' type='application'> <stability value='Evolving' /> diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.rlogind.c b/usr/src/cmd/cmd-inet/usr.sbin/in.rlogind.c index 5d3bc60abf..1c495aff84 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.rlogind.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/in.rlogind.c @@ -3,8 +3,8 @@ * Use is subject to license terms. */ -/* Copyright(c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ +/* Copyright(c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ /* * Copyright (c) 1983 The Regents of the University of California. @@ -1057,13 +1057,13 @@ doit(int f, if ((p = open("/dev/ptmx", O_RDWR)) == -1) fatalperror(f, "cannot open /dev/ptmx"); if (grantpt(p) == -1) - fatal(f, "could not grant slave pty"); + fatal(f, "could not grant subsidiary pty"); if (unlockpt(p) == -1) - fatal(f, "could not unlock slave pty"); + fatal(f, "could not unlock subsidiary pty"); if ((line = ptsname(p)) == NULL) - fatal(f, "could not enable slave pty"); + fatal(f, "could not enable subsidiary pty"); if ((t = open(line, O_RDWR)) == -1) - fatal(f, "could not open slave pty"); + fatal(f, "could not open subsidiary pty"); if (ioctl(t, I_PUSH, "ptem") == -1) fatalperror(f, "ioctl I_PUSH ptem"); if (ioctl(t, I_PUSH, "ldterm") == -1) @@ -1128,9 +1128,9 @@ doit(int f, /* * System V ptys allow the TIOC{SG}WINSZ ioctl to be - * issued on the master side of the pty. Luckily, that's + * issued on the manager side of the pty. Luckily, that's * the only tty ioctl we need to do do, so we can close the - * slave side in the parent process after the fork. + * subsidiary side in the parent process after the fork. */ (void) ioctl(p, TIOCSWINSZ, &win); @@ -1161,12 +1161,12 @@ doit(int f, if (setsid() == -1) fatalperror(f, "setsid"); if ((tt = open(line, O_RDWR)) == -1) - fatalperror(f, "could not re-open slave pty"); + fatalperror(f, "could not re-open subsidiary pty"); if (close(p) == -1) - fatalperror(f, "error closing pty master"); + fatalperror(f, "error closing pty manager"); if (close(t) == -1) - fatalperror(f, "error closing pty slave" + fatalperror(f, "error closing pty subsidiary" " opened before session established"); /* * If this fails we may or may not be able to output an @@ -1209,8 +1209,8 @@ doit(int f, /* * Must ignore SIGTTOU, otherwise we'll stop - * when we try and set slave pty's window shape - * (our controlling tty is the master pty). + * when we try and set subsidiary pty's window shape + * (our controlling tty is the manager pty). * Likewise, we don't want any of the tty-generated * signals from chars passing through. */ @@ -1332,7 +1332,7 @@ static void protocol(int f, int p, int encr_flag) { struct stat buf; - struct protocol_arg rloginp; + struct protocol_arg rloginp; struct strioctl rloginmod; int ptmfd; /* fd of logindmux coneected to ptmx */ int netfd; /* fd of logindmux connected to netf */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.routed/route.xml b/usr/src/cmd/cmd-inet/usr.sbin/in.routed/route.xml index 3e10fbacd2..e9d73eb57f 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.routed/route.xml +++ b/usr/src/cmd/cmd-inet/usr.sbin/in.routed/route.xml @@ -80,7 +80,7 @@ privileges='basic,proc_owner,proc_fork,proc_exec,proc_info,proc_session,file_cho value='solaris.smf.manage.routing' /> </property_group> - <!-- Properties in this group are used by routeadm (1M) --> + <!-- Properties in this group are used by routeadm(8) --> <property_group name='routeadm' type='application'> <stability value='Unstable' /> <propval name='protocol' type='astring' value='ipv4' /> @@ -90,7 +90,7 @@ privileges='basic,proc_owner,proc_fork,proc_exec,proc_info,proc_session,file_cho value='solaris.smf.value.routing' /> </property_group> - <!-- Properties in this group are modifiable via routeadm (1M) --> + <!-- Properties in this group are modifiable via routeadm(8) --> <property_group name='routing' type='application'> <stability value='Evolving' /> diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.telnetd.c b/usr/src/cmd/cmd-inet/usr.sbin/in.telnetd.c index aa5a27c0b7..08ad200c45 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.telnetd.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/in.telnetd.c @@ -242,7 +242,7 @@ static int cryptmod_fd = -1; #define TS_DONT 8 /* dont " */ static int ncc; -static int master; /* master side of pty */ +static int manager; /* manager side of pty */ static int pty; /* side of pty that gets ioctls */ static int net; static int inter; @@ -2754,20 +2754,20 @@ doit(int f, struct sockaddr_storage *who) char username[MAXUSERNAMELEN]; int len; uchar_t passthru; - char *slavename; + char *subsidname; if ((p = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) { fatalperror(f, "open /dev/ptmx", errno); } if (grantpt(p) == -1) - fatal(f, "could not grant slave pty"); + fatal(f, "could not grant subsidiary pty"); if (unlockpt(p) == -1) - fatal(f, "could not unlock slave pty"); - if ((slavename = ptsname(p)) == NULL) - fatal(f, "could not enable slave pty"); + fatal(f, "could not unlock subsidiary pty"); + if ((subsidname = ptsname(p)) == NULL) + fatal(f, "could not enable subsidiary pty"); (void) dup2(f, 0); - if ((t = open(slavename, O_RDWR | O_NOCTTY)) == -1) - fatal(f, "could not open slave pty"); + if ((t = open(subsidname, O_RDWR | O_NOCTTY)) == -1) + fatal(f, "could not open subsidiary pty"); if (ioctl(t, I_PUSH, "ptem") == -1) fatalperror(f, "ioctl I_PUSH ptem", errno); if (ioctl(t, I_PUSH, "ldterm") == -1) @@ -2775,7 +2775,7 @@ doit(int f, struct sockaddr_storage *who) if (ioctl(t, I_PUSH, "ttcompat") == -1) fatalperror(f, "ioctl I_PUSH ttcompat", errno); - line = slavename; + line = subsidname; pty = t; @@ -3039,7 +3039,7 @@ doit(int f, struct sockaddr_storage *who) fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of ptmfd failed\n"); net = netfd; - master = ptmfd; + manager = ptmfd; cryptmod_fd = netfd; /* @@ -3100,11 +3100,11 @@ doit(int f, struct sockaddr_storage *who) if ((pid = fork()) < 0) fatalperror(netfd, "fork", errno); if (pid) - telnet(net, master); + telnet(net, manager); /* * The child process needs to be the session leader * and have the pty as its controlling tty. Thus we need - * to re-open the slave side of the pty no without + * to re-open the subsidiary side of the pty no without * the O_NOCTTY flag that we have been careful to * use up to this point. */ @@ -3130,10 +3130,10 @@ doit(int f, struct sockaddr_storage *who) if (terminaltype) (void) local_setenv("TERM", terminaltype+5, 1); /* - * -h : pass on name of host. + * -h : pass on name of host. * WARNING: -h is accepted by login if and only if * getuid() == 0. - * -p : don't clobber the environment (so terminal type stays set). + * -p : don't clobber the environment (so terminal type stays set). */ { /* System V login expects a utmp entry to already be there */ @@ -3192,7 +3192,7 @@ doit(int f, struct sockaddr_storage *who) ((AuthenticatingUser != NULL) && strlen(AuthenticatingUser))) { (void) execl(LOGIN_PROGRAM, "login", "-p", - "-d", slavename, + "-d", subsidname, "-h", host, "-u", krb5_name, "-s", pam_svc_name, @@ -3208,7 +3208,7 @@ doit(int f, struct sockaddr_storage *who) */ (void) execl(LOGIN_PROGRAM, "login", "-p", - "-d", slavename, + "-d", subsidname, "-h", host, "-s", pam_svc_name, "--", (AuthenticatingUser != NULL ? AuthenticatingUser : @@ -3216,7 +3216,7 @@ doit(int f, struct sockaddr_storage *who) } else /* default, no auth. info available, login does it all */ { (void) execl(LOGIN_PROGRAM, "login", - "-p", "-h", host, "-d", slavename, "--", + "-p", "-h", host, "-d", subsidname, "--", getenv("USER"), 0); } @@ -3254,7 +3254,7 @@ fatalperror(int f, char *msg, int errnum) * inkernel telnet streams module (telmod). */ static void -telnet(int net, int master) +telnet(int net, int manager) { int on = 1; char mode; @@ -3265,7 +3265,7 @@ telnet(int net, int master) if (ioctl(net, FIONBIO, &on) == -1) syslog(LOG_INFO, "ioctl FIONBIO net: %m\n"); - if (ioctl(master, FIONBIO, &on) == -1) + if (ioctl(manager, FIONBIO, &on) == -1) syslog(LOG_INFO, "ioctl FIONBIO pty p: %m\n"); (void) signal(SIGTSTP, SIG_IGN); (void) signal(SIGCHLD, (void (*)())cleanup); @@ -3302,7 +3302,7 @@ telnet(int net, int master) * stuff in the corresponding output buffer */ if (pfrontp - pbackp) { - FD_SET(master, &obits); + FD_SET(manager, &obits); } else { FD_SET(net, &ibits); } @@ -3390,7 +3390,7 @@ telnet(int net, int master) fatal(net, "ioctl TEL_IOC_GETBLK failed\n"); } - if ((c = select(max(net, master) + 1, &ibits, &obits, &xbits, + if ((c = select(max(net, manager) + 1, &ibits, &obits, &xbits, (struct timeval *)0)) < 1) { if (c == -1) { if (errno == EINTR) { @@ -3427,7 +3427,7 @@ telnet(int net, int master) netflush(); if (ncc > 0) telrcv(); - if (FD_ISSET(master, &obits) && (pfrontp - pbackp) > 0) + if (FD_ISSET(manager, &obits) && (pfrontp - pbackp) > 0) ptyflush(); } cleanup(0); @@ -4279,7 +4279,7 @@ ptyflush(void) int n; if ((n = pfrontp - pbackp) > 0) - n = write(master, pbackp, n); + n = write(manager, pbackp, n); if (n < 0) return; pbackp += n; @@ -4447,9 +4447,9 @@ cleanup(int signum) /* * If the TEL_IOC_ENABLE ioctl hasn't completed, then we need to * handle closing differently. We close "net" first and then - * "master" in that order. We do close(net) first because + * "manager" in that order. We do close(net) first because * we have no other way to disconnect forwarding between the network - * and master. So by issuing the close()'s we ensure that no further + * and manager. So by issuing the close()'s we ensure that no further * data rises from TCP. A more complex fix would be adding proper * support for throwing a "stop" switch for forwarding data between * logindmux peers. It's possible to block in the close of the tty @@ -4460,7 +4460,7 @@ cleanup(int signum) if (!telmod_init_done) { (void) close(net); - (void) close(master); + (void) close(manager); } rmut(); diff --git a/usr/src/cmd/cmd-inet/usr.sbin/routeadm/forwarding.xml b/usr/src/cmd/cmd-inet/usr.sbin/routeadm/forwarding.xml index 88e9b5b855..2bdcaa6299 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/routeadm/forwarding.xml +++ b/usr/src/cmd/cmd-inet/usr.sbin/routeadm/forwarding.xml @@ -108,7 +108,7 @@ value='solaris.smf.manage.routing' /> </property_group> - <!-- Properties in this group are modifiable via routeadm (1M) --> + <!-- Properties in this group are modifiable via routeadm(8) --> <property_group name='routeadm' type='application'> <propval name='default-ipv4-forwarding' type='boolean' value='false' /> @@ -212,7 +212,7 @@ value='solaris.smf.manage.routing' /> </property_group> - <!-- Properties in this group are modifiable via routeadm (1M) --> + <!-- Properties in this group are modifiable via routeadm(8) --> <property_group name='routeadm' type='application'> <propval name='default-ipv6-forwarding' type='boolean' value='false' /> diff --git a/usr/src/cmd/cmd-inet/usr.sbin/routeadm/legacy-routing.xml b/usr/src/cmd/cmd-inet/usr.sbin/routeadm/legacy-routing.xml index 33b0bde139..30902c43b5 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/routeadm/legacy-routing.xml +++ b/usr/src/cmd/cmd-inet/usr.sbin/routeadm/legacy-routing.xml @@ -94,7 +94,7 @@ <instance name='ipv4' enabled='false'> - <!-- Properties in this group are used by routeadm (1M) --> + <!-- Properties in this group are used by routeadm(8) --> <property_group name='routeadm' type='application'> <stability value='Evolving' /> <propval name='protocol' type='astring' value='ipv4' /> @@ -116,7 +116,7 @@ <instance name='ipv6' enabled='false'> - <!-- Properties in this group are used by routeadm (1M) --> + <!-- Properties in this group are used by routeadm(8) --> <property_group name='routeadm' type='application'> <stability value='Evolving' /> <propval name='protocol' type='astring' value='ipv6' /> diff --git a/usr/src/cmd/dcs/sparc/sun4u/rdr_messages.c b/usr/src/cmd/dcs/sparc/sun4u/rdr_messages.c index 187319c234..0ef0dde39d 100644 --- a/usr/src/cmd/dcs/sparc/sun4u/rdr_messages.c +++ b/usr/src/cmd/dcs/sparc/sun4u/rdr_messages.c @@ -1291,7 +1291,7 @@ rdr_setopt(int fd, int name, int level) * Bind the specified file descriptor to a specified * address. If the address is already bound, no error is * returned. This is the expected behavior if a server - * has been started by inetd (1M). + * has been started by inetd(8). */ static int rdr_bind(int fd, struct sockaddr *addr) @@ -1322,7 +1322,7 @@ rdr_bind(int fd, struct sockaddr *addr) * Ignore the error if EINVAL is returned. In * this case, we assume that this means that * the address was already bound. This is not - * an error for servers started by inetd (1M). + * an error for servers started by inetd(8). */ if ((rc == -1) && (errno != EINVAL)) { return (RDR_NET_ERR); diff --git a/usr/src/cmd/devfsadm/misc_link.c b/usr/src/cmd/devfsadm/misc_link.c index 5f241df296..7397fcdb40 100644 --- a/usr/src/cmd/devfsadm/misc_link.c +++ b/usr/src/cmd/devfsadm/misc_link.c @@ -204,6 +204,9 @@ static devfsadm_create_t misc_cbt[] = { { "pseudo", "ddi_pseudo", "tpm", TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name }, + { "pseudo", "ddi_pseudo", "overlay", + TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name + } }; DEVFSADM_CREATE_INIT_V0(misc_cbt); @@ -224,8 +227,8 @@ static devfsadm_remove_t misc_remove_cbt[] = { { "pseudo", "^daplt$", RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all }, - { "pseudo", "^zcons/" ZONENAME_REGEXP "/(" ZCONS_MASTER_NAME "|" - ZCONS_SLAVE_NAME ")$", + { "pseudo", "^zcons/" ZONENAME_REGEXP "/(" ZCONS_MANAGER_NAME "|" + ZCONS_SUBSIDIARY_NAME ")$", RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all }, { "pseudo", "^" CPUID_SELF_NAME "$", RM_ALWAYS | RM_PRE | RM_HOT, @@ -474,7 +477,7 @@ fc_port(di_minor_t minor, di_node_t node) /* * Handles: * minor node type "ddi_printer". - * rules of the form: type=ddi_printer;name=bpp \M0 + * rules of the form: type=ddi_printer;name=bpp \M0 */ static int printer_create(di_minor_t minor, di_node_t node) @@ -676,7 +679,7 @@ zcons_create(di_minor_t minor, di_node_t node) } /* - * /dev/cpu/self/cpuid -> /devices/pseudo/cpuid@0:self + * /dev/cpu/self/cpuid -> /devices/pseudo/cpuid@0:self */ static int cpuid(di_minor_t minor, di_node_t node) diff --git a/usr/src/cmd/dladm/Makefile b/usr/src/cmd/dladm/Makefile index 6171822797..bba8a8cede 100644 --- a/usr/src/cmd/dladm/Makefile +++ b/usr/src/cmd/dladm/Makefile @@ -20,6 +20,7 @@ # # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2015 Joyent, Inc. # # Copyright (c) 2018, Joyent, Inc. @@ -38,7 +39,7 @@ XGETFLAGS += -a -x $(PROG).xcl LDLIBS += -L$(ROOT)/lib -lsocket LDLIBS += -ldladm -ldlpi -lkstat -lsecdb -lbsm -lofmt -linetutil -ldevinfo -LDLIBS += $(ZLAZYLOAD) -lrstp $(ZNOLAZYLOAD) +LDLIBS += $(ZLAZYLOAD) -lrstp $(ZNOLAZYLOAD) -lnsl -lumem -lcustr CERRWARN += -_gcc=-Wno-switch CERRWARN += -_gcc=-Wno-unused-label diff --git a/usr/src/cmd/dladm/dladm.c b/usr/src/cmd/dladm/dladm.c index 21ff6ce195..020d0d7266 100644 --- a/usr/src/cmd/dladm/dladm.c +++ b/usr/src/cmd/dladm/dladm.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2016 Nexenta Systems, Inc. + * Copyright (c) 2015 Joyent, Inc. All rights reserved. * Copyright 2020 Peter Tribble. * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. */ @@ -63,6 +64,7 @@ #include <libdliptun.h> #include <libdlsim.h> #include <libdlbridge.h> +#include <libdloverlay.h> #include <libinetutil.h> #include <libvrrpadm.h> #include <bsm/adt.h> @@ -78,6 +80,7 @@ #include <stddef.h> #include <stp_in.h> #include <ofmt.h> +#include <libcustr.h> #define MAXPORT 256 #define MAXVNIC 256 @@ -196,6 +199,7 @@ static ofmt_cb_t print_lacp_cb, print_phys_one_mac_cb; static ofmt_cb_t print_xaggr_cb, print_aggr_stats_cb; static ofmt_cb_t print_phys_one_hwgrp_cb, print_wlan_attr_cb; static ofmt_cb_t print_wifi_status_cb, print_link_attr_cb; +static ofmt_cb_t print_overlay_cb, print_overlay_fma_cb, print_overlay_targ_cb; typedef void cmdfunc_t(int, char **, const char *); @@ -223,6 +227,8 @@ static cmdfunc_t do_create_bridge, do_modify_bridge, do_delete_bridge; static cmdfunc_t do_add_bridge, do_remove_bridge, do_show_bridge; static cmdfunc_t do_create_iptun, do_modify_iptun, do_delete_iptun; static cmdfunc_t do_show_iptun, do_up_iptun, do_down_iptun; +static cmdfunc_t do_create_overlay, do_delete_overlay, do_modify_overlay; +static cmdfunc_t do_show_overlay; static void do_up_vnic_common(int, char **, const char *, boolean_t); @@ -258,8 +264,11 @@ static void die(const char *, ...); static void die_optdup(int); static void die_opterr(int, int, const char *); static void die_dlerr(dladm_status_t, const char *, ...); +static void die_dlerrlist(dladm_status_t, dladm_errlist_t *, + const char *, ...); static void warn(const char *, ...); static void warn_dlerr(dladm_status_t, const char *, ...); +static void warn_dlerrlist(dladm_errlist_t *); typedef struct cmd { char *c_name; @@ -406,6 +415,17 @@ static cmd_t cmds[] = { " <bridge>\n" " show-bridge -t [-p] [-o <field>,...] [-s [-i <interval>]]" " <bridge>\n" }, + { "create-overlay", do_create_overlay, + " create-overlay [-t] -e <encap> -s <search> -v <vnetid>\n" + "\t\t [ -p <prop>=<value>[,...]] <overlay>" }, + { "delete-overlay", do_delete_overlay, + " delete-overlay <overlay>" }, + { "modify-overlay", do_modify_overlay, + " modify-overlay -d mac | -f | -s mac=ip:port " + "<overlay>" }, + { "show-overlay", do_show_overlay, + " show-overlay [-f | -t] [[-p] -o <field>,...] " + "[<overlay>]\n" }, { "show-usage", do_show_usage, " show-usage [-a] [-d | -F <format>] " "[-s <DD/MM/YYYY,HH:MM:SS>]\n" @@ -1430,6 +1450,82 @@ static ofmt_field_t bridge_trill_fields[] = { offsetof(bridge_trill_fields_buf_t, bridget_nexthop), print_default_cb }, { NULL, 0, 0, NULL}}; +static const struct option overlay_create_lopts[] = { + { "encap", required_argument, NULL, 'e' }, + { "prop", required_argument, NULL, 'p' }, + { "search", required_argument, NULL, 's' }, + { "temporary", no_argument, NULL, 't' }, + { "vnetid", required_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 } +}; + +static const struct option overlay_modify_lopts[] = { + { "delete-entry", required_argument, NULL, 'd' }, + { "flush-table", no_argument, NULL, 'f' }, + { "set-entry", required_argument, NULL, 's' }, + { NULL, 0, NULL, 0 } +}; + +static const struct option overlay_show_lopts[] = { + { "fma", no_argument, NULL, 'f' }, + { "target", no_argument, NULL, 't' }, + { "parsable", no_argument, NULL, 'p' }, + { "parseable", no_argument, NULL, 'p' }, + { "output", required_argument, NULL, 'o' }, + { NULL, 0, NULL, 0 } +}; + +/* + * Structures for dladm show-overlay + */ +typedef enum { + OVERLAY_LINK, + OVERLAY_PROPERTY, + OVERLAY_PERM, + OVERLAY_REQ, + OVERLAY_VALUE, + OVERLAY_DEFAULT, + OVERLAY_POSSIBLE +} overlay_field_index_t; + +static const ofmt_field_t overlay_fields[] = { +/* name, field width, index */ +{ "LINK", 19, OVERLAY_LINK, print_overlay_cb }, +{ "PROPERTY", 19, OVERLAY_PROPERTY, print_overlay_cb }, +{ "PERM", 5, OVERLAY_PERM, print_overlay_cb }, +{ "REQ", 4, OVERLAY_REQ, print_overlay_cb }, +{ "VALUE", 11, OVERLAY_VALUE, print_overlay_cb }, +{ "DEFAULT", 10, OVERLAY_DEFAULT, print_overlay_cb }, +{ "POSSIBLE", 10, OVERLAY_POSSIBLE, print_overlay_cb }, +{ NULL, 0, 0, NULL } +}; + +typedef enum { + OVERLAY_FMA_LINK, + OVERLAY_FMA_STATUS, + OVERLAY_FMA_DETAILS +} overlay_fma_field_index_t; + +static const ofmt_field_t overlay_fma_fields[] = { +{ "LINK", 20, OVERLAY_FMA_LINK, print_overlay_fma_cb }, +{ "STATUS", 8, OVERLAY_FMA_STATUS, print_overlay_fma_cb }, +{ "DETAILS", 52, OVERLAY_FMA_DETAILS, print_overlay_fma_cb }, +{ NULL, 0, 0, NULL } +}; + +typedef enum { + OVERLAY_TARG_LINK, + OVERLAY_TARG_TARGET, + OVERLAY_TARG_DEST +} overlay_targ_field_index_t; + +static const ofmt_field_t overlay_targ_fields[] = { +{ "LINK", 20, OVERLAY_TARG_LINK, print_overlay_targ_cb }, +{ "TARGET", 18, OVERLAY_TARG_TARGET, print_overlay_targ_cb }, +{ "DESTINATION", 42, OVERLAY_TARG_DEST, print_overlay_targ_cb }, +{ NULL, 0, 0, NULL } +}; + static char *progname; static sig_atomic_t signalled; @@ -1439,6 +1535,12 @@ static sig_atomic_t signalled; */ static dladm_handle_t handle = NULL; +/* + * Global error list that all routines can use. It's initialized by the main + * code. + */ +static dladm_errlist_t errlist; + #define DLADM_ETHERSTUB_NAME "etherstub" #define DLADM_IS_ETHERSTUB(id) (id == DATALINK_INVALID_LINKID) @@ -1506,6 +1608,8 @@ main(int argc, char *argv[]) "could not open /dev/dld"); } + dladm_errlist_init(&errlist); + cmdp->c_fn(argc - 1, &argv[1], cmdp->c_usage); dladm_close(handle); @@ -4801,7 +4905,7 @@ do_create_vnic(int argc, char *argv[], const char *use) status = dladm_vnic_create(handle, name, dev_linkid, mac_addr_type, mac_addr, maclen, &mac_slot, mac_prefix_len, vid, vrid, af, - &linkid, proplist, flags); + &linkid, proplist, &errlist, flags); switch (status) { case DLADM_STATUS_OK: break; @@ -4812,7 +4916,8 @@ do_create_vnic(int argc, char *argv[], const char *use) break; default: - die_dlerr(status, "vnic creation over %s failed", devname); + die_dlerrlist(status, &errlist, "vnic creation over %s failed", + devname); } dladm_free_props(proplist); @@ -5311,7 +5416,7 @@ do_create_etherstub(int argc, char *argv[], const char *use) status = dladm_vnic_create(handle, name, DATALINK_INVALID_LINKID, VNIC_MAC_ADDR_TYPE_AUTO, mac_addr, ETHERADDRL, NULL, 0, 0, - VRRP_VRID_NONE, AF_UNSPEC, NULL, NULL, flags); + VRRP_VRID_NONE, AF_UNSPEC, NULL, NULL, &errlist, flags); if (status != DLADM_STATUS_OK) die_dlerr(status, "etherstub creation failed"); } @@ -8953,6 +9058,21 @@ warn_dlerr(dladm_status_t err, const char *format, ...) (void) fprintf(stderr, ": %s\n", dladm_status2str(err, errmsg)); } +static void +warn_dlerrlist(dladm_errlist_t *errlist) +{ + if (errlist != NULL && errlist->el_count > 0) { + int i; + for (i = 0; i < errlist->el_count; i++) { + (void) fprintf(stderr, gettext("%s: warning: "), + progname); + + (void) fprintf(stderr, "%s\n", + gettext(errlist->el_errs[i])); + } + } +} + /* * Also closes the dladm handle if it is not NULL. */ @@ -8978,6 +9098,34 @@ die_dlerr(dladm_status_t err, const char *format, ...) exit(EXIT_FAILURE); } +/* + * Like die_dlerr, but uses the errlist for additional information. + */ +/* PRINTFLIKE3 */ +static void +die_dlerrlist(dladm_status_t err, dladm_errlist_t *errlist, + const char *format, ...) +{ + va_list alist; + char errmsg[DLADM_STRSIZE]; + + warn_dlerrlist(errlist); + format = gettext(format); + (void) fprintf(stderr, "%s: ", progname); + + va_start(alist, format); + (void) vfprintf(stderr, format, alist); + va_end(alist); + (void) fprintf(stderr, ": %s\n", dladm_status2str(err, errmsg)); + + /* close dladm handle if it was opened */ + if (handle != NULL) + dladm_close(handle); + + exit(EXIT_FAILURE); + +} + /* PRINTFLIKE1 */ static void die(const char *format, ...) @@ -9685,3 +9833,680 @@ do_up_part(int argc, char *argv[], const char *use) (void) dladm_part_up(handle, partid, 0); } + +static void +do_create_overlay(int argc, char *argv[], const char *use) +{ + int opt; + char *encap = NULL, *endp, *search = NULL; + char name[MAXLINKNAMELEN]; + dladm_status_t status; + uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; + uint64_t vid = 0; + boolean_t havevid = B_FALSE; + char propstr[DLADM_STRSIZE]; + dladm_arg_list_t *proplist = NULL; + + bzero(propstr, sizeof (propstr)); + while ((opt = getopt_long(argc, argv, ":te:v:p:s:", + overlay_create_lopts, NULL)) != -1) { + switch (opt) { + case 'e': + encap = optarg; + break; + case 's': + search = optarg; + break; + case 't': + flags &= ~DLADM_OPT_PERSIST; + break; + case 'p': + (void) strlcat(propstr, optarg, DLADM_STRSIZE); + if (strlcat(propstr, ",", DLADM_STRSIZE) >= + DLADM_STRSIZE) + die("property list too long '%s'", propstr); + break; + case 'v': + vid = strtoul(optarg, &endp, 10); + if (*endp != '\0' || (vid == 0 && errno == EINVAL)) + die("couldn't parse virtual networkd id: %s", + optarg); + if (vid == ULONG_MAX && errno == ERANGE) + die("virtual networkd id too large: %s", + optarg); + havevid = B_TRUE; + break; + default: + die_opterr(optopt, opt, use); + } + } + + /* + * Overlays do not currently support persistence. + * This will be addressed by https://www.illumos.org/issues/14434 + */ + if ((flags & DLADM_OPT_PERSIST) != 0) + die("overlays do not (yet) support persistence, use -t"); + + if (havevid == B_FALSE) + die("missing required virtual network id"); + + if (encap == NULL) + die("missing required encapsulation plugin"); + + if (search == NULL) + die("missing required search plugin"); + + if (optind != (argc - 1)) + die("missing device name"); + + if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= MAXLINKNAMELEN) + die("link name too long '%s'", argv[optind]); + + if (!dladm_valid_linkname(name)) + die("invalid link name '%s'", argv[optind]); + + if (strlen(encap) + 1 > MAXLINKNAMELEN) + die("encapsulation plugin name too long '%s'", encap); + + if (strlen(search) + 1 > MAXLINKNAMELEN) + die("search plugin name too long '%s'", encap); + + if (dladm_parse_link_props(propstr, &proplist, B_FALSE) + != DLADM_STATUS_OK) + die("invalid overlay property"); + + status = dladm_overlay_create(handle, name, encap, search, vid, + proplist, &errlist, flags); + dladm_free_props(proplist); + if (status != DLADM_STATUS_OK) { + die_dlerrlist(status, &errlist, "overlay creation failed"); + } +} + +/* ARGSUSED */ +static void +do_delete_overlay(int argc, char *argv[], const char *use) +{ + datalink_id_t linkid = DATALINK_ALL_LINKID; + dladm_status_t status; + + if (argc != 2) { + usage(); + } + + status = dladm_name2info(handle, argv[1], &linkid, NULL, NULL, NULL); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to delete %s", argv[1]); + + status = dladm_overlay_delete(handle, linkid); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to delete %s", argv[1]); +} + +typedef struct showoverlay_state { + ofmt_handle_t sho_ofmt; + const char *sho_linkname; + dladm_overlay_propinfo_handle_t sho_info; + uint8_t sho_value[DLADM_OVERLAY_PROP_SIZEMAX]; + uint32_t sho_size; +} showoverlay_state_t; + +typedef struct showoverlay_fma_state { + ofmt_handle_t shof_ofmt; + const char *shof_linkname; + dladm_overlay_status_t *shof_status; +} showoverlay_fma_state_t; + +typedef struct showoverlay_targ_state { + ofmt_handle_t shot_ofmt; + const char *shot_linkname; + const struct ether_addr *shot_key; + const dladm_overlay_point_t *shot_point; +} showoverlay_targ_state_t; + +static void +print_overlay_value(char *outbuf, uint_t bufsize, uint_t type, const void *pbuf, + const size_t psize) +{ + const struct in6_addr *ipv6; + struct in_addr ip; + + switch (type) { + case OVERLAY_PROP_T_INT: + if (psize != 1 && psize != 2 && psize != 4 && psize != 8) { + (void) snprintf(outbuf, bufsize, "?"); + break; + } + if (psize == 1) + (void) snprintf(outbuf, bufsize, "%d", *(int8_t *)pbuf); + if (psize == 2) + (void) snprintf(outbuf, bufsize, "%d", + *(int16_t *)pbuf); + if (psize == 4) + (void) snprintf(outbuf, bufsize, "%d", + *(int32_t *)pbuf); + if (psize == 8) + (void) snprintf(outbuf, bufsize, "%d", + *(int64_t *)pbuf); + break; + case OVERLAY_PROP_T_UINT: + if (psize != 1 && psize != 2 && psize != 4 && psize != 8) { + (void) snprintf(outbuf, bufsize, "?"); + break; + } + if (psize == 1) + (void) snprintf(outbuf, bufsize, "%d", + *(uint8_t *)pbuf); + if (psize == 2) + (void) snprintf(outbuf, bufsize, "%d", + *(uint16_t *)pbuf); + if (psize == 4) + (void) snprintf(outbuf, bufsize, "%d", + *(uint32_t *)pbuf); + if (psize == 8) + (void) snprintf(outbuf, bufsize, "%d", + *(uint64_t *)pbuf); + break; + case OVERLAY_PROP_T_IP: + if (psize != sizeof (struct in6_addr)) { + warn("malformed overlay IP property: %d bytes\n", + psize); + (void) snprintf(outbuf, bufsize, "--"); + break; + } + + ipv6 = pbuf; + if (IN6_IS_ADDR_V4MAPPED(ipv6)) { + IN6_V4MAPPED_TO_INADDR(ipv6, &ip); + if (inet_ntop(AF_INET, &ip, outbuf, bufsize) == NULL) { + warn("malformed overlay IP property\n"); + (void) snprintf(outbuf, bufsize, "--"); + break; + } + } else { + if (inet_ntop(AF_INET6, ipv6, outbuf, bufsize) == + NULL) { + warn("malformed overlay IP property\n"); + (void) snprintf(outbuf, bufsize, "--"); + break; + } + } + + break; + case OVERLAY_PROP_T_STRING: + (void) snprintf(outbuf, bufsize, "%s", pbuf); + break; + default: + abort(); + } + + return; + +} + +static boolean_t +print_overlay_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) +{ + dladm_status_t status; + showoverlay_state_t *sp = ofarg->ofmt_cbarg; + dladm_overlay_propinfo_handle_t infop = sp->sho_info; + const char *pname; + uint_t type, prot; + const void *def; + uint32_t defsize; + const mac_propval_range_t *rangep; + + if ((status = dladm_overlay_prop_info(infop, &pname, &type, &prot, &def, + &defsize, &rangep)) != DLADM_STATUS_OK) { + warn_dlerr(status, "failed to get get property info"); + return (B_TRUE); + } + + switch (ofarg->ofmt_id) { + case OVERLAY_LINK: + (void) snprintf(buf, bufsize, "%s", sp->sho_linkname); + break; + case OVERLAY_PROPERTY: + (void) snprintf(buf, bufsize, "%s", pname); + break; + case OVERLAY_PERM: + if ((prot & OVERLAY_PROP_PERM_RW) == OVERLAY_PROP_PERM_RW) { + (void) snprintf(buf, bufsize, "%s", "rw"); + } else if ((prot & OVERLAY_PROP_PERM_RW) == + OVERLAY_PROP_PERM_READ) { + (void) snprintf(buf, bufsize, "%s", "r-"); + } else { + (void) snprintf(buf, bufsize, "%s", "--"); + } + break; + case OVERLAY_REQ: + (void) snprintf(buf, bufsize, "%s", + prot & OVERLAY_PROP_PERM_REQ ? "y" : "-"); + break; + case OVERLAY_VALUE: + if (sp->sho_size == 0) { + (void) snprintf(buf, bufsize, "%s", "--"); + } else { + print_overlay_value(buf, bufsize, type, sp->sho_value, + sp->sho_size); + } + break; + case OVERLAY_DEFAULT: + if (defsize == 0) { + (void) snprintf(buf, bufsize, "%s", "--"); + } else { + print_overlay_value(buf, bufsize, type, def, defsize); + } + break; + case OVERLAY_POSSIBLE: { + int i; + char **vals, *ptr, *lim; + if (rangep->mpr_count == 0) { + (void) snprintf(buf, bufsize, "%s", "--"); + break; + } + + vals = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * + rangep->mpr_count); + if (vals == NULL) + die("insufficient memory"); + for (i = 0; i < rangep->mpr_count; i++) { + vals[i] = (char *)vals + sizeof (char *) * + rangep->mpr_count + i * DLADM_MAX_PROP_VALCNT; + } + + if (dladm_range2strs(rangep, vals) != 0) { + free(vals); + (void) snprintf(buf, bufsize, "%s", "?"); + break; + } + + ptr = buf; + lim = buf + bufsize; + for (i = 0; i < rangep->mpr_count; i++) { + ptr += snprintf(ptr, lim - ptr, "%s,", vals[i]); + if (ptr >= lim) + break; + } + if (rangep->mpr_count > 0) + buf[strlen(buf) - 1] = '\0'; + free(vals); + break; + } + default: + abort(); + } + return (B_TRUE); +} + +static int +dladm_overlay_show_one(dladm_handle_t handle, datalink_id_t linkid, + dladm_overlay_propinfo_handle_t phdl, void *arg) +{ + showoverlay_state_t *sp = arg; + sp->sho_info = phdl; + + sp->sho_size = sizeof (sp->sho_value); + if (dladm_overlay_get_prop(handle, linkid, phdl, &sp->sho_value, + &sp->sho_size) != DLADM_STATUS_OK) + return (DLADM_WALK_CONTINUE); + + ofmt_print(sp->sho_ofmt, sp); + return (DLADM_WALK_CONTINUE); +} + +static int +show_one_overlay(dladm_handle_t hdl, datalink_id_t linkid, void *arg) +{ + char buf[MAXLINKNAMELEN]; + showoverlay_state_t state; + datalink_class_t class; + + if (dladm_datalink_id2info(hdl, linkid, NULL, &class, NULL, buf, + MAXLINKNAMELEN) != DLADM_STATUS_OK || + class != DATALINK_CLASS_OVERLAY) + return (DLADM_WALK_CONTINUE); + + state.sho_linkname = buf; + state.sho_ofmt = arg; + + dladm_errlist_reset(&errlist); + (void) dladm_overlay_walk_prop(handle, linkid, dladm_overlay_show_one, + &state, &errlist); + warn_dlerrlist(&errlist); + + return (DLADM_WALK_CONTINUE); +} + +static boolean_t +print_overlay_targ_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) +{ + char keybuf[ETHERADDRSTRL]; + const showoverlay_targ_state_t *shot = ofarg->ofmt_cbarg; + const dladm_overlay_point_t *point = shot->shot_point; + char macbuf[ETHERADDRSTRL]; + char ipbuf[INET6_ADDRSTRLEN]; + custr_t *cus; + + switch (ofarg->ofmt_id) { + case OVERLAY_TARG_LINK: + (void) snprintf(buf, bufsize, shot->shot_linkname); + break; + case OVERLAY_TARG_TARGET: + if ((point->dop_flags & DLADM_OVERLAY_F_DEFAULT) != 0) { + (void) snprintf(buf, bufsize, "*:*:*:*:*:*"); + } else { + if (ether_ntoa_r(shot->shot_key, keybuf) == NULL) { + warn("encountered malformed mac address key\n"); + return (B_FALSE); + } + (void) snprintf(buf, bufsize, "%s", keybuf); + } + break; + case OVERLAY_TARG_DEST: + if (custr_alloc_buf(&cus, buf, bufsize) != 0) { + die("ran out of memory for printing the overlay " + "target destination"); + } + + if (point->dop_dest & OVERLAY_PLUGIN_D_ETHERNET) { + if (ether_ntoa_r(&point->dop_mac, macbuf) == NULL) { + warn("encountered malformed mac address target " + "for key %s\n", keybuf); + return (B_FALSE); + } + (void) custr_append(cus, macbuf); + } + + if (point->dop_dest & OVERLAY_PLUGIN_D_IP) { + if (IN6_IS_ADDR_V4MAPPED(&point->dop_ip)) { + struct in_addr v4; + IN6_V4MAPPED_TO_INADDR(&point->dop_ip, &v4); + if (inet_ntop(AF_INET, &v4, ipbuf, + sizeof (ipbuf)) == NULL) + abort(); + } else if (inet_ntop(AF_INET6, &point->dop_ip, ipbuf, + sizeof (ipbuf)) == NULL) { + /* + * The only failures we should get are + * EAFNOSUPPORT and ENOSPC because of buffer + * exhaustion. In either of these cases, that + * means something has gone horribly wrong. + */ + abort(); + } + if (point->dop_dest & OVERLAY_PLUGIN_D_ETHERNET) + (void) custr_appendc(cus, ','); + (void) custr_append(cus, ipbuf); + } + + if (point->dop_dest & OVERLAY_PLUGIN_D_PORT) { + if (point->dop_dest & OVERLAY_PLUGIN_D_IP) + (void) custr_appendc(cus, ':'); + else if (point->dop_dest & OVERLAY_PLUGIN_D_ETHERNET) + (void) custr_appendc(cus, ','); + (void) custr_append_printf(cus, "%u", point->dop_port); + } + + custr_free(cus); + + break; + } + return (B_TRUE); +} + +/* ARGSUSED */ +static int +show_one_overlay_table_entry(dladm_handle_t handle, datalink_id_t linkid, + const struct ether_addr *key, const dladm_overlay_point_t *point, void *arg) +{ + showoverlay_targ_state_t *shot = arg; + + shot->shot_key = key; + shot->shot_point = point; + ofmt_print(shot->shot_ofmt, shot); + + return (DLADM_WALK_CONTINUE); +} + +/* ARGSUSED */ +static int +show_one_overlay_table(dladm_handle_t handle, datalink_id_t linkid, void *arg) +{ + char linkbuf[MAXLINKNAMELEN]; + showoverlay_targ_state_t shot; + datalink_class_t class; + + if (dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, linkbuf, + MAXLINKNAMELEN) != DLADM_STATUS_OK || + class != DATALINK_CLASS_OVERLAY) + return (DLADM_WALK_CONTINUE); + + shot.shot_ofmt = arg; + shot.shot_linkname = linkbuf; + + (void) dladm_overlay_walk_cache(handle, linkid, + show_one_overlay_table_entry, &shot); + + return (DLADM_WALK_CONTINUE); +} + +static boolean_t +print_overlay_fma_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) +{ + showoverlay_fma_state_t *shof = ofarg->ofmt_cbarg; + dladm_overlay_status_t *st = shof->shof_status; + + switch (ofarg->ofmt_id) { + case OVERLAY_FMA_LINK: + (void) snprintf(buf, bufsize, "%s", shof->shof_linkname); + break; + case OVERLAY_FMA_STATUS: + (void) snprintf(buf, bufsize, st->dos_degraded == B_TRUE ? + "DEGRADED": "ONLINE"); + break; + case OVERLAY_FMA_DETAILS: + (void) snprintf(buf, bufsize, "%s", st->dos_degraded == B_TRUE ? + st->dos_fmamsg : "-"); + break; + default: + abort(); + } + return (B_TRUE); +} + +/* ARGSUSED */ +static void +show_one_overlay_fma_cb(dladm_handle_t handle, datalink_id_t linkid, + dladm_overlay_status_t *stat, void *arg) +{ + showoverlay_fma_state_t *shof = arg; + shof->shof_status = stat; + ofmt_print(shof->shof_ofmt, shof); +} + + +static int +show_one_overlay_fma(dladm_handle_t handle, datalink_id_t linkid, void *arg) +{ + dladm_status_t status; + char linkbuf[MAXLINKNAMELEN]; + datalink_class_t class; + showoverlay_fma_state_t shof; + + if (dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, linkbuf, + MAXLINKNAMELEN) != DLADM_STATUS_OK || + class != DATALINK_CLASS_OVERLAY) { + die("datalink %s is not an overlay device\n", linkbuf); + } + + shof.shof_ofmt = arg; + shof.shof_linkname = linkbuf; + + status = dladm_overlay_status(handle, linkid, + show_one_overlay_fma_cb, &shof); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to obtain device status for %s", + linkbuf); + + return (DLADM_WALK_CONTINUE); +} + +static void +do_show_overlay(int argc, char *argv[], const char *use) +{ + int i, opt; + datalink_id_t linkid = DATALINK_ALL_LINKID; + dladm_status_t status; + int (*funcp)(dladm_handle_t, datalink_id_t, void *); + char *fields_str = NULL; + const ofmt_field_t *fieldsp; + ofmt_status_t oferr; + boolean_t parse; + ofmt_handle_t ofmt; + uint_t ofmtflags; + int err; + + + funcp = show_one_overlay; + fieldsp = overlay_fields; + parse = B_FALSE; + ofmtflags = OFMT_WRAP; + while ((opt = getopt_long(argc, argv, ":o:pft", overlay_show_lopts, + NULL)) != -1) { + switch (opt) { + case 'f': + funcp = show_one_overlay_fma; + fieldsp = overlay_fma_fields; + break; + case 'o': + fields_str = optarg; + break; + case 'p': + parse = B_TRUE; + ofmtflags = OFMT_PARSABLE; + break; + case 't': + funcp = show_one_overlay_table; + fieldsp = overlay_targ_fields; + break; + default: + die_opterr(optopt, opt, use); + } + } + + if (fields_str != NULL && strcasecmp(fields_str, "all") == 0) + fields_str = NULL; + + oferr = ofmt_open(fields_str, fieldsp, ofmtflags, 0, &ofmt); + ofmt_check(oferr, parse, ofmt, die, warn); + + err = 0; + if (argc > optind) { + for (i = optind; i < argc; i++) { + status = dladm_name2info(handle, argv[i], &linkid, + NULL, NULL, NULL); + if (status != DLADM_STATUS_OK) { + warn_dlerr(status, "failed to find %s", + argv[i]); + err = 1; + continue; + } + (void) funcp(handle, linkid, ofmt); + } + } else { + (void) dladm_walk_datalink_id(funcp, handle, ofmt, + DATALINK_CLASS_OVERLAY, DATALINK_ANY_MEDIATYPE, + DLADM_OPT_ACTIVE); + } + ofmt_close(ofmt); + + exit(err); +} + +static void +do_modify_overlay(int argc, char *argv[], const char *use) +{ + int opt, ocnt = 0; + boolean_t flush, set, delete; + struct ether_addr e; + char *dest = NULL; + datalink_id_t linkid = DATALINK_ALL_LINKID; + dladm_status_t status; + + flush = set = delete = B_FALSE; + while ((opt = getopt_long(argc, argv, ":fd:s:", overlay_modify_lopts, + NULL)) != -1) { + switch (opt) { + case 'd': + if (delete == B_TRUE) + die_optdup('d'); + delete = B_TRUE; + ocnt++; + if (ether_aton_r(optarg, &e) == NULL) + die("invalid mac address: %s\n", optarg); + break; + case 'f': + if (flush == B_TRUE) + die_optdup('f'); + flush = B_TRUE; + ocnt++; + break; + case 's': + if (set == B_TRUE) + die_optdup('s'); + set = B_TRUE; + ocnt++; + dest = strchr(optarg, '='); + *dest = '\0'; + dest++; + if (dest == NULL) + die("malformed value, expected mac=dest, " + "got: %s\n", optarg); + if (ether_aton_r(optarg, &e) == NULL) + die("invalid mac address: %s\n", optarg); + break; + default: + die_opterr(optopt, opt, use); + } + } + + if (ocnt == 0) + die("need to specify one of -d, -f, or -s"); + if (ocnt > 1) + die("only one of -d, -f, or -s may be used"); + + if (argv[optind] == NULL) + die("missing required overlay device\n"); + if (argc > optind + 1) + die("only one overlay device may be specified\n"); + + status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, + NULL); + if (status != DLADM_STATUS_OK) { + die_dlerr(status, "failed to find overlay %s", argv[optind]); + } + + if (flush == B_TRUE) { + status = dladm_overlay_cache_flush(handle, linkid); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to flush target cache for " + "overlay %s", argv[optind]); + } + + if (delete == B_TRUE) { + status = dladm_overlay_cache_delete(handle, linkid, &e); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to flush target %s from " + "overlay target cache %s", optarg, argv[optind]); + } + + if (set == B_TRUE) { + status = dladm_overlay_cache_set(handle, linkid, &e, dest); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to set target %s for overlay " + "target cache %s", optarg, argv[optind]); + } + +} diff --git a/usr/src/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithChill.d b/usr/src/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithChill.d index ebb3b01601..7d7d07671a 100644 --- a/usr/src/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithChill.d +++ b/usr/src/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithChill.d @@ -25,14 +25,12 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * ASSERTION: * Destructive actions may never be speculative. * * SECTION: Speculative Tracing/Using a Speculation - * SECTION: dtrace (1M) Utility/ -w option + * SECTION: dtrace(8) Utility/ -w option * */ #pragma D option quiet diff --git a/usr/src/cmd/enhance/enhance.c b/usr/src/cmd/enhance/enhance.c index 25650e378e..3fb004fbd0 100644 --- a/usr/src/cmd/enhance/enhance.c +++ b/usr/src/cmd/enhance/enhance.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -69,24 +67,24 @@ int unlockpt(int fd); #define PTY_CNTRL "pty" /* - * Pseudo-terminal slave device file names start with the following + * Pseudo-terminal subsidiary device file names start with the following * prefix. */ -#define PTY_SLAVE "tty" +#define PTY_SUBSID "tty" /* - * Specify the maximum suffix length for the control and slave device + * Specify the maximum suffix length for the control and subsidiary device * names. */ #define PTY_MAX_SUFFIX 10 /* - * Set the maximum length of the master and slave terminal device filenames, - * including space for a terminating '\0'. + * Set the maximum length of the manager and subsidiary terminal device + * filenames, including space for a terminating '\0'. */ #define PTY_MAX_NAME (sizeof(PTY_DEV_DIR)-1 + \ - (sizeof(PTY_SLAVE) > sizeof(PTY_CNTRL) ? \ - sizeof(PTY_SLAVE) : sizeof(PTY_CNTRL))-1 \ + (sizeof(PTY_SUBSID) > sizeof(PTY_CNTRL) ? \ + sizeof(PTY_SUBSID) : sizeof(PTY_CNTRL))-1 \ + PTY_MAX_SUFFIX + 1) /* * Set the maximum length of an input line. @@ -110,15 +108,15 @@ int unlockpt(int fd); */ #define PTY_READ_TIMEOUT 100000 /* micro-seconds */ -static int pty_open_master(const char *prog, int *cntrl, char *slave_name); -static int pty_open_slave(const char *prog, char *slave_name); -static int pty_child(const char *prog, int slave, char *argv[]); +static int pty_open_manager(const char *prog, int *cntrl, char *subsid_name); +static int pty_open_subsid(const char *prog, char *subsid_name); +static int pty_child(const char *prog, int subsid, char *argv[]); static int pty_parent(const char *prog, int cntrl); static int pty_stop_parent(int waserr, int cntrl, GetLine *gl, char *rbuff); static GL_FD_EVENT_FN(pty_read_from_program); static int pty_write_to_fd(int fd, const char *string, int n); static void pty_child_exited(int sig); -static int pty_master_readable(int fd, long usec); +static int pty_manager_readable(int fd, long usec); /*....................................................................... * Run a program with enhanced terminal editing facilities. @@ -129,11 +127,11 @@ static int pty_master_readable(int fd, long usec); int main(int argc, char *argv[]) { int cntrl = -1; /* The fd of the pseudo-terminal controller device */ - int slave = -1; /* The fd of the pseudo-terminal slave device */ + int subsid = -1; /* The fd of the pseudo-terminal subsidiary device */ pid_t pid; /* The return value of fork() */ int status; /* The return statuses of the parent and child functions */ - char slave_name[PTY_MAX_NAME]; /* The filename of the slave end of the */ - /* pseudo-terminal. */ + char subsid_name[PTY_MAX_NAME]; /* The filename of the subsidiary end of */ + /* the pseudo-terminal. */ char *prog; /* The name of the program (ie. argv[0]) */ /* * Check the arguments. @@ -165,11 +163,11 @@ int main(int argc, char *argv[]) }; }; /* - * Open the master side of a pseudo-terminal pair, and return + * Open the manager side of a pseudo-terminal pair, and return * the corresponding file descriptor and the filename of the - * slave end of the pseudo-terminal. + * subsidiary end of the pseudo-terminal. */ - if(pty_open_master(prog, &cntrl, slave_name)) + if(pty_open_manager(prog, &cntrl, subsid_name)) return 1; /* * Set up a signal handler to watch for the child process exiting. @@ -201,11 +199,11 @@ int main(int argc, char *argv[]) status = pty_parent(prog, cntrl); close(cntrl); } else { - close(cntrl); /* The child doesn't use the slave device */ + close(cntrl); /* The child doesn't use the subsidiary device */ signal(SIGCHLD, pty_child_exited); - if((slave = pty_open_slave(prog, slave_name)) >= 0) { - status = pty_child(prog, slave, argv + 1); - close(slave); + if((subsid = pty_open_subsid(prog, subsid_name)) >= 0) { + status = pty_child(prog, subsid, argv + 1); + close(subsid); } else { status = 1; }; @@ -214,24 +212,24 @@ int main(int argc, char *argv[]) } /*....................................................................... - * Open the master side of a pseudo-terminal pair, and return + * Open the manager side of a pseudo-terminal pair, and return * the corresponding file descriptor and the filename of the - * slave end of the pseudo-terminal. + * subsidiary end of the pseudo-terminal. * * Input/Output: * prog const char * The name of this program. * cntrl int * The file descriptor of the pseudo-terminal * controller device will be assigned tp *cntrl. - * slave_name char * The file-name of the pseudo-terminal slave device - * will be recorded in slave_name[], which must have + * subsid_name char * The file-name of the pseudo-terminal subsidiary device + * will be recorded in subsid_name[], which must have * at least PTY_MAX_NAME elements. * Output: * return int 0 - OK. * 1 - Error. */ -static int pty_open_master(const char *prog, int *cntrl, char *slave_name) +static int pty_open_manager(const char *prog, int *cntrl, char *subsid_name) { - char master_name[PTY_MAX_NAME]; /* The filename of the master device */ + char manager_name[PTY_MAX_NAME]; /* The filename of the manager device */ DIR *dir; /* The directory iterator */ struct dirent *file; /* A file in "/dev" */ /* @@ -240,26 +238,26 @@ static int pty_open_master(const char *prog, int *cntrl, char *slave_name) *cntrl = -1; /* * On systems with the Sys-V pseudo-terminal interface, we don't - * have to search for a free master terminal. We just open /dev/ptmx, - * and if there is a free master terminal device, we are given a file + * have to search for a free manager terminal. We just open /dev/ptmx, + * and if there is a free manager terminal device, we are given a file * descriptor connected to it. */ #if HAVE_SYSV_PTY *cntrl = open("/dev/ptmx", O_RDWR); if(*cntrl >= 0) { /* - * Get the filename of the slave side of the pseudo-terminal. + * Get the filename of the subsidiary side of the pseudo-terminal. */ char *name = ptsname(*cntrl); if(name) { if(strlen(name)+1 > PTY_MAX_NAME) { - fprintf(stderr, "%s: Slave pty filename too long.\n", prog); + fprintf(stderr, "%s: Subsidiary pty filename too long.\n", prog); return 1; }; - strlcpy(slave_name, name, PTY_MAX_NAME); + strlcpy(subsid_name, name, PTY_MAX_NAME); /* - * If unable to get the slave name, discard the controller file descriptor, - * ready to try a search instead. + * If unable to get the subsidiary name, discard the controller file + * descriptor, ready to try a search instead. */ } else { close(*cntrl); @@ -269,7 +267,7 @@ static int pty_open_master(const char *prog, int *cntrl, char *slave_name) #endif /* * On systems without /dev/ptmx, or if opening /dev/ptmx failed, - * we open one master terminal after another, until one that isn't + * we open one manager terminal after another, until one that isn't * in use by another program is found. * * Open the devices directory. @@ -287,7 +285,7 @@ static int pty_open_master(const char *prog, int *cntrl, char *slave_name) while(*cntrl < 0 && (file = readdir(dir))) { if(strncmp(file->d_name, PTY_CNTRL, sizeof(PTY_CNTRL)-1) == 0) { /* - * Get the common extension of the control and slave filenames. + * Get the common extension of the control and subsidiary filenames. */ const char *ext = file->d_name + sizeof(PTY_CNTRL)-1; if(strlen(ext) > PTY_MAX_SUFFIX) @@ -295,18 +293,18 @@ static int pty_open_master(const char *prog, int *cntrl, char *slave_name) /* * Attempt to open the control file. */ - strlcpy(master_name, PTY_DEV_DIR, sizeof(master_name)); - strlcat(master_name, PTY_CNTRL, sizeof(master_name)); - strlcat(master_name, ext, sizeof(master_name)); - *cntrl = open(master_name, O_RDWR); + strlcpy(manager_name, PTY_DEV_DIR, sizeof(manager_name)); + strlcat(manager_name, PTY_CNTRL, sizeof(manager_name)); + strlcat(manager_name, ext, sizeof(manager_name)); + *cntrl = open(manager_name, O_RDWR); if(*cntrl < 0) continue; /* - * Attempt to open the matching slave file. + * Attempt to open the matching subsidiary file. */ - strlcpy(slave_name, PTY_DEV_DIR, PTY_MAX_NAME); - strlcat(slave_name, PTY_SLAVE, PTY_MAX_NAME); - strlcat(slave_name, ext, PTY_MAX_NAME); + strlcpy(subsid_name, PTY_DEV_DIR, PTY_MAX_NAME); + strlcat(subsid_name, PTY_SUBSID, PTY_MAX_NAME); + strlcat(subsid_name, ext, PTY_MAX_NAME); }; }; closedir(dir); @@ -321,8 +319,8 @@ static int pty_open_master(const char *prog, int *cntrl, char *slave_name) return 1; }; /* - * System V systems require the program that opens the master to - * grant access to the slave side of the pseudo-terminal. + * System V systems require the program that opens the manager to + * grant access to the subsidiary side of the pseudo-terminal. */ #ifdef HAVE_SYSV_PTY if(grantpt(*cntrl) < 0 || @@ -339,18 +337,18 @@ static int pty_open_master(const char *prog, int *cntrl, char *slave_name) } /*....................................................................... - * Open the slave end of a pseudo-terminal. + * Open the subsidiary end of a pseudo-terminal. * * Input: * prog const char * The name of this program. - * slave_name char * The filename of the slave device. + * subsid_name char * The filename of the subsidiary device. * Output: * return int The file descriptor of the successfully opened - * slave device, or < 0 on error. + * subsidiary device, or < 0 on error. */ -static int pty_open_slave(const char *prog, char *slave_name) +static int pty_open_subsid(const char *prog, char *subsid_name) { - int fd; /* The file descriptor of the slave device */ + int fd; /* The file descriptor of the subsidiary device */ /* * Place the process in its own process group. In system-V based * OS's, this ensures that when the pseudo-terminal is opened, it @@ -364,16 +362,16 @@ static int pty_open_slave(const char *prog, char *slave_name) /* * Attempt to open the specified device. */ - fd = open(slave_name, O_RDWR); + fd = open(subsid_name, O_RDWR); if(fd < 0) { - fprintf(stderr, "%s: Unable to open pseudo-terminal slave device (%s).\n", + fprintf(stderr, "%s: Unable to open pty subsidiary device (%s).\n", prog, strerror(errno)); return -1; }; /* * On system-V streams based systems, we need to push the stream modules * that implement pseudo-terminal and termio interfaces. At least on - * Solaris, which pushes these automatically when a slave is opened, + * Solaris, which pushes these automatically when a subsidiary is opened, * this is redundant, so ignore errors when pushing the modules. */ #if HAVE_SYSV_PTY @@ -498,11 +496,11 @@ static int pty_stop_parent(int waserr, int cntrl, GetLine *gl, char *rbuff) /*....................................................................... * Run the user's program, with its stdin and stdout connected to the - * slave end of the psuedo-terminal. + * subsidiary end of the psuedo-terminal. * * Input: * prog const char * The name of this program. - * slave int The file descriptor of the slave end of the + * subsid int The file descriptor of the subsidiary end of the * pseudo terminal. * argv char *[] The argument vector to pass to the user's program, * where argv[0] is the name of the user's program, @@ -514,33 +512,33 @@ static int pty_stop_parent(int waserr, int cntrl, GetLine *gl, char *rbuff) * with the user's program. In this case 1 is * returned. */ -static int pty_child(const char *prog, int slave, char *argv[]) +static int pty_child(const char *prog, int subsid, char *argv[]) { struct termios attr; /* The terminal attributes */ /* * We need to stop the pseudo-terminal from echoing everything that we send it. */ - if(tcgetattr(slave, &attr)) { + if(tcgetattr(subsid, &attr)) { fprintf(stderr, "%s: Can't get pseudo-terminal attributes (%s).\n", prog, strerror(errno)); return 1; }; attr.c_lflag &= ~(ECHO); - while(tcsetattr(slave, TCSADRAIN, &attr)) { + while(tcsetattr(subsid, TCSADRAIN, &attr)) { if(errno != EINTR) { fprintf(stderr, "%s: tcsetattr error: %s\n", prog, strerror(errno)); return 1; }; }; /* - * Arrange for stdin, stdout and stderr to be connected to the slave device, - * ignoring errors that imply that either stdin or stdout is closed. + * Arrange for stdin, stdout and stderr to be connected to the subsidiary + * device, ignoring errors that imply that either stdin or stdout is closed. */ - while(dup2(slave, STDIN_FILENO) < 0 && errno==EINTR) + while(dup2(subsid, STDIN_FILENO) < 0 && errno==EINTR) ; - while(dup2(slave, STDOUT_FILENO) < 0 && errno==EINTR) + while(dup2(subsid, STDOUT_FILENO) < 0 && errno==EINTR) ; - while(dup2(slave, STDERR_FILENO) < 0 && errno==EINTR) + while(dup2(subsid, STDERR_FILENO) < 0 && errno==EINTR) ; /* * Run the user's program. @@ -648,7 +646,7 @@ static GL_FD_EVENT_FN(pty_read_from_program) */ memmove(rbuff, nextp, len - (nextp - rbuff) + 1); }; - } while(pty_master_readable(fd, PTY_READ_TIMEOUT)); + } while(pty_manager_readable(fd, PTY_READ_TIMEOUT)); /* * Make the incomplete line in the output buffer the current prompt. */ @@ -686,7 +684,7 @@ static int pty_write_to_fd(int fd, const char *string, int n) /*....................................................................... * This is the signal handler that is called when the child process * that is running the user's program exits for any reason. It closes - * the slave end of the terminal, so that gl_get_line() in the parent + * the subsidiary end of the terminal, so that gl_get_line() in the parent * process sees an end of file. */ static void pty_child_exited(int sig) @@ -707,7 +705,7 @@ static void pty_child_exited(int sig) * available). * 1 - Data is waiting to be read. */ -static int pty_master_readable(int fd, long usec) +static int pty_manager_readable(int fd, long usec) { #if HAVE_SELECT fd_set rfds; /* The set of file descriptors to check */ diff --git a/usr/src/cmd/fmthard/Makefile b/usr/src/cmd/fmthard/Makefile index 4f1205de7a..ac1cb3b292 100644 --- a/usr/src/cmd/fmthard/Makefile +++ b/usr/src/cmd/fmthard/Makefile @@ -24,14 +24,13 @@ # cmd/fmthard/Makefile # -PROG= fmthard +PROG= fmthard include ../Makefile.cmd RELUSRSBIN= ../usr/sbin ROOTSYMLINK= $(ROOTETC)/$(PROG) LDLIBS += -ladm -lefi -lint := LINTFLAGS = -u -erroff=E_BAD_FORMAT_ARG_TYPE2 .KEEP_STATE: @@ -44,7 +43,4 @@ $(ROOTSYMLINK): clean: -lint: lint_PROG - include ../Makefile.targ - diff --git a/usr/src/cmd/fmthard/fmthard.c b/usr/src/cmd/fmthard/fmthard.c index 46754e1b76..8a44358f97 100644 --- a/usr/src/cmd/fmthard/fmthard.c +++ b/usr/src/cmd/fmthard/fmthard.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ +/* All Rights Reserved */ /* @@ -121,7 +121,7 @@ static diskaddr_t lastlba = 0; /* last LBA on 64-bit VTOC */ static char *uboot = "boot"; #elif defined(i386) -/* use installgrub(8) to install boot blocks */ +/* use installboot(8) to install boot blocks */ static char *uboot = ""; #else #error No platform defined. @@ -168,7 +168,7 @@ main(int argc, char **argv) case 'b': (void) fprintf(stderr, "fmthard: -p and -b no longer supported." - " Use installgrub(8) to install boot blocks\n"); + " Use installboot(8) to install boot blocks\n"); break; #endif /* defined(i386) */ diff --git a/usr/src/cmd/make/bin/ar.cc b/usr/src/cmd/make/bin/ar.cc index 9a884714b1..50c8c2c309 100644 --- a/usr/src/cmd/make/bin/ar.cc +++ b/usr/src/cmd/make/bin/ar.cc @@ -154,11 +154,11 @@ typedef struct { /* * File table of contents */ -extern timestruc_t& read_archive(register Name target); -static Boolean open_archive(char *filename, register Ar *arp); -static void close_archive(register Ar *arp); -static Boolean read_archive_dir(register Ar *arp, Name library, char **long_names_table); -static void translate_entry(register Ar *arp, Name target, register Property member, char **long_names_table); +extern timestruc_t& read_archive(Name target); +static Boolean open_archive(char *filename, Ar *arp); +static void close_archive(Ar *arp); +static Boolean read_archive_dir(Ar *arp, Name library, char **long_names_table); +static void translate_entry(Ar *arp, Name target, Property member, char **long_names_table); static long sgetl(char *); /* @@ -177,16 +177,16 @@ static long sgetl(char *); */ int read_member_header (Ar_port *header, FILE *fd, char* filename); -int process_long_names_member (register Ar *arp, char **long_names_table, char *filename); +int process_long_names_member (Ar *arp, char **long_names_table, char *filename); timestruc_t& -read_archive(register Name target) +read_archive(Name target) { - register Property member; + Property member; wchar_t *slash; String_rec true_member_name; wchar_t buffer[STRING_BUFFER_LENGTH]; - register Name true_member = NULL; + Name true_member = NULL; Ar ar; char *long_names_table = NULL; /* Table of long member names */ @@ -267,7 +267,7 @@ read_archive(register Name target) * Global variables used: */ static Boolean -open_archive(char *filename, register Ar *arp) +open_archive(char *filename, Ar *arp) { int fd; char mag_5[AR_5_MAGIC_LENGTH]; @@ -350,7 +350,7 @@ open_archive(char *filename, register Ar *arp) * Global variables used: */ static void -close_archive(register Ar *arp) +close_archive(Ar *arp) { if (arp->fd != NULL) { (void) fclose(arp->fd); @@ -374,14 +374,14 @@ close_archive(register Ar *arp) * Global variables used: */ static Boolean -read_archive_dir(register Ar *arp, Name library, char **long_names_table) +read_archive_dir(Ar *arp, Name library, char **long_names_table) { wchar_t *name_string; wchar_t *member_string; - register long len; - register wchar_t *p; - register char *q; - register Name name; + long len; + wchar_t *p; + char *q; + Name name; Property member; long ptr; long date; @@ -562,7 +562,7 @@ read_error: * Global variables used: */ int -process_long_names_member(register Ar *arp, char **long_names_table, char *filename) +process_long_names_member(Ar *arp, char **long_names_table, char *filename) { Ar_port *ar_member_header; int table_size; @@ -614,10 +614,10 @@ process_long_names_member(register Ar *arp, char **long_names_table, char *filen * Global variables used: */ static void -translate_entry(register Ar *arp, Name target, register Property member, char **long_names_table) +translate_entry(Ar *arp, Name target, Property member, char **long_names_table) { - register int len; - register int i; + int len; + int i; wchar_t *member_string; ar_port_word *offs; int strtablen; @@ -625,8 +625,8 @@ translate_entry(register Ar *arp, Name target, register Property member, char ** char *csym; /* string table */ ar_port_word *offend; /* end of offsets table */ int date; - register wchar_t *ap; - register char *hp; + wchar_t *ap; + char *hp; int maxs; int offset; char buffer[4]; @@ -794,10 +794,10 @@ read_error: * Global variables used: */ static long -sgetl(register char *buffer) +sgetl(char *buffer) { - register long w = 0; - register int i = BITSPERBYTE * AR_PORT_WORD; + long w = 0; + int i = BITSPERBYTE * AR_PORT_WORD; while ((i -= BITSPERBYTE) >= 0) { w |= (long) ((unsigned char) *buffer++) << i; diff --git a/usr/src/cmd/make/bin/doname.cc b/usr/src/cmd/make/bin/doname.cc index 70289cc0b5..5de1a99096 100644 --- a/usr/src/cmd/make/bin/doname.cc +++ b/usr/src/cmd/make/bin/doname.cc @@ -78,30 +78,30 @@ static int second_pass = 0; /* * File table of contents */ -extern Doname doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic); -extern Doname doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic); +extern Doname doname_check(Name target, Boolean do_get, Boolean implicit, Boolean automatic); +extern Doname doname(Name target, Boolean do_get, Boolean implicit, Boolean automatic); static Boolean check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals); void dynamic_dependencies(Name target); -static Doname run_command(register Property line, Boolean print_machine); +static Doname run_command(Property line, Boolean print_machine); extern Doname execute_serial(Property line); -extern Name vpath_translation(register Name cmd); +extern Name vpath_translation(Name cmd); extern void check_state(Name temp_file_name); -static void read_dependency_file(register Name filename); +static void read_dependency_file(Name filename); static void check_read_state_file(void); -static void do_assign(register Name line, register Name target); -static void build_command_strings(Name target, register Property line); -static Doname touch_command(register Property line, register Name target, Doname result); +static void do_assign(Name line, Name target); +static void build_command_strings(Name target, Property line); +static Doname touch_command(Property line, Name target, Doname result); extern void update_target(Property line, Doname result); -static Doname sccs_get(register Name target, register Property *command); -extern void read_directory_of_file(register Name file); -static void add_pattern_conditionals(register Name target); -extern void set_locals(register Name target, register Property old_locals); -extern void reset_locals(register Name target, register Property old_locals, register Property conditional, register int index); +static Doname sccs_get(Name target, Property *command); +extern void read_directory_of_file(Name file); +static void add_pattern_conditionals(Name target); +extern void set_locals(Name target, Property old_locals); +extern void reset_locals(Name target, Property old_locals, Property conditional, int index); extern Boolean check_auto_dependencies(Name target, int auto_count, Name *automatics); static void delete_query_chain(Chain ch); // From read2.cc -extern Name normalize_name(register wchar_t *name_string, register int length); +extern Name normalize_name(wchar_t *name_string, int length); @@ -127,7 +127,7 @@ extern Name normalize_name(register wchar_t *name_string, register int length); * report_dependencies No error msg if -P is on */ Doname -doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic) +doname_check(Name target, Boolean do_get, Boolean implicit, Boolean automatic) { int first_time = 1; Doname rv = build_failed; @@ -288,19 +288,19 @@ find_dyntarget(Name target) * report_dependencies make -P is on */ Doname -doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic) +doname(Name target, Boolean do_get, Boolean implicit, Boolean automatic) { Doname result = build_dont_know; Chain out_of_date_list = NULL; Chain target_group; Property old_locals = NULL; - register Property line; + Property line; Property command = NULL; - register Dependency dependency; + Dependency dependency; Name less = NULL; Name true_target = target; Name *automatics = NULL; - register int auto_count; + int auto_count; Boolean rechecking_target = false; Boolean saved_commands_done; Boolean restart = false; @@ -936,7 +936,7 @@ static Boolean check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals) { Boolean dependencies_running; - register Dependency dependency; + Dependency dependency; Doname dep_result; Boolean dependency_changed = false; @@ -1240,9 +1240,9 @@ check_dependencies(Doname *result, Property line, Boolean do_get, Name target, N Name target_body; Name tt = true_target; Property member; - register wchar_t *target_end; - register Dependency suffix; - register int suffix_length; + wchar_t *target_end; + Dependency suffix; + int suffix_length; Wstring targ_string; Wstring suf_string; @@ -1318,16 +1318,16 @@ void dynamic_dependencies(Name target) { wchar_t pattern[MAXPATHLEN]; - register wchar_t *p; + wchar_t *p; Property line; - register Dependency dependency; - register Dependency *remove; + Dependency dependency; + Dependency *remove; String_rec string; wchar_t buffer[MAXPATHLEN]; - register Boolean set_at = false; - register wchar_t *start; + Boolean set_at = false; + wchar_t *start; Dependency new_depe; - register Boolean reuse_cell; + Boolean reuse_cell; Dependency first_member; Name directory; Name lib; @@ -1574,11 +1574,11 @@ dynamic_dependencies(Name target) * touch Indicates that make -t is on */ static Doname -run_command(register Property line, Boolean) +run_command(Property line, Boolean) { - register Doname result = build_ok; - register Boolean remember_only = false; - register Name target = line->body.line.target; + Doname result = build_ok; + Boolean remember_only = false; + Name target = line->body.line.target; wchar_t *string; char tmp_file_path[MAXPATHLEN]; @@ -1902,7 +1902,7 @@ execute_serial(Property line) * Global variables used: */ Name -vpath_translation(register Name cmd) +vpath_translation(Name cmd) { wchar_t buffer[STRING_BUFFER_LENGTH]; String_rec new_cmd; @@ -1991,9 +1991,9 @@ check_state(Name temp_file_name) * trace_reader Debug flag */ static void -read_dependency_file(register Name filename) +read_dependency_file(Name filename) { - register Makefile_type save_makefile_type; + Makefile_type save_makefile_type; if (filename == NULL) { return; @@ -2036,8 +2036,8 @@ static void check_read_state_file(void) { timestruc_t previous = make_state->stat.time; - register Makefile_type save_makefile_type; - register Property makefile; + Makefile_type save_makefile_type; + Property makefile; make_state->stat.time = file_no_time; if ((exists(make_state) == file_doesnt_exist) || @@ -2080,13 +2080,13 @@ check_read_state_file(void) * assign_done Set to indicate doname needs to reprocess */ static void -do_assign(register Name line, register Name target) +do_assign(Name line, Name target) { Wstring wcb(line); - register wchar_t *string = wcb.get_string(); - register wchar_t *equal; - register Name name; - register Boolean append = false; + wchar_t *string = wcb.get_string(); + wchar_t *equal; + Name name; + Boolean append = false; /* * If any runtime assignments are done, doname() must reprocess all @@ -2163,17 +2163,17 @@ do_assign(register Name line, register Name target) * silent Used to init field for line */ static void -build_command_strings(Name target, register Property line) +build_command_strings(Name target, Property line) { String_rec command_line; - register Cmd_line command_template = line->body.line.command_template; - register Cmd_line *insert = &line->body.line.command_used; - register Cmd_line used = *insert; + Cmd_line command_template = line->body.line.command_template; + Cmd_line *insert = &line->body.line.command_used; + Cmd_line used = *insert; wchar_t buffer[STRING_BUFFER_LENGTH]; wchar_t *start; Name new_command_line; - register Boolean new_command_longer = false; - register Boolean ignore_all_command_dependency = true; + Boolean new_command_longer = false; + Boolean ignore_all_command_dependency = true; Property member; static Name less_name; static Name percent_name; @@ -2508,10 +2508,10 @@ build_command_strings(Name target, register Property line) * silent Do not echo commands */ static Doname -touch_command(register Property line, register Name target, Doname result) +touch_command(Property line, Name target, Doname result) { Name name; - register Chain target_group; + Chain target_group; String_rec touch_string; wchar_t buffer[MAXPATHLEN]; Name touch_cmd; @@ -2677,15 +2677,15 @@ update_target(Property line, Doname result) * sccs_get_rule The rule to used for sccs getting */ static Doname -sccs_get(register Name target, register Property *command) +sccs_get(Name target, Property *command) { - register int result; + int result; char link[MAXPATHLEN]; String_rec string; wchar_t name[MAXPATHLEN]; - register wchar_t *p; + wchar_t *p; timestruc_t sccs_time; - register Property line; + Property line; int sym_link_depth = 0; /* For sccs, we need to chase symlinks. */ @@ -2820,7 +2820,7 @@ sccs_get(register Name target, register Property *command) * dot The Name ".", used as the default dir */ void -read_directory_of_file(register Name file) +read_directory_of_file(Name file) { Wstring file_string(file); @@ -2828,10 +2828,10 @@ read_directory_of_file(register Name file) wchar_t usr_include_buf[MAXPATHLEN]; wchar_t usr_include_sys_buf[MAXPATHLEN]; - register Name directory = dot; - register wchar_t *p = (wchar_t *) wcsrchr(wcb, + Name directory = dot; + wchar_t *p = (wchar_t *) wcsrchr(wcb, (int) slash_char); - register int length = p - wcb; + int length = p - wcb; static Name usr_include; static Name usr_include_sys; @@ -2884,9 +2884,9 @@ read_directory_of_file(register Name file) * conditionals The list of pattern conditionals */ static void -add_pattern_conditionals(register Name target) +add_pattern_conditionals(Name target) { - register Property conditional; + Property conditional; Property new_prop; Property *previous; Name_rec dummy; @@ -2951,11 +2951,11 @@ add_pattern_conditionals(register Name target) * recursion_level Used for tracing */ void -set_locals(register Name target, register Property old_locals) +set_locals(Name target, Property old_locals) { - register Property conditional; - register int i; - register Boolean saved_conditional_macro_used; + Property conditional; + int i; + Boolean saved_conditional_macro_used; Chain cond_name; Chain cond_chain; @@ -3013,9 +3013,9 @@ set_locals(register Name target, register Property old_locals) * recursion_level Used for tracing */ void -reset_locals(register Name target, register Property old_locals, register Property conditional, register int index) +reset_locals(Name target, Property old_locals, Property conditional, int index) { - register Property this_conditional; + Property this_conditional; Chain cond_chain; if (target->dont_activate_cond_values) { @@ -3136,7 +3136,7 @@ delete_query_chain(Chain ch) } Doname -target_can_be_built(register Name target) { +target_can_be_built(Name target) { Doname result = build_dont_know; Name true_target = target; Property line; diff --git a/usr/src/cmd/make/bin/dosys.cc b/usr/src/cmd/make/bin/dosys.cc index dcab4df019..2996835740 100644 --- a/usr/src/cmd/make/bin/dosys.cc +++ b/usr/src/cmd/make/bin/dosys.cc @@ -79,13 +79,13 @@ static void redirect_stderr(void); * working_on_targets We started processing real targets */ Doname -dosys(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target) +dosys(Name command, Boolean ignore_error, Boolean call_make, Boolean silent_error, Boolean always_exec, Name target) { timestruc_t before; - register int length = command->hash.length; + int length = command->hash.length; Wstring wcb(command); - register wchar_t *p = wcb.get_string(); - register wchar_t *q; + wchar_t *p = wcb.get_string(); + wchar_t *q; Doname result; /* Strip spaces from head of command string */ diff --git a/usr/src/cmd/make/bin/files.cc b/usr/src/cmd/make/bin/files.cc index dc2d86f32b..6d53241f12 100644 --- a/usr/src/cmd/make/bin/files.cc +++ b/usr/src/cmd/make/bin/files.cc @@ -61,12 +61,12 @@ /* * File table of contents */ -extern timestruc_t& exists(register Name target); -extern void set_target_stat(register Name target, struct stat buf); -static timestruc_t& vpath_exists(register Name target); +extern timestruc_t& exists(Name target); +extern void set_target_stat(Name target, struct stat buf); +static timestruc_t& vpath_exists(Name target); static Name enter_file_name(wchar_t *name_string, wchar_t *library); -static Boolean star_match(register char *string, register char *pattern); -static Boolean amatch(register wchar_t *string, register wchar_t *pattern); +static Boolean star_match(char *string, char *pattern); +static Boolean amatch(wchar_t *string, wchar_t *pattern); /* * exists(target) @@ -85,10 +85,10 @@ static Boolean amatch(register wchar_t *string, register wchar_t *pattern); * vpath_defined Was the variable VPATH defined in environment? */ timestruc_t& -exists(register Name target) +exists(Name target) { struct stat buf; - register int result; + int result; /* We cache stat information. */ if (target->stat.time != file_no_time) { @@ -174,7 +174,7 @@ exists(register Name target) * represented by target. */ void -set_target_stat(register Name target, struct stat buf) +set_target_stat(Name target, struct stat buf) { target->stat.stat_errno = 0; target->stat.is_file = true; @@ -209,7 +209,7 @@ set_target_stat(register Name target, struct stat buf) * vpath_name The Name "VPATH", used to get macro value */ static timestruc_t& -vpath_exists(register Name target) +vpath_exists(Name target) { wchar_t *vpath; wchar_t file_name[MAXPATHLEN]; @@ -296,7 +296,7 @@ read_dir(Name dir, wchar_t *pattern, Property line, wchar_t *library) DIR *dir_fd; int m_local_dependency=0; #define d_fileno d_ino - register struct dirent *dp; + struct dirent *dp; wchar_t *vpath = NULL; wchar_t *p; int result = 0; @@ -613,9 +613,9 @@ enter_file_name(wchar_t *name_string, wchar_t *library) * Global variables used: */ static Boolean -star_match(register wchar_t *string, register wchar_t *pattern) +star_match(wchar_t *string, wchar_t *pattern) { - register int pattern_ch; + int pattern_ch; switch (*pattern) { case 0: @@ -657,12 +657,12 @@ star_match(register wchar_t *string, register wchar_t *pattern) * Global variables used: */ static Boolean -amatch(register wchar_t *string, register wchar_t *pattern) +amatch(wchar_t *string, wchar_t *pattern) { - register long lower_bound; - register long string_ch; - register long pattern_ch; - register int k; + long lower_bound; + long string_ch; + long pattern_ch; + int k; top: for (; 1; pattern++, string++) { diff --git a/usr/src/cmd/make/bin/implicit.cc b/usr/src/cmd/make/bin/implicit.cc index bd8eaab8d7..b0b08b6242 100644 --- a/usr/src/cmd/make/bin/implicit.cc +++ b/usr/src/cmd/make/bin/implicit.cc @@ -56,10 +56,10 @@ static wchar_t WIDE_NULL[1] = {(wchar_t) nul_char}; * File table of contents */ extern Doname find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking); -extern Doname find_ar_suffix_rule(register Name target, Name true_target, Property *command, Boolean rechecking); -extern Doname find_double_suffix_rule(register Name target, Property *command, Boolean rechecking); -extern void build_suffix_list(register Name target_suffix); -extern Doname find_percent_rule(register Name target, Property *command, Boolean rechecking); +extern Doname find_ar_suffix_rule(Name target, Name true_target, Property *command, Boolean rechecking); +extern Doname find_double_suffix_rule(Name target, Property *command, Boolean rechecking); +extern void build_suffix_list(Name target_suffix); +extern Doname find_percent_rule(Name target, Property *command, Boolean rechecking); static void create_target_group_and_dependencies_list(Name target, Percent pat_rule, String percent); static Boolean match_found_with_pattern(Name target, Percent pat_rule, String percent, wchar_t *percent_buf); static void construct_string_from_pattern(Percent pat_rule, String percent, String result); @@ -113,11 +113,11 @@ find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *co static wchar_t static_string_buf_3M [ 3 * MAXPATHLEN ]; Name true_target = target; wchar_t *sourcename = (wchar_t*)static_string_buf_3M; - register wchar_t *put_suffix; - register Property source_suffix; - register Name source; + wchar_t *put_suffix; + Property source_suffix; + Name source; Doname result; - register Property line; + Property line; extern Boolean tilde_rule; Boolean name_found = true; Boolean posix_tilde_attempt = true; @@ -495,11 +495,11 @@ posix_attempts: * suffixes List of suffixes used for scan (from .SUFFIXES) */ Doname -find_ar_suffix_rule(register Name target, Name true_target, Property *command, Boolean rechecking) +find_ar_suffix_rule(Name target, Name true_target, Property *command, Boolean rechecking) { wchar_t *target_end; - register Dependency suffix; - register int suffix_length; + Dependency suffix; + int suffix_length; Property line; Name body; static Name dot_a; @@ -590,13 +590,13 @@ find_ar_suffix_rule(register Name target, Name true_target, Property *command, B * suffixes List of suffixes used for scan (from .SUFFIXES) */ Doname -find_double_suffix_rule(register Name target, Property *command, Boolean rechecking) +find_double_suffix_rule(Name target, Property *command, Boolean rechecking) { Name true_target = target; Name target_body; - register wchar_t *target_end; - register Dependency suffix; - register int suffix_length; + wchar_t *target_end; + Dependency suffix; + int suffix_length; Boolean scanned_once = false; Boolean name_found = true; @@ -697,12 +697,12 @@ find_double_suffix_rule(register Name target, Property *command, Boolean recheck * working_on_targets Indicates that this is a real target */ void -build_suffix_list(register Name target_suffix) +build_suffix_list(Name target_suffix) { - register Dependency source_suffix; + Dependency source_suffix; wchar_t rule_name[MAXPATHLEN]; - register Property line; - register Property suffix; + Property line; + Property suffix; Name rule; /* If this is before default.mk has been read we just return to try */ @@ -795,12 +795,12 @@ build_suffix_list(register Name target_suffix) * empty_name */ Doname -find_percent_rule(register Name target, Property *command, Boolean rechecking) +find_percent_rule(Name target, Property *command, Boolean rechecking) { - register Percent pat_rule, pat_depe; - register Name depe_to_check; - register Dependency depe; - register Property line; + Percent pat_rule, pat_depe; + Name depe_to_check; + Dependency depe; + Property line; String_rec string; wchar_t string_buf[STRING_BUFFER_LENGTH]; String_rec percent; diff --git a/usr/src/cmd/make/bin/macro.cc b/usr/src/cmd/make/bin/macro.cc index 7f4d5bfb46..f81d855556 100644 --- a/usr/src/cmd/make/bin/macro.cc +++ b/usr/src/cmd/make/bin/macro.cc @@ -53,14 +53,14 @@ */ void -setvar_append(register Name name, register Name value) +setvar_append(Name name, Name value) { - register Property macro_apx = get_prop(name->prop, macro_append_prop); - register Property macro = get_prop(name->prop, macro_prop); + Property macro_apx = get_prop(name->prop, macro_append_prop); + Property macro = get_prop(name->prop, macro_prop); int length; String_rec destination; wchar_t buffer[STRING_BUFFER_LENGTH]; - register Chain chain; + Chain chain; Name val = NULL; if(macro_apx == NULL) { @@ -113,8 +113,8 @@ setvar_envvar(void) { wchar_t buffer[STRING_BUFFER_LENGTH]; int length; - register char *mbs, *tmp_mbs_buffer = NULL; - register char *env, *tmp_mbs_buffer2 = NULL; + char *mbs, *tmp_mbs_buffer = NULL; + char *env, *tmp_mbs_buffer2 = NULL; Envvar p; String_rec value; diff --git a/usr/src/cmd/make/bin/main.cc b/usr/src/cmd/make/bin/main.cc index 8c35d06494..fbb54963c3 100644 --- a/usr/src/cmd/make/bin/main.cc +++ b/usr/src/cmd/make/bin/main.cc @@ -61,7 +61,7 @@ #include <vroot/report.h> /* report_dependency(), get_report_file() */ // From read2.cc -extern Name normalize_name(register wchar_t *name_string, register int length); +extern Name normalize_name(wchar_t *name_string, int length); extern void job_adjust_fini(); @@ -129,7 +129,7 @@ extern "C" { extern void dmake_message_callback(char *); } -extern Name normalize_name(register wchar_t *name_string, register int length); +extern Name normalize_name(wchar_t *name_string, int length); extern int main(int, char * []); @@ -148,7 +148,7 @@ static void setup_for_projectdir(void); static void setup_makeflags_argv(void); static void report_dir_enter_leave(Boolean entering); -extern void expand_value(Name, register String , Boolean); +extern void expand_value(Name, String , Boolean); static const char verstring[] = "illumos make"; @@ -184,7 +184,7 @@ main(int argc, char *argv[]) * cp is a -> to the value of the MAKEFLAGS env var, * which has to be regular chars. */ - register char *cp; + char *cp; char make_state_dir[MAXPATHLEN]; Boolean parallel_flag = false; Boolean argv_zero_relative = false; @@ -910,17 +910,17 @@ doalarm(int sig __attribute__((unused))) * Global variables used: */ static void -read_command_options(register int argc, register char **argv) +read_command_options(int argc, char **argv) { - register int ch; + int ch; int current_optind = 1; int last_optind_with_double_hyphen = 0; int last_optind; int last_current_optind; - register int i; - register int j; - register int k; - register int makefile_next = 0; /* + int i; + int j; + int k; + int makefile_next = 0; /* * flag to note options: * -c, f, g, j, m, o */ @@ -1326,7 +1326,7 @@ setup_makeflags_argv() * touch Set for make -t */ static int -parse_command_option(register char ch) +parse_command_option(char ch) { static int invert_next = 0; int invert_this = invert_next; @@ -1778,28 +1778,28 @@ read_files_and_state(int argc, char **argv) { wchar_t buffer[1000]; wchar_t buffer_posix[1000]; - register char ch; - register char *cp; + char ch; + char *cp; Property def_make_macro = NULL; Name def_make_name; Name default_makefile; String_rec dest; wchar_t destbuffer[STRING_BUFFER_LENGTH]; - register int i; - register int j; + int i; + int j; Name keep_state_name; int length; Name Makefile; - register Property macro; + Property macro; struct stat make_state_stat; Name makefile_name; - register int makefile_next = 0; - register Boolean makefile_read = false; + int makefile_next = 0; + Boolean makefile_read = false; String_rec makeflags_string; String_rec makeflags_string_posix; String_rec * makeflags_string_current; Name makeflags_value_saved; - register Name name; + Name name; Name new_make_value; Boolean save_do_not_exec_rule; static wchar_t state_file_str; @@ -1808,7 +1808,7 @@ read_files_and_state(int argc, char **argv) Boolean temp; char tmp_char; wchar_t *tmp_wcs_buffer; - register Name value; + Name value; ASCII_Dyn_Array makeflags_and_macro; Boolean is_xpg4; @@ -2439,14 +2439,14 @@ read_files_and_state(int argc, char **argv) static void enter_argv_values(int argc, char *argv[], ASCII_Dyn_Array *makeflags_and_macro) { - register char *cp; - register int i; + char *cp; + int i; int length; - register Name name; + Name name; int opt_separator = argc; char tmp_char; wchar_t *tmp_wcs_buffer; - register Name value; + Name value; Boolean append = false; Property macro; struct stat statbuf; @@ -2637,7 +2637,7 @@ enter_argv_values(int argc, char *argv[], ASCII_Dyn_Array *makeflags_and_macro) * Append the DMake option and value to the MAKEFLAGS string. */ static void -append_makeflags_string(Name name, register String makeflags_string) +append_makeflags_string(Name name, String makeflags_string) { const char *option; @@ -2687,13 +2687,13 @@ append_makeflags_string(Name name, register String makeflags_string) static void read_environment(Boolean read_only) { - register char **environment; + char **environment; int length; wchar_t *tmp_wcs_buffer; Boolean alloced_tmp_wcs_buffer = false; - register wchar_t *name; - register wchar_t *value; - register Name macro; + wchar_t *name; + wchar_t *value; + Name macro; Property val; Boolean read_only_saved; @@ -2791,7 +2791,7 @@ read_environment(Boolean read_only) * recursion_level Initialized */ static Boolean -read_makefile(register Name makefile, Boolean complain, Boolean must_exist, Boolean report_file) +read_makefile(Name makefile, Boolean complain, Boolean must_exist, Boolean report_file) { Boolean b; @@ -2830,7 +2830,7 @@ make_targets(int argc, char **argv, Boolean parallel_flag) int i; char *cp; Doname result; - register Boolean target_to_make_found = false; + Boolean target_to_make_found = false; (void) doname(init, true, true); recursion_level = 1; @@ -3068,9 +3068,9 @@ make_targets(int argc, char **argv, Boolean parallel_flag) * report_dependency dwight */ static void -report_recursion(register Name target) +report_recursion(Name target) { - register FILE *report_file = get_report_file(); + FILE *report_file = get_report_file(); if ((report_file == NULL) || (report_file == (FILE*)-1)) { return; @@ -3097,14 +3097,14 @@ report_recursion(register Name target) extern void append_or_replace_macro_in_dyn_array(ASCII_Dyn_Array *Ar, char *macro) { - register char *cp0; /* work pointer in macro */ - register char *cp1; /* work pointer in array */ - register char *cp2; /* work pointer in array */ - register char *cp3; /* work pointer in array */ - register char *name; /* macro name */ - register char *value; /* macro value */ - register int len_array; - register int len_macro; + char *cp0; /* work pointer in macro */ + char *cp1; /* work pointer in array */ + char *cp2; /* work pointer in array */ + char *cp3; /* work pointer in array */ + char *name; /* macro name */ + char *value; /* macro value */ + int len_array; + int len_macro; char * esc_value = NULL; int esc_len; diff --git a/usr/src/cmd/make/bin/misc.cc b/usr/src/cmd/make/bin/misc.cc index ed4d89b78a..d6e2d0b87f 100644 --- a/usr/src/cmd/make/bin/misc.cc +++ b/usr/src/cmd/make/bin/misc.cc @@ -66,8 +66,8 @@ extern void job_adjust_fini(); /* * File table of contents */ -static void print_rule(register Name target); -static void print_target_n_deps(register Name target); +static void print_rule(Name target); +static void print_target_n_deps(Name target); /***************************************** * @@ -318,9 +318,9 @@ void dump_make_state(void) { Name_set::iterator p, e; - register Property prop; - register Dependency dep; - register Cmd_line rule; + Property prop; + Dependency dep; + Cmd_line rule; Percent percent, percent_depe; /* Default target */ @@ -464,11 +464,11 @@ dump_make_state(void) * Global variables used: */ static void -print_rule(register Name target) +print_rule(Name target) { - register Cmd_line rule; - register Property line; - register Dependency dependency; + Cmd_line rule; + Property line; + Dependency dependency; if (target->dependency_printed || ((line = get_prop(target->prop, line_prop)) == NULL) || @@ -514,11 +514,11 @@ dump_target_list(void) } static void -print_target_n_deps(register Name target) +print_target_n_deps(Name target) { - register Cmd_line rule; - register Property line; - register Dependency dependency; + Cmd_line rule; + Property line; + Dependency dependency; if (target->dependency_printed) { return; diff --git a/usr/src/cmd/make/bin/nse_printdep.cc b/usr/src/cmd/make/bin/nse_printdep.cc index dd2bc62825..cb7228d2da 100644 --- a/usr/src/cmd/make/bin/nse_printdep.cc +++ b/usr/src/cmd/make/bin/nse_printdep.cc @@ -32,15 +32,15 @@ /* * File table of contents */ -void print_dependencies(register Name target, register Property line); -static void print_deps(register Name target, register Property line); +void print_dependencies(Name target, Property line); +static void print_deps(Name target, Property line); static void print_more_deps(Name target, Name name); static void print_filename(Name name); static Boolean should_print_dep(Property line); static void print_forest(Name target); static void print_deplist(Dependency head); -void print_value(register Name value, Daemon daemon); -static void print_rule(register Name target); +void print_value(Name value, Daemon daemon); +static void print_rule(Name target); static void print_rec_info(Name target); static Boolean is_out_of_date(Property line); extern void depvar_print_results (void); @@ -62,7 +62,7 @@ extern void depvar_print_results (void); * makefiles_used List of all makefiles read */ void -print_dependencies(register Name target, register Property line) +print_dependencies(Name target, Property line) { Dependency dp; static Boolean makefiles_printed = false; @@ -120,7 +120,7 @@ static void print_more_deps(Name target, Name name) { Property line; - register Dependency dependencies; + Dependency dependencies; line = get_prop(name->prop, line_prop); if (line != NULL && line->body.line.dependencies != NULL) { @@ -151,9 +151,9 @@ print_more_deps(Name target, Name name) * recursive_name The Name ".RECURSIVE", printed */ static void -print_deps(register Name target, register Property line) +print_deps(Name target, Property line) { - register Dependency dep; + Dependency dep; if ((target->dependency_printed) || (target == force)) { @@ -302,7 +302,7 @@ print_forest(Name target) * Used for the -p option */ void -print_value(register Name value, Daemon daemon) +print_value(Name value, Daemon daemon) { Chain cp; @@ -323,10 +323,10 @@ print_value(register Name value, Daemon daemon) } static void -print_rule(register Name target) +print_rule(Name target) { - register Cmd_line rule; - register Property line; + Cmd_line rule; + Property line; if (((line= get_prop(target->prop, line_prop)) == NULL) || ((line->body.line.command_template == NULL) && diff --git a/usr/src/cmd/make/bin/read.cc b/usr/src/cmd/make/bin/read.cc index 9d697c6ced..93b1e5f726 100644 --- a/usr/src/cmd/make/bin/read.cc +++ b/usr/src/cmd/make/bin/read.cc @@ -59,10 +59,10 @@ static int line_started_with_space=0; // Used to diagnose spaces instead of tabs /* * File table of contents */ -static void parse_makefile(register Name true_makefile_name, register Source source); -static Source push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source); +static void parse_makefile(Name true_makefile_name, Source source); +static Source push_macro_value(Source bp, wchar_t *buffer, int size, Source source); extern void enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen); -extern Name normalize_name(register wchar_t *name_string, register int length); +extern Name normalize_name(wchar_t *name_string, int length); /* * read_simple_file(makefile_name, chase_path, doname_it, @@ -93,27 +93,27 @@ extern Name normalize_name(register wchar_t *name_string, register int length); Boolean -read_simple_file(register Name makefile_name, register Boolean chase_path, register Boolean doname_it, Boolean complain, Boolean must_exist, Boolean report_file, Boolean lock_makefile) +read_simple_file(Name makefile_name, Boolean chase_path, Boolean doname_it, Boolean complain, Boolean must_exist, Boolean report_file, Boolean lock_makefile) { static short max_include_depth; - register Property makefile = maybe_append_prop(makefile_name, + Property makefile = maybe_append_prop(makefile_name, makefile_prop); Boolean forget_after_parse = false; static pathpt makefile_path; - register int n; + int n; char *path; - register Source source = ALLOC(Source); + Source source = ALLOC(Source); Property orig_makefile = makefile; Dependency *dpp; Dependency dp; - register int length; + int length; wchar_t *previous_file_being_read = file_being_read; int previous_line_number = line_number; wchar_t previous_current_makefile[MAXPATHLEN]; Makefile_type save_makefile_type; Name normalized_makefile_name; - register wchar_t *string_start; - register wchar_t *string_end; + wchar_t *string_start; + wchar_t *string_end; @@ -457,21 +457,21 @@ read_simple_file(register Name makefile_name, register Boolean chase_path, regis * empty_name The Name "" */ static void -parse_makefile(register Name true_makefile_name, register Source source) +parse_makefile(Name true_makefile_name, Source source) { /* char mb_buffer[MB_LEN_MAX]; */ - register wchar_t *source_p; - register wchar_t *source_end; - register wchar_t *string_start; + wchar_t *source_p; + wchar_t *source_end; + wchar_t *string_start; wchar_t *string_end; - register Boolean macro_seen_in_string; + Boolean macro_seen_in_string; Boolean append; String_rec name_string; wchar_t name_buffer[STRING_BUFFER_LENGTH]; - register int distance; - register int paren_count; + int distance; + int paren_count; int brace_count; int char_number; Cmd_line command; @@ -486,9 +486,9 @@ parse_makefile(register Name true_makefile_name, register Source source) Name_vector nvp; Boolean target_group_seen; - register Reader_state state; - register Reader_state on_eoln_state; - register Separator separator; + Reader_state state; + Reader_state on_eoln_state; + Separator separator; wchar_t buffer[4 * STRING_BUFFER_LENGTH]; Source extrap; @@ -2025,7 +2025,7 @@ default: * Global variables used: */ static Source -push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source) +push_macro_value(Source bp, wchar_t *buffer, int size, Source source) { bp->string.buffer.start = bp->string.text.p = buffer; bp->string.text.end = NULL; diff --git a/usr/src/cmd/make/bin/read2.cc b/usr/src/cmd/make/bin/read2.cc index a968e18b8b..c198ceef6e 100644 --- a/usr/src/cmd/make/bin/read2.cc +++ b/usr/src/cmd/make/bin/read2.cc @@ -57,11 +57,11 @@ static Boolean built_last_make_run_seen; /* * File table of contents */ -static Name_vector enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names); -extern Name normalize_name(register wchar_t *name_string, register int length); -static void read_suffixes_list(register Name_vector depes); +static Name_vector enter_member_name(wchar_t *lib_start, wchar_t *member_start, wchar_t *string_end, Name_vector current_names, Name_vector *extra_names); +extern Name normalize_name(wchar_t *name_string, int length); +static void read_suffixes_list(Name_vector depes); static void make_relative(wchar_t *to, wchar_t *result); -static void print_rule(register Cmd_line command); +static void print_rule(Cmd_line command); static void sh_transform(Name *name, Name *value); @@ -94,10 +94,10 @@ static void sh_transform(Name *name, Name *value); */ Name_vector -enter_name(String string, Boolean tail_present, register wchar_t *string_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen) +enter_name(String string, Boolean tail_present, wchar_t *string_start, wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen) { Name name; - register wchar_t *cp; + wchar_t *cp; wchar_t ch; /* If we were passed a separate tail of the name we append it to the */ @@ -192,9 +192,9 @@ if(current_names->used != 0 && current_names->names[current_names->used-1] == pl * Global variables used: */ static Name_vector -enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names) +enter_member_name(wchar_t *lib_start, wchar_t *member_start, wchar_t *string_end, Name_vector current_names, Name_vector *extra_names) { - register Boolean entry = false; + Boolean entry = false; wchar_t buffer[STRING_BUFFER_LENGTH]; Name lib; Name member; @@ -202,9 +202,9 @@ enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, r Property prop; wchar_t *memberp; wchar_t *q; - register int paren_count; - register Boolean has_dollar; - register wchar_t *cq; + int paren_count; + Boolean has_dollar; + wchar_t *cq; Name long_member_name = NULL; /* Internalize the name of the library */ @@ -334,15 +334,15 @@ enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, r * dotdot The Name "..", compared against */ Name -normalize_name(register wchar_t *name_string, register int length) +normalize_name(wchar_t *name_string, int length) { static Name dotdot; - register wchar_t *string = ALLOC_WC(length + 1); - register wchar_t *string2; - register wchar_t *cdp; + wchar_t *string = ALLOC_WC(length + 1); + wchar_t *string2; + wchar_t *cdp; wchar_t *current_component; Name name; - register int count; + int count; if (dotdot == NULL) { MBSTOWCS(wcs_buffer, ".."); @@ -464,7 +464,7 @@ removed_one: * plus The Name "+", compared against */ Chain -find_target_groups(register Name_vector target_list, register int i, Boolean reset) +find_target_groups(Name_vector target_list, int i, Boolean reset) { static Chain target_group = NULL; static Chain tail_target_group = NULL; @@ -568,10 +568,10 @@ find_target_groups(register Name_vector target_list, register int i, Boolean res * trace_reader Indicates that we should echo stuff we read */ void -enter_dependencies(register Name target, Chain target_group, register Name_vector depes, register Cmd_line command, register Separator separator) +enter_dependencies(Name target, Chain target_group, Name_vector depes, Cmd_line command, Separator separator) { - register int i; - register Property line; + int i; + Property line; Name name; Name directory; wchar_t *namep; @@ -580,7 +580,7 @@ enter_dependencies(register Name target, Chain target_group, register Name_vecto Dependency *dpp; Property line2; wchar_t relative[MAXPATHLEN]; - register int recursive_state; + int recursive_state; Boolean register_as_auto; Boolean not_auto_found; char *slash; @@ -870,10 +870,10 @@ enter_dependencies(register Name target, Chain target_group, register Name_vecto * wait_name The Name ".WAIT", compared against */ void -enter_dependency(Property line, register Name depe, Boolean automatic) +enter_dependency(Property line, Name depe, Boolean automatic) { - register Dependency dp; - register Dependency *insert; + Dependency dp; + Dependency *insert; if (trace_reader) { (void) printf("%s ", depe->string_mb); @@ -927,13 +927,13 @@ enter_dependency(Property line, register Name depe, Boolean automatic) * trace_reader Indicates that we should echo stuff we read */ Percent -enter_percent(register Name target, Chain target_group, register Name_vector depes, Cmd_line command) +enter_percent(Name target, Chain target_group, Name_vector depes, Cmd_line command) { - register Percent result = ALLOC(Percent); - register Percent depe; - register Percent *depe_tail = &result->dependencies; - register Percent *insert; - register wchar_t *cp, *cp1; + Percent result = ALLOC(Percent); + Percent depe; + Percent *depe_tail = &result->dependencies; + Percent *insert; + wchar_t *cp, *cp1; Name_vector nvp; int i; int pattern; @@ -1065,9 +1065,9 @@ enter_percent(register Name target, Chain target_group, register Name_vector dep * trace_reader Indicates that we should echo stuff we read */ Dyntarget -enter_dyntarget(register Name target) +enter_dyntarget(Name target) { - register Dyntarget result = ALLOC(Dyntarget); + Dyntarget result = ALLOC(Dyntarget); Dyntarget p; Dyntarget *insert; int i; @@ -1130,9 +1130,9 @@ enter_dyntarget(register Name target) * trace_reader Indicates that we should echo stuff we read */ void -special_reader(Name target, register Name_vector depes, Cmd_line command) +special_reader(Name target, Name_vector depes, Cmd_line command) { - register int n; + int n; switch (target->special_reader) { @@ -1471,14 +1471,14 @@ special_reader(Name target, register Name_vector depes, Cmd_line command) * trace_reader Indicates that we should echo stuff we read */ static void -read_suffixes_list(register Name_vector depes) +read_suffixes_list(Name_vector depes) { - register int n; - register Dependency dp; - register Dependency *insert_dep; - register Name np; + int n; + Dependency dp; + Dependency *insert_dep; + Name np; Name np2; - register Boolean first = true; + Boolean first = true; if (depes->used == 0) { /* .SUFFIXES with no dependency list clears the */ @@ -1652,7 +1652,7 @@ make_relative(wchar_t *to, wchar_t *result) * Global variables used: */ static void -print_rule(register Cmd_line command) +print_rule(Cmd_line command) { for (; command != NULL; command = command->next) { (void) printf("\t%s\n", command->command_line->string_mb); @@ -1676,9 +1676,9 @@ print_rule(register Cmd_line command) * trace_reader Indicates that we should echo stuff we read */ void -enter_conditional(register Name target, Name name, Name value, register Boolean append) +enter_conditional(Name target, Name name, Name value, Boolean append) { - register Property conditional; + Property conditional; static int sequence; Name orig_target = target; @@ -1741,7 +1741,7 @@ enter_conditional(register Name target, Name name, Name value, register Boolean * trace_reader Indicates that we should echo stuff we read */ void -enter_equal(Name name, Name value, register Boolean append) +enter_equal(Name name, Name value, Boolean append) { wchar_t *string; Name temp; diff --git a/usr/src/cmd/make/bin/rep.cc b/usr/src/cmd/make/bin/rep.cc index 479967f938..87e9c0a782 100644 --- a/usr/src/cmd/make/bin/rep.cc +++ b/usr/src/cmd/make/bin/rep.cc @@ -323,7 +323,7 @@ gather_recursive_deps(void) Name_set::iterator np, e; String_rec rec; wchar_t rec_buf[STRING_BUFFER_LENGTH]; - register Property lines; + Property lines; Boolean has_recursive; Dependency dp; diff --git a/usr/src/cmd/make/bin/state.cc b/usr/src/cmd/make/bin/state.cc index a7557a4946..91719d7ffa 100644 --- a/usr/src/cmd/make/bin/state.cc +++ b/usr/src/cmd/make/bin/state.cc @@ -93,7 +93,7 @@ static char * escape_target_name(Name np) } } -static void print_auto_depes(register Dependency dependency, register FILE *fd, register Boolean built_this_run, register int *line_length, register char *target_name, jmp_buf long_jump); +static void print_auto_depes(Dependency dependency, FILE *fd, Boolean built_this_run, int *line_length, char *target_name, jmp_buf long_jump); /* * write_state_file(report_recursive, exiting) @@ -120,21 +120,21 @@ static void print_auto_depes(register Dependency dependency, register FILE *fd, void write_state_file(int, Boolean exiting) { - register FILE *fd; + FILE *fd; int lock_err; char buffer[MAXPATHLEN]; char make_state_tempfile[MAXPATHLEN]; jmp_buf long_jump; - register int attempts = 0; + int attempts = 0; Name_set::iterator np, e; - register Property lines; - register int m; + Property lines; + int m; Dependency dependency; - register Boolean name_printed; + Boolean name_printed; Boolean built_this_run = false; char *target_name; int line_length; - register Cmd_line cp; + Cmd_line cp; if (!rewrite_statefile || @@ -410,7 +410,7 @@ write_state_file(int, Boolean exiting) * force The Name " FORCE", compared against */ static void -print_auto_depes(register Dependency dependency, register FILE *fd, register Boolean built_this_run, register int *line_length, register char *target_name, jmp_buf long_jump) +print_auto_depes(Dependency dependency, FILE *fd, Boolean built_this_run, int *line_length, char *target_name, jmp_buf long_jump) { if (!dependency->automatic || dependency->stale || diff --git a/usr/src/cmd/make/include/mksh/dosys.h b/usr/src/cmd/make/include/mksh/dosys.h index 18e33924d5..25b6ba8364 100644 --- a/usr/src/cmd/make/include/mksh/dosys.h +++ b/usr/src/cmd/make/include/mksh/dosys.h @@ -1,5 +1,3 @@ -#ifndef _MKSH_DOSYS_H -#define _MKSH_DOSYS_H /* * CDDL HEADER START * @@ -25,13 +23,16 @@ * Use is subject to license terms. */ +#ifndef _MKSH_DOSYS_H +#define _MKSH_DOSYS_H + #include <mksh/defs.h> #include <vroot/vroot.h> -extern Boolean await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, void *xdrs, int job_msg_id); -extern int doexec(register wchar_t *command, register Boolean ignore_error, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio); -extern int doshell(wchar_t *command, register Boolean ignore_error, char *stdout_file, char *stderr_file, int nice_prio); -extern void redirect_io(char *stdout_file, char *stderr_file); -extern void sh_command2string(register String command, register String destination); +extern Boolean await(Boolean, Boolean, Name, wchar_t *, pid_t, void *, int); +extern int doexec(wchar_t *, Boolean, char *, char *, pathpt, int); +extern int doshell(wchar_t *, Boolean, char *, char *, int); +extern void redirect_io(char *, char *); +extern void sh_command2string(String, String); -#endif +#endif /* _MKSH_DOSYS_H */ diff --git a/usr/src/cmd/make/include/mksh/macro.h b/usr/src/cmd/make/include/mksh/macro.h index 2068d4884d..504289fbf8 100644 --- a/usr/src/cmd/make/include/mksh/macro.h +++ b/usr/src/cmd/make/include/mksh/macro.h @@ -1,5 +1,3 @@ -#ifndef _MKSH_MACRO_H -#define _MKSH_MACRO_H /* * CDDL HEADER START * @@ -25,12 +23,15 @@ * Use is subject to license terms. */ +#ifndef _MKSH_MACRO_H +#define _MKSH_MACRO_H + #include <mksh/defs.h> -extern void expand_macro(register Source source, register String destination, wchar_t *current_string, Boolean cmd); -extern void expand_value(Name value, register String destination, Boolean cmd); -extern Name getvar(register Name name); +extern void expand_macro(Source, String, wchar_t *, Boolean); +extern void expand_value(Name, String, Boolean); +extern Name getvar(Name); -extern Property setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level); +extern Property setvar_daemon(Name, Name, Boolean, Daemon, Boolean, short); -#endif +#endif /* _MKSH_MACRO_H */ diff --git a/usr/src/cmd/make/include/mksh/misc.h b/usr/src/cmd/make/include/mksh/misc.h index d5506fdedb..fd3d6410e5 100644 --- a/usr/src/cmd/make/include/mksh/misc.h +++ b/usr/src/cmd/make/include/mksh/misc.h @@ -1,5 +1,3 @@ -#ifndef _MKSH_MISC_H -#define _MKSH_MISC_H /* * CDDL HEADER START * @@ -27,31 +25,35 @@ * Copyright 2019 RackTop Systems. */ +#ifndef _MKSH_MISC_H +#define _MKSH_MISC_H + #include <mksh/defs.h> -extern void append_char(wchar_t from, register String to); -extern Property append_prop(register Name target, register Property_id type); -extern void append_string(register wchar_t *from, register String to, register int length); -extern void enable_interrupt(register void (*handler) (int)); -extern char *errmsg(int errnum); -extern void fatal_mksh(const char *message, ...) __NORETURN; -extern void fatal_reader_mksh(const char *pattern, ...) __NORETURN; +extern void append_char(wchar_t, String); +extern Property append_prop(Name, Property_id); +extern void append_string(wchar_t *, String, int); +extern void enable_interrupt(void (*) (int)); +extern char *errmsg(int); +extern void fatal_mksh(const char *, ...) __NORETURN; +extern void fatal_reader_mksh(const char *, ...) __NORETURN; extern char *get_current_path_mksh(void); -extern Property get_prop(register Property start, register Property_id type); -extern char *getmem(size_t size); -extern Name getname_fn(wchar_t *name, register int len, register Boolean dont_enter, register Boolean * foundp = NULL); -extern void store_name(Name name); -extern void free_name(Name name); +extern Property get_prop(Property, Property_id); +extern char *getmem(size_t); +extern Name getname_fn(wchar_t *name, int len, Boolean dont_enter, + Boolean *foundp = NULL); +extern void store_name(Name); +extern void free_name(Name); extern void handle_interrupt_mksh(int); -extern Property maybe_append_prop(register Name target, register Property_id type); -extern void retmem(wchar_t *p); -extern void retmem_mb(caddr_t p); +extern Property maybe_append_prop(Name, Property_id); +extern void retmem(wchar_t *); +extern void retmem_mb(caddr_t); extern void setup_char_semantics(void); -extern void setup_interrupt(register void (*handler) (int)); -extern void warning_mksh(char * message, ...); +extern void setup_interrupt(void (*) (int)); +extern void warning_mksh(char *, ...); -extern void append_string(register char *from, register String to, register int length); -extern wchar_t *get_wstring(char * from); +extern void append_string(char *, String, int); +extern wchar_t *get_wstring(char *); -#endif +#endif /* _MKSH_MISC_H */ diff --git a/usr/src/cmd/make/include/mksh/read.h b/usr/src/cmd/make/include/mksh/read.h index 7866d3d398..1151d529b0 100644 --- a/usr/src/cmd/make/include/mksh/read.h +++ b/usr/src/cmd/make/include/mksh/read.h @@ -1,5 +1,3 @@ -#ifndef _MKSH_READ_H -#define _MKSH_READ_H /* * CDDL HEADER START * @@ -25,9 +23,11 @@ * Use is subject to license terms. */ +#ifndef _MKSH_READ_H +#define _MKSH_READ_H #include <mksh/defs.h> -extern Source get_next_block_fn(register Source source); +extern Source get_next_block_fn(Source source); -#endif +#endif /* _MKSH_READ_H */ diff --git a/usr/src/cmd/make/include/vroot/args.h b/usr/src/cmd/make/include/vroot/args.h index 09bb4b47e5..d001b29ee6 100644 --- a/usr/src/cmd/make/include/vroot/args.h +++ b/usr/src/cmd/make/include/vroot/args.h @@ -25,7 +25,7 @@ #ifndef _ARGS_H_ -#define _ARGS_H_ +#define _ARGS_H_ #include <sys/syscall.h> #include <errno.h> @@ -39,25 +39,52 @@ typedef enum { rw_read, rw_write} rwt, *rwpt; -extern void translate_with_thunk(register char *filename, int (*thunk) (char *), pathpt path_vector, pathpt vroot_vector, rwt rw); +extern void translate_with_thunk(char *, int (*) (char *), pathpt, pathpt, + rwt); union Args { - struct { int mode;} access; - struct { int mode;} chmod; - struct { int user; int group;} chown; - struct { int mode;} creat; - struct { char **argv; char **environ;} execve; - struct { struct stat *buffer;} lstat; - struct { int mode;} mkdir; - struct { char *name; int mode;} mount; - struct { int flags; int mode;} open; - struct { char *buffer; int buffer_size;} readlink; - struct { struct stat *buffer;} stat; - struct { int length;} truncate; - struct { struct timeval *time;} utimes; + struct { + int mode; + } access; + struct { + int mode; + } chmod; + struct { + int user; int group; + } chown; + struct { + int mode; + } creat; + struct { + char **argv; char **environ; + } execve; + struct { + struct stat *buffer; + } lstat; + struct { + int mode; + } mkdir; + struct { + char *name; int mode; + } mount; + struct { + int flags; int mode; + } open; + struct { + char *buffer; int buffer_size; + } readlink; + struct { + struct stat *buffer; + } stat; + struct { + int length; + } truncate; + struct { + struct timeval *time; + } utimes; }; extern union Args vroot_args; extern int vroot_result; -#endif +#endif /* _ARGS_H_ */ diff --git a/usr/src/cmd/make/include/vroot/vroot.h b/usr/src/cmd/make/include/vroot/vroot.h index cf84681ebf..eff7df173b 100644 --- a/usr/src/cmd/make/include/vroot/vroot.h +++ b/usr/src/cmd/make/include/vroot/vroot.h @@ -25,12 +25,12 @@ #ifndef _VROOT_H_ -#define _VROOT_H_ +#define _VROOT_H_ #include <stdio.h> #include <nl_types.h> -#define VROOT_DEFAULT ((pathpt)-1) +#define VROOT_DEFAULT ((pathpt)-1) typedef struct { char *path; @@ -38,24 +38,24 @@ typedef struct { } pathcellt, *pathcellpt, patht; typedef patht *pathpt; -extern void add_dir_to_path(const char *path, register pathpt *pointer, register int position); +extern void add_dir_to_path(const char *, pathpt *, int); extern void flush_path_cache(void); extern void flush_vroot_cache(void); extern const char *get_path_name(void); -extern char *get_vroot_path(register char **vroot, register char **path, register char **filename); +extern char *get_vroot_path(char **, char **, char **); extern const char *get_vroot_name(void); -extern int open_vroot(char *path, int flags, int mode, pathpt vroot_path, pathpt vroot_vroot); -extern pathpt parse_path_string(register char *string, register int remove_slash); +extern int open_vroot(char *, int, int, pathpt, pathpt); +extern pathpt parse_path_string(char *, int); extern void scan_path_first(void); extern void scan_vroot_first(void); -extern void set_path_style(int style); +extern void set_path_style(int); -extern int access_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot); +extern int access_vroot(char *, int, pathpt, pathpt); -extern int execve_vroot(char *path, char **argv, char **environ, pathpt vroot_path, pathpt vroot_vroot); +extern int execve_vroot(char *, char **, char **, pathpt, pathpt); -extern int lstat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot); -extern int stat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot); -extern int readlink_vroot(char *path, char *buffer, int buffer_size, pathpt vroot_path, pathpt vroot_vroot); +extern int lstat_vroot(char *, struct stat *, pathpt, pathpt); +extern int stat_vroot(char *, struct stat *, pathpt, pathpt); +extern int readlink_vroot(char *, char *, int, pathpt, pathpt); -#endif +#endif /* _VROOT_H_ */ diff --git a/usr/src/cmd/make/lib/mksh/macro.cc b/usr/src/cmd/make/lib/mksh/macro.cc index b8151054a9..24e3a453ba 100644 --- a/usr/src/cmd/make/lib/mksh/macro.cc +++ b/usr/src/cmd/make/lib/mksh/macro.cc @@ -45,7 +45,7 @@ * File table of contents */ static void add_macro_to_global_list(Name macro_to_add); -static void expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd); +static void expand_value_with_daemon(Name, Property macro, String destination, Boolean cmd); static void init_arch_macros(void); static void init_mach_macros(void); @@ -70,11 +70,11 @@ long env_alloc_bytes = 0; * Global variables used: */ Name -getvar(register Name name) +getvar(Name name) { String_rec destination; wchar_t buffer[STRING_BUFFER_LENGTH]; - register Name result; + Name result; if ((name == host_arch) || (name == target_arch)) { if (!init_arch_done) { @@ -115,12 +115,12 @@ getvar(register Name name) * Global variables used: */ void -expand_value(Name value, register String destination, Boolean cmd) +expand_value(Name value, String destination, Boolean cmd) { Source_rec sourceb; - register Source source = &sourceb; - register wchar_t *source_p = NULL; - register wchar_t *source_end = NULL; + Source source = &sourceb; + wchar_t *source_p = NULL; + wchar_t *source_end = NULL; wchar_t *block_start = NULL; int quote_seen = 0; @@ -235,9 +235,9 @@ expand_value(Name value, register String destination, Boolean cmd) * and get the value. The value is then expanded. * destination is a String that is filled in with the expanded macro. * It may be passed in referencing a buffer to expand the macro into. - * Note that most expansions are done on demand, e.g. right + * Note that most expansions are done on demand, e.g. right * before the command is executed and not while the file is - * being parsed. + * being parsed. * * Parameters: * source The source block that references the string @@ -256,19 +256,19 @@ expand_value(Name value, register String destination, Boolean cmd) * query_mentioned Set if the word "?" is mentioned */ void -expand_macro(register Source source, register String destination, wchar_t *current_string, Boolean cmd) +expand_macro(Source source, String destination, wchar_t *current_string, Boolean cmd) { static Name make = (Name)NULL; static wchar_t colon_sh[4]; static wchar_t colon_shell[7]; String_rec string; wchar_t buffer[STRING_BUFFER_LENGTH]; - register wchar_t *source_p = source->string.text.p; - register wchar_t *source_end = source->string.text.end; - register int closer = 0; + wchar_t *source_p = source->string.text.p; + wchar_t *source_end = source->string.text.end; + int closer = 0; wchar_t *block_start = (wchar_t *)NULL; int quote_seen = 0; - register int closer_level = 1; + int closer_level = 1; Name name = (Name)NULL; wchar_t *colon = (wchar_t *)NULL; wchar_t *percent = (wchar_t *)NULL; @@ -857,7 +857,7 @@ add_macro_to_global_list(Name macro_to_add) value_to_add = ""; } - /* + /* * Check if this macro is already on list, if so, do nothing */ for (macro_on_list = cond_macro_list; @@ -885,11 +885,11 @@ add_macro_to_global_list(Name macro_to_add) * * Set the magic macros TARGET_ARCH, HOST_ARCH, * - * Parameters: + * Parameters: * * Global variables used: - * host_arch Property for magic macro HOST_ARCH - * target_arch Property for magic macro TARGET_ARCH + * host_arch Property for magic macro HOST_ARCH + * target_arch Property for magic macro TARGET_ARCH * * Return value: * The function does not return a value, but can @@ -940,11 +940,11 @@ init_arch_macros(void) * * Set the magic macros TARGET_MACH, HOST_MACH, * - * Parameters: + * Parameters: * * Global variables used: - * host_mach Property for magic macro HOST_MACH - * target_mach Property for magic macro TARGET_MACH + * host_mach Property for magic macro HOST_MACH + * target_mach Property for magic macro TARGET_MACH * * Return value: * The function does not return a value, but can @@ -1005,9 +1005,9 @@ init_mach_macros(void) * Global variables used: */ static void -expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd) +expand_value_with_daemon(Name, Property macro, String destination, Boolean cmd) { - register Chain chain; + Chain chain; switch (macro->body.macro.daemon) { @@ -1074,14 +1074,14 @@ int sunpro_dependencies_buf_size = 0; * envvar A list of environment vars with $ in value */ Property -setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level) +setvar_daemon(Name name, Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level) { - register Property macro = maybe_append_prop(name, macro_prop); - register Property macro_apx = get_prop(name->prop, macro_append_prop); + Property macro = maybe_append_prop(name, macro_prop); + Property macro_apx = get_prop(name->prop, macro_append_prop); int length = 0; String_rec destination; wchar_t buffer[STRING_BUFFER_LENGTH]; - register Chain chain; + Chain chain; Name val; wchar_t *val_string = (wchar_t*)NULL; Wstring wcb; @@ -1111,7 +1111,7 @@ setvar_daemon(register Name name, register Name value, Boolean append, Daemon da value = GETNAME(destination.buffer.start, FIND_LENGTH); } } - + if(macro_apx != NULL) { val = macro_apx->body.macro_appendix.value; } else { @@ -1313,7 +1313,7 @@ found_it:; new_value = ALLOC_WC(length); new_value_allocated = true; WCSTOMBS(mbs_buffer, old_vr); - (void) swprintf(new_value, length * SIZEOFWCHAR_T, + (void) swprintf(new_value, length * SIZEOFWCHAR_T, L"/usr/arch/%s/%s:%s", ha->string_mb + 1, ta->string_mb + 1, diff --git a/usr/src/cmd/make/lib/mksh/misc.cc b/usr/src/cmd/make/lib/mksh/misc.cc index fe14fd874d..b46a7a1fd4 100644 --- a/usr/src/cmd/make/lib/mksh/misc.cc +++ b/usr/src/cmd/make/lib/mksh/misc.cc @@ -84,7 +84,7 @@ long getwstring_count = 0; /* * File table of contents */ -static void expand_string(register String string, register int length); +static void expand_string(String string, int length); #define FATAL_ERROR_MSG_SIZE 200 @@ -154,11 +154,11 @@ retmem_mb(caddr_t p) * hashtab The hashtable used for the nametable */ Name -getname_fn(wchar_t *name, register int len, register Boolean dont_enter, register Boolean * foundp) +getname_fn(wchar_t *name, int len, Boolean dont_enter, Boolean * foundp) { - register int length; - register wchar_t *cap = name; - register Name np; + int length; + wchar_t *cap = name; + Name np; static Name_rec empty_Name; char *tmp_mbs_buffer = NULL; char *mbs_name = mbs_buffer; @@ -266,7 +266,7 @@ free_name(Name name) * sighvalue The original signal handler */ void -enable_interrupt(register void (*handler) (int)) +enable_interrupt(void (*handler) (int)) { if (sigivalue != SIG_IGN) { (void) bsd_signal(SIGINT, (SIG_PF) handler); @@ -546,11 +546,11 @@ get_current_path_mksh(void) * Global variables used: */ Property -append_prop(register Name target, register Property_id type) +append_prop(Name target, Property_id type) { - register Property *insert = &target->prop; - register Property prop = *insert; - register int size; + Property *insert = &target->prop; + Property prop = *insert; + int size; switch (type) { case conditional_prop: @@ -623,9 +623,9 @@ append_prop(register Name target, register Property_id type) * Global variables used: */ Property -maybe_append_prop(register Name target, register Property_id type) +maybe_append_prop(Name target, Property_id type) { - register Property prop; + Property prop; if ((prop = get_prop(target->prop, type)) != NULL) { return prop; @@ -649,7 +649,7 @@ maybe_append_prop(register Name target, register Property_id type) * Global variables used: */ Property -get_prop(register Property start, register Property_id type) +get_prop(Property start, Property_id type) { for (; start != NULL; start = start->next) { if (start->type == type) { @@ -672,7 +672,7 @@ get_prop(register Property start, register Property_id type) * Global variables used: */ void -append_string(register wchar_t *from, register String to, register int length) +append_string(wchar_t *from, String to, int length) { if (length == FIND_LENGTH) { length = wcslen(from); @@ -703,7 +703,7 @@ wchar_t * get_wstring(char *from) { } void -append_string(register char *from, register String to, register int length) +append_string(char *from, String to, int length) { if (length == FIND_LENGTH) { length = strlen(from); @@ -735,9 +735,9 @@ append_string(register char *from, register String to, register int length) * Global variables used: */ static void -expand_string(register String string, register int length) +expand_string(String string, int length) { - register wchar_t *p; + wchar_t *p; if (string->buffer.start == NULL) { /* For strings that have no memory allocated */ @@ -784,7 +784,7 @@ expand_string(register String string, register int length) * Global variables used: */ void -append_char(wchar_t from, register String to) +append_char(wchar_t from, String to) { if (to->buffer.start == NULL) { expand_string(to, 32); @@ -829,7 +829,7 @@ handle_interrupt_mksh(int) * sighvalue The original signal handler */ void -setup_interrupt(register void (*handler) (int)) +setup_interrupt(void (*handler) (int)) { sigivalue = bsd_signal(SIGINT, SIG_IGN); sigqvalue = bsd_signal(SIGQUIT, SIG_IGN); diff --git a/usr/src/cmd/make/lib/mksh/read.cc b/usr/src/cmd/make/lib/mksh/read.cc index 6a6a2612b4..08dec3d5b3 100644 --- a/usr/src/cmd/make/lib/mksh/read.cc +++ b/usr/src/cmd/make/lib/mksh/read.cc @@ -59,18 +59,18 @@ */ Boolean make_state_locked; Source -get_next_block_fn(register Source source) +get_next_block_fn(Source source) { - register off_t to_read; - register int length; - register size_t num_wc_chars; + off_t to_read; + int length; + size_t num_wc_chars; char ch_save; char *ptr; if (source == NULL) { return NULL; } - if ((source->fd < 0) || + if ((source->fd < 0) || ((source->bytes_left_in_file <= 0) && (source->inp_buf_ptr >= source->inp_buf_end))) { /* We can't read from the makefile, so pop the source block */ @@ -104,7 +104,7 @@ get_next_block_fn(register Source source) * Hopefully the kernel managed to prefetch the stuff. */ to_read = source->bytes_left_in_file; - source->inp_buf_ptr = source->inp_buf = getmem(to_read + 1); + source->inp_buf_ptr = source->inp_buf = getmem(to_read + 1); source->inp_buf_end = source->inp_buf + to_read; length = read(source->fd, source->inp_buf, (unsigned int) to_read); if (length != to_read) { @@ -139,7 +139,7 @@ get_next_block_fn(register Source source) break; } } - + if ((int) num_wc_chars == (size_t)-1) { source->error_converting = true; return source; diff --git a/usr/src/cmd/make/lib/vroot/report.cc b/usr/src/cmd/make/lib/vroot/report.cc index 9def773476..d022971f4b 100644 --- a/usr/src/cmd/make/lib/vroot/report.cc +++ b/usr/src/cmd/make/lib/vroot/report.cc @@ -122,7 +122,7 @@ close_file(void) /* If .nse_depinfo file doesn't exist */ if ((nse_depinfo_fp = fopen(nse_depinfo_file, "r+")) == NULL) { if (is_path) { - if ((nse_depinfo_fp = + if ((nse_depinfo_fp = fopen(nse_depinfo_file, "w")) == NULL) { fprintf(stderr, gettext("Cannot open `%s' for writing\n"), nse_depinfo_file); @@ -131,7 +131,7 @@ close_file(void) unlink(lock_file); return; } - while (fgets(line, MAXPATHLEN+2, command_output_fp) + while (fgets(line, MAXPATHLEN+2, command_output_fp) != NULL) { fprintf(nse_depinfo_fp, "%s", line); } @@ -155,7 +155,7 @@ close_file(void) len = strlen(sfile); while (fgets(line, MAXPATHLEN+2, nse_depinfo_fp) != NULL) { if (strncmp(line, sfile, len) == 0 && line[len] == ':') { - while (fgets(buf, MAXPATHLEN+2, command_output_fp) + while (fgets(buf, MAXPATHLEN+2, command_output_fp) != NULL) { if (is_path) { fprintf(merge_fp, "%s", buf); @@ -173,10 +173,10 @@ close_file(void) != NULL) { fputs(line, merge_fp); } - clean_up(nse_depinfo_fp, merge_fp, + clean_up(nse_depinfo_fp, merge_fp, nse_depinfo_file, merge_file, 0); } else { - clean_up(nse_depinfo_fp, merge_fp, + clean_up(nse_depinfo_fp, merge_fp, nse_depinfo_file, merge_file, 1); } if (file_locked) { @@ -186,7 +186,7 @@ close_file(void) return; } /* entry found */ fputs(line, merge_fp); - } + } /* Entry never found. Add it if there is a search path */ if (is_path) { while (fgets(line, MAXPATHLEN+2, command_output_fp) != NULL) { @@ -206,7 +206,7 @@ report_dep(char *iflag, char *filename) { if (command_output_fp == NULL) { - sprintf(command_output_tmpfile, + sprintf(command_output_tmpfile, "%s/%s.%d.XXXXXX", tmpdir, NSE_DEPINFO, getpid()); int fd = mkstemp(command_output_tmpfile); if ((fd < 0) || (command_output_fp = fdopen(fd, "w")) == NULL) { @@ -268,7 +268,7 @@ report_search_path(char *iflag) } sprintf(filename, "%s-CPP", ptr+1); getcwd(curdir, sizeof(curdir)); - if (strcmp(curdir, sdir) != 0 && strlen(iflag) > 2 && + if (strcmp(curdir, sdir) != 0 && strlen(iflag) > 2 && iflag[2] != '/') { /* Makefile must have had an "cd xx; cc ..." */ /* Modify the -I path to be relative to the cd */ @@ -283,10 +283,10 @@ report_search_path(char *iflag) void report_dependency(const char *name) { - register char *filename; + char *filename; char buffer[MAXPATHLEN+1]; - register char *p; - register char *p2; + char *p; + char *p2; char nse_depinfo_file[MAXPATHLEN]; if (report_file == NULL) { diff --git a/usr/src/cmd/make/lib/vroot/vroot.cc b/usr/src/cmd/make/lib/vroot/vroot.cc index 785a0bc638..cd61967e12 100644 --- a/usr/src/cmd/make/lib/vroot/vroot.cc +++ b/usr/src/cmd/make/lib/vroot/vroot.cc @@ -57,12 +57,12 @@ static vroot_datat vroot_data= { "", NULL, NULL, NULL, 0, 1}; void -add_dir_to_path(const char *path, register pathpt *pointer, register int position) +add_dir_to_path(const char *path, pathpt *pointer, int position) { - register int size= 0; - register int length; - register char *name; - register pathcellpt p; + int size= 0; + int length; + char *name; + pathcellpt p; pathpt new_path; if (*pointer != NULL) { @@ -88,9 +88,9 @@ add_dir_to_path(const char *path, register pathpt *pointer, register int positio } pathpt -parse_path_string(register char *string, register int remove_slash) +parse_path_string(char *string, int remove_slash) { - register char *p; + char *p; pathpt result= NULL; if (string != NULL) @@ -148,7 +148,7 @@ set_path_style(int style) } char * -get_vroot_path(register char **vroot, register char **path, register char **filename) +get_vroot_path(char **vroot, char **path, char **filename) { if (vroot != NULL) { if ((*vroot= vroot_data.vroot_start) == NULL) @@ -163,13 +163,13 @@ get_vroot_path(register char **vroot, register char **path, register char **file } void -translate_with_thunk(register char *filename, int (*thunk) (char *), pathpt path_vector, pathpt vroot_vector, rwt rw) +translate_with_thunk(char *filename, int (*thunk) (char *), pathpt path_vector, pathpt vroot_vector, rwt rw) { - register pathcellt *vp; - pathcellt *pp; - register pathcellt *pp1; - register char *p; - int flags[256]; + pathcellt *vp; + pathcellt *pp; + pathcellt *pp1; + char *p; + int flags[256]; /* Setup path to use */ if (rw == rw_write) diff --git a/usr/src/cmd/nvmeadm/nvmeadm.c b/usr/src/cmd/nvmeadm/nvmeadm.c index 80f63b0767..8aa55184cb 100644 --- a/usr/src/cmd/nvmeadm/nvmeadm.c +++ b/usr/src/cmd/nvmeadm/nvmeadm.c @@ -10,10 +10,9 @@ */ /* - * Copyright 2016 Nexenta Systems, Inc. * Copyright 2017 Joyent, Inc. - * Copyright 2019 Western Digital Corporation. * Copyright 2021 Oxide Computer Company + * Copyright 2022 Tintri by DDN, Inc. All rights reserved. */ /* @@ -28,8 +27,7 @@ * secure-erase ... * detach ... * attach ... - * get-param ... - * set-param ... + * list-firmware ... * load-firmware ... * commit-firmware ... * activate-firmware ... @@ -110,6 +108,7 @@ static void usage_get_features(const char *); static void usage_format(const char *); static void usage_secure_erase(const char *); static void usage_attach_detach(const char *); +static void usage_firmware_list(const char *); static void usage_firmware_load(const char *); static void usage_firmware_commit(const char *); static void usage_firmware_activate(const char *); @@ -169,6 +168,12 @@ static const nvmeadm_cmd_t nvmeadm_cmds[] = { do_attach_detach, usage_attach_detach, B_FALSE }, { + "list-firmware", + "list firmware on a controller", + NULL, + do_get_logpage_fwslot, usage_firmware_list, B_FALSE + }, + { "load-firmware", "load firmware to a controller", NULL, @@ -722,6 +727,14 @@ usage_get_logpage(const char *c_name) "are error, health, and firmware.\n", c_name); } +static void +usage_firmware_list(const char *c_name) +{ + (void) fprintf(stderr, "%s <ctl>\n\n" + " Print the log page that contains the list of firmware " + "images installed on the specified NVMe controller.\n", c_name); +} + static int do_get_logpage_error(int fd, const nvme_process_arg_t *npa) { @@ -788,7 +801,7 @@ do_get_logpage_fwslot(int fd, const nvme_process_arg_t *npa) return (-1); (void) printf("%s: ", npa->npa_name); - nvme_print_fwslot_log(fwlog); + nvme_print_fwslot_log(fwlog, npa->npa_idctl); free(fwlog); @@ -1314,6 +1327,7 @@ do_firmware_load(int fd, const nvme_process_arg_t *npa) ssize_t len; offset_t offset = 0; size_t size; + uint16_t sc; char buf[FIRMWARE_READ_BLKSIZE]; if (npa->npa_argc > 2) @@ -1323,6 +1337,10 @@ do_firmware_load(int fd, const nvme_process_arg_t *npa) errx(-1, "Requires firmware file name, and an " "optional offset"); + if (npa->npa_isns) + errx(-1, "Firmware loading not available on a per-namespace " + "basis"); + if (npa->npa_argc == 2) offset = get_fw_offsetb(npa->npa_argv[1]); @@ -1342,9 +1360,9 @@ do_firmware_load(int fd, const nvme_process_arg_t *npa) if (len == 0) break; - if (!nvme_firmware_load(fd, buf, len, offset)) + if (!nvme_firmware_load(fd, buf, len, offset, &sc)) errx(-1, "Error loading \"%s\": %s", npa->npa_argv[0], - strerror(errno)); + nvme_fw_error(errno, sc)); offset += len; size += len; @@ -1390,7 +1408,7 @@ static int do_firmware_commit(int fd, const nvme_process_arg_t *npa) { uint_t slot; - uint16_t sct, sc; + uint16_t sc; if (npa->npa_argc > 1) errx(-1, "Too many arguments"); @@ -1398,11 +1416,18 @@ do_firmware_commit(int fd, const nvme_process_arg_t *npa) if (npa->npa_argc == 0) errx(-1, "Firmware slot number is required"); + if (npa->npa_isns) + errx(-1, "Firmware committing not available on a per-namespace " + "basis"); + slot = get_slot_number(npa->npa_argv[0]); - if (!nvme_firmware_commit(fd, slot, NVME_FWC_SAVE, &sct, &sc)) + if (slot == 1 && npa->npa_idctl->id_frmw.fw_readonly) + errx(-1, "Cannot commit firmware to slot 1: slot is read-only"); + + if (!nvme_firmware_commit(fd, slot, NVME_FWC_SAVE, &sc)) errx(-1, "Failed to commit firmware to slot %u: %s", - slot, nvme_str_error(sct, sc)); + slot, nvme_fw_error(errno, sc)); if (verbose) (void) printf("Firmware committed to slot %u.\n", slot); @@ -1423,7 +1448,7 @@ static int do_firmware_activate(int fd, const nvme_process_arg_t *npa) { uint_t slot; - uint16_t sct, sc; + uint16_t sc; if (npa->npa_argc > 1) errx(-1, "Too many arguments"); @@ -1431,15 +1456,19 @@ do_firmware_activate(int fd, const nvme_process_arg_t *npa) if (npa->npa_argc == 0) errx(-1, "Firmware slot number is required"); + if (npa->npa_isns) + errx(-1, "Firmware activation not available on a per-namespace " + "basis"); + slot = get_slot_number(npa->npa_argv[0]); - if (!nvme_firmware_commit(fd, slot, NVME_FWC_ACTIVATE, &sct, &sc)) + if (!nvme_firmware_commit(fd, slot, NVME_FWC_ACTIVATE, &sc)) errx(-1, "Failed to activate slot %u: %s", slot, - nvme_str_error(sct, sc)); + nvme_fw_error(errno, sc)); if (verbose) printf("Slot %u activated: %s.\n", slot, - nvme_str_error(sct, sc)); + nvme_fw_error(errno, sc)); return (0); } diff --git a/usr/src/cmd/nvmeadm/nvmeadm.h b/usr/src/cmd/nvmeadm/nvmeadm.h index ff6a21c87f..6b620f8fab 100644 --- a/usr/src/cmd/nvmeadm/nvmeadm.h +++ b/usr/src/cmd/nvmeadm/nvmeadm.h @@ -10,9 +10,8 @@ */ /* - * Copyright 2016 Nexenta Systems, Inc. - * Copyright 2019 Western Digital Corporation * Copyright 2021 Oxide Computer Company + * Copyright 2022 Tintri by DDN, Inc. All rights reserved. */ #ifndef _NVMEADM_H @@ -69,7 +68,7 @@ extern void nvme_print_error_log(int, nvme_error_log_entry_t *, nvme_version_t *); extern void nvme_print_health_log(nvme_health_log_t *, nvme_identify_ctrl_t *, nvme_version_t *); -extern void nvme_print_fwslot_log(nvme_fwslot_log_t *); +extern void nvme_print_fwslot_log(nvme_fwslot_log_t *, nvme_identify_ctrl_t *); extern void nvme_print_feat_arbitration(uint64_t, void *, size_t, nvme_identify_ctrl_t *, nvme_version_t *); @@ -97,7 +96,7 @@ extern void nvme_print_feat_auto_pst(uint64_t, void *, size_t, nvme_identify_ctrl_t *, nvme_version_t *); extern void nvme_print_feat_progress(uint64_t, void *, size_t, nvme_identify_ctrl_t *, nvme_version_t *); -extern const char *nvme_str_error(int, int); +extern const char *nvme_fw_error(int, int); /* device node functions */ extern int nvme_open(di_minor_t); @@ -113,8 +112,8 @@ extern int nvme_intr_cnt(int); extern boolean_t nvme_format_nvm(int, uint8_t, uint8_t); extern boolean_t nvme_detach(int); extern boolean_t nvme_attach(int); -extern boolean_t nvme_firmware_load(int, void *, size_t, offset_t); -extern boolean_t nvme_firmware_commit(int fd, int, int, uint16_t *, uint16_t *); +extern boolean_t nvme_firmware_load(int, void *, size_t, offset_t, uint16_t *); +extern boolean_t nvme_firmware_commit(int, int, int, uint16_t *); /* * ofmt related diff --git a/usr/src/cmd/nvmeadm/nvmeadm_dev.c b/usr/src/cmd/nvmeadm/nvmeadm_dev.c index fca609a320..1617de5da9 100644 --- a/usr/src/cmd/nvmeadm/nvmeadm_dev.c +++ b/usr/src/cmd/nvmeadm/nvmeadm_dev.c @@ -10,8 +10,7 @@ */ /* - * Copyright 2016 Nexenta Systems, Inc. - * Copyright 2019 Western Digital Corporation + * Copyright 2022 Tintri by DDN, Inc. All rights reserved. */ #include <sys/types.h> @@ -35,9 +34,6 @@ nvme_ioctl(int fd, int ioc, size_t *bufsize, void **buf, uint64_t arg, void *ptr = NULL; int ret; - if (res != NULL) - *res = ~0ULL; - if (bufsize != NULL && *bufsize != 0) { assert(buf != NULL); @@ -62,6 +58,13 @@ nvme_ioctl(int fd, int ioc, size_t *bufsize, void **buf, uint64_t arg, *res = nioc.n_arg; if (ret != 0) { + /* + * We're not clearing *res here as there may be cases where + * we get an error _and_ we have interesting information in + * returned in *res that callers of this functions might be + * interested in. + */ + if (debug) warn("nvme_ioctl()"); if (ptr != NULL) @@ -178,14 +181,28 @@ nvme_attach(int fd) } boolean_t -nvme_firmware_load(int fd, void *buf, size_t len, offset_t offset) +nvme_firmware_load(int fd, void *buf, size_t len, offset_t offset, uint16_t *sc) { - return (nvme_ioctl(fd, NVME_IOC_FIRMWARE_DOWNLOAD, &len, &buf, offset, - NULL)); + boolean_t rv; + uint64_t res; + + rv = nvme_ioctl(fd, NVME_IOC_FIRMWARE_DOWNLOAD, &len, &buf, offset, + &res); + + /* + * If the hardware returned a command-specific status code, we'll get + * it as a negative value from the driver. + */ + if ((int64_t)res < 0) + *sc = (uint16_t)-(int64_t)res; + else + *sc = 0; + + return (rv); } boolean_t -nvme_firmware_commit(int fd, int slot, int action, uint16_t *sct, uint16_t *sc) +nvme_firmware_commit(int fd, int slot, int action, uint16_t *sc) { boolean_t rv; uint64_t res; @@ -193,10 +210,14 @@ nvme_firmware_commit(int fd, int slot, int action, uint16_t *sct, uint16_t *sc) rv = nvme_ioctl(fd, NVME_IOC_FIRMWARE_COMMIT, NULL, NULL, ((uint64_t)action << 32) | slot, &res); - if (sct != NULL) - *sct = (uint16_t)(res >> 16); - if (sc != NULL) - *sc = (uint16_t)res; + /* + * If the hardware returned a command-specific status code, we'll get + * it as a negative value from the driver. + */ + if ((int64_t)res < 0) + *sc = (uint16_t)-(int64_t)res; + else + *sc = 0; return (rv); } diff --git a/usr/src/cmd/nvmeadm/nvmeadm_print.c b/usr/src/cmd/nvmeadm/nvmeadm_print.c index 9190131566..43c15925b2 100644 --- a/usr/src/cmd/nvmeadm/nvmeadm_print.c +++ b/usr/src/cmd/nvmeadm/nvmeadm_print.c @@ -10,9 +10,9 @@ */ /* - * Copyright 2016 Nexenta Systems, Inc. - * Copyright 2019 Western Digital Corporation * Copyright 2021 Oxide Computer Company + * Copyright 2022 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2022 Tintri by DDN, Inc. All rights reserved. */ /* @@ -1909,17 +1909,25 @@ nvme_print_health_log(nvme_health_log_t *hlog, nvme_identify_ctrl_t *idctl, * This function pretty-prints the firmware slot information. */ void -nvme_print_fwslot_log(nvme_fwslot_log_t *fwlog) +nvme_print_fwslot_log(nvme_fwslot_log_t *fwlog, nvme_identify_ctrl_t *idctl) { int i; + char str[NVME_FWVER_SZ + sizeof (" (read-only)")]; + nvme_print(0, "Firmware Slot Information", -1, NULL); nvme_print_uint64(2, "Active Firmware Slot", fwlog->fw_afi, NULL, NULL); if (fwlog->fw_next != 0) nvme_print_uint64(2, "Next Firmware Slot", fwlog->fw_next, NULL, NULL); - for (i = 0; i != ARRAYSIZE(fwlog->fw_frs); i++) { + + (void) snprintf(str, sizeof (str), "%.*s%s", + nvme_strlen(fwlog->fw_frs[0], sizeof (fwlog->fw_frs[0])), + fwlog->fw_frs[0], idctl->id_frmw.fw_readonly ? " (read-only)" : ""); + nvme_print_str(2, "Firmware Revision for Slot", 1, str, sizeof (str)); + + for (i = 1; i < idctl->id_frmw.fw_nslot; i++) { nvme_print_str(2, "Firmware Revision for Slot", i + 1, fwlog->fw_frs[i][0] == '\0' ? "<Unused>" : fwlog->fw_frs[i], sizeof (fwlog->fw_frs[i])); @@ -2166,6 +2174,34 @@ nvme_print_feat_async_event(uint64_t res, void *b, size_t s, nvme_version_check(version, 1, 0), aec.b.aec_volatile, "enabled", "disabled"); } + + /* NVMe 1.2 */ + nvme_print_bit(4, "Namespace attribute notices", + nvme_version_check(version, 1, 2), + aec.b.aec_nsan, "enabled", "disabled"); + nvme_print_bit(4, "Firmware activation notices", + nvme_version_check(version, 1, 2), + aec.b.aec_fwact, "enabled", "disabled"); + + /* NVMe 1.3 */ + nvme_print_bit(4, "Telemetry log notices", + nvme_version_check(version, 1, 3), + aec.b.aec_telln, "enabled", "disabled"); + + /* NVMe 1.4 */ + nvme_print_bit(4, "ANA change notices", + nvme_version_check(version, 1, 4), + aec.b.aec_ansacn, "enabled", "disabled"); + nvme_print_bit(4, + "Predictable latency event aggr. LCNs", + nvme_version_check(version, 1, 4), + aec.b.aec_plat, "enabled", "disabled"); + nvme_print_bit(4, "LBA status information notices", + nvme_version_check(version, 1, 4), + aec.b.aec_lbasi, "enabled", "disabled"); + nvme_print_bit(4, "Endurance group event aggregate LCNs", + nvme_version_check(version, 1, 4), + aec.b.aec_egeal, "enabled", "disabled"); } void @@ -2214,21 +2250,12 @@ nvme_print_feat_progress(uint64_t res, void *b, size_t s, spm.b.spm_pbslc, NULL, NULL); } -static const char * -nvme_str_generic_error(int sc) +const char * +nvme_fw_error(int err, int sc) { - switch (sc) { - case NVME_CQE_SC_GEN_SUCCESS: - return ("Success"); - default: - return ("See message log (usually /var/adm/messages) " - "for details"); - } -} + if (sc == 0) + return (strerror(err)); -static const char * -nvme_str_specific_error(int sc) -{ switch (sc) { case NVME_CQE_SC_SPC_INV_FW_SLOT: return ("Invalid firmware slot"); @@ -2250,20 +2277,5 @@ nvme_str_specific_error(int sc) return ("See message log (usually /var/adm/messages) " "for details"); } -} -const char * -nvme_str_error(int sct, int sc) -{ - switch (sct) { - case NVME_CQE_SCT_GENERIC: - return (nvme_str_generic_error(sc)); - - case NVME_CQE_SCT_SPECIFIC: - return (nvme_str_specific_error(sc)); - - default: - return ("See message log (usually /var/adm/messages) " - "for details"); - } } diff --git a/usr/src/cmd/pcieadm/pcieadm_cfgspace.c b/usr/src/cmd/pcieadm/pcieadm_cfgspace.c index 1f4a5daf48..73841d4c23 100644 --- a/usr/src/cmd/pcieadm/pcieadm_cfgspace.c +++ b/usr/src/cmd/pcieadm/pcieadm_cfgspace.c @@ -10,7 +10,7 @@ */ /* - * Copyright 2021 Oxide Computer Company + * Copyright 2022 Oxide Computer Company */ /* @@ -499,6 +499,7 @@ pcieadm_cfgspace_print_regdef(pcieadm_cfgspace_walk_t *walkp, if (strval == NULL) { strval = "reserved"; } + pcieadm_field_printf(walkp, regdef->prd_short, regdef->prd_human, regval, "%s (0x%" PRIx64 ")\n", strval, regval << regdef->prd_lowbit); @@ -1171,9 +1172,9 @@ static pcieadm_regdef_t pcieadm_regdef_msictrl[] = { .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, { 8, 8, "pvm", "Per-Vector Masking Capable", PRDV_STRVAL, .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, - { 9, 9, "extmdcap", "Extended Message Data Capable", + { 9, 9, "extmdcap", "Extended Message Data Capable", PRDV_STRVAL, .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, - { 10, 10, "extmden", "extended Message Data Enable", + { 10, 10, "extmden", "extended Message Data Enable", PRDV_STRVAL, .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, { -1, -1, NULL } }; @@ -1438,17 +1439,19 @@ static pcieadm_regdef_t pcieadm_regdef_pcie_linkctl[] = { { 5, 5, "retrain", "Retrain Link", PRDV_HEX }, { 6, 6, "ccc", "Common Clock Configuration", PRDV_STRVAL, .prd_val = { .prdv_strval = { "asynchronous", "common" } } }, - { 7, 7, "extsync", "Extended Sync", PRDV_HEX, + { 7, 7, "extsync", "Extended Sync", PRDV_STRVAL, .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, - { 8, 8, "clkpm", "Clock Power Management", PRDV_HEX, + { 8, 8, "clkpm", "Clock Power Management", PRDV_STRVAL, .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, - { 9, 9, "hwawd", "Hardware Autonomous Width", PRDV_HEX, + { 9, 9, "hwawd", "Hardware Autonomous Width", PRDV_STRVAL, .prd_val = { .prdv_strval = { "enabled", "disabled" } } }, - { 10, 10, "linkbwint", "Link Bandwidth Management Interrupt", PRDV_HEX, - .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, - { 11, 11, "linkabwint", "Link Autonomous Bandwidth Interrupt", PRDV_HEX, - .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, - { 14, 15, "drs", "DRS Signaling Control", PRDV_HEX, + { 10, 10, "linkbwint", "Link Bandwidth Management Interrupt", + PRDV_STRVAL, .prd_val = { .prdv_strval = { "disabled", + "enabled" } } }, + { 11, 11, "linkabwint", "Link Autonomous Bandwidth Interrupt", + PRDV_STRVAL, .prd_val = { .prdv_strval = { "disabled", + "enabled" } } }, + { 14, 15, "drs", "DRS Signaling Control", PRDV_STRVAL, .prd_val = { .prdv_strval = { "not reported", "Interrupt enabled", "DRS->FRS enabled" } } }, { -1, -1, NULL } @@ -1489,9 +1492,9 @@ static pcieadm_regdef_t pcieadm_regdef_pcie_slotcap[] = { .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, { 7, 14, "slotplv", "Slot Power Limit Value", PRDV_HEX }, { 15, 16, "slotpls", "Slot Power Limit Scale", PRDV_HEX }, - { 17, 17, "emi", "Electromechanical Interlock Present", + { 17, 17, "emi", "Electromechanical Interlock Present", PRDV_STRVAL, .prd_val = { .prdv_strval = { "no", "yes" } } }, - { 18, 18, "ncc", "No Command Completed", PRDV_HEX, + { 18, 18, "ncc", "No Command Completed", PRDV_STRVAL, .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, { 19, 31, "slotno", "Physical Slot Number", PRDV_HEX }, { -1, -1, NULL } @@ -4264,6 +4267,91 @@ pcieadm_cap_info_ht(pcieadm_cfgspace_walk_t *walkp, } } +/* + * Root Complex Link Declaration + */ +static pcieadm_regdef_t pcieadm_regdef_rcld_desc[] = { + { 0, 3, "type", "Element Type", PRDV_STRVAL, + .prd_val = { .prdv_strval = { "Configuration Space Element", + "System Egress Port or internal sink", + "Internal Root Complex Link" } } }, + { 8, 15, "num", "Number of Entries", PRDV_HEX }, + { 16, 23, "id", "Component ID", PRDV_HEX }, + { 24, 31, "port", "Port Number", PRDV_HEX }, + { -1, -1, NULL } +}; + +static pcieadm_regdef_t pcieadm_regdef_rcld_link[] = { + { 0, 0, "valid", "Link Valid", PRDV_STRVAL, + .prd_val = { .prdv_strval = { "no", "yes" } } }, + { 1, 1, "type", "Link Type", PRDV_STRVAL, + .prd_val = { .prdv_strval = { "RCRB", "Configuration Space" } } }, + { 2, 2, "rcrb", "Assosciate RCRB", PRDV_STRVAL, + .prd_val = { .prdv_strval = { "no", "yes" } } }, + { 16, 23, "tid", "Target Component ID", PRDV_HEX }, + { 24, 31, "tport", "Target Port Number", PRDV_HEX }, + { -1, -1, NULL } +}; + +/* + * Print a variable number of Root Complex Links. + */ +static void +pcieadm_cfgspace_print_rcld(pcieadm_cfgspace_walk_t *walkp, + pcieadm_cfgspace_print_t *print, void *arg) +{ + uint_t nlinks = walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 5]; + + for (uint_t i = 0; i < nlinks; i++) { + char mshort[32], mhuman[128]; + pcieadm_cfgspace_print_t p; + uint16_t off = print->pcp_off + i * 0x10; + uint8_t type = walkp->pcw_data->pcb_u8[walkp->pcw_capoff + off]; + + (void) snprintf(mshort, sizeof (mshort), "link%udesc", i); + (void) snprintf(mhuman, sizeof (mhuman), "Link %u Description"); + + p.pcp_off = off; + p.pcp_len = 4; + p.pcp_short = mshort; + p.pcp_human = mhuman; + p.pcp_print = pcieadm_cfgspace_print_regdef; + p.pcp_arg = pcieadm_regdef_rcld_link; + + p.pcp_print(walkp, &p, p.pcp_arg); + + /* + * The way that we print the link depends on the actual type of + * link which is in bit 2 of the link description. + */ + p.pcp_off += 8; + + if ((type & (1 << 1)) == 0) { + (void) snprintf(mshort, sizeof (mshort), + "link%uaddr", i); + (void) snprintf(mhuman, sizeof (mhuman), + "Link %u Address"); + p.pcp_len = 8; + p.pcp_print = pcieadm_cfgspace_print_hex; + p.pcp_arg = NULL; + + p.pcp_print(walkp, &p, p.pcp_arg); + } else { + warnx("encountered unsupported RCLD Link Address"); + } + } +} + +static pcieadm_cfgspace_print_t pcieadm_cap_rcld[] = { + { 0x0, 4, "caphdr", "Capability Header", + pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr }, + { 0x4, 4, "desc", "Self Description", + pcieadm_cfgspace_print_regdef, pcieadm_regdef_rcld_desc }, + { 0x10, 0x10, "link", "Link Entry", pcieadm_cfgspace_print_rcld }, + { -1, -1, NULL } +}; + + pcieadm_pci_cap_t pcieadm_pci_caps[] = { { PCI_CAP_ID_PM, "pcipm", "PCI Power Management", pcieadm_cap_info_pcipm, { { 2, 8, pcieadm_cap_pcipm_v3 }, @@ -4316,7 +4404,8 @@ pcieadm_pci_cap_t pcieadm_pcie_caps[] = { { PCIE_EXT_CAP_ID_PWR_BUDGET, "powbudg", "Power Budgeting", pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_powbudg } } }, { PCIE_EXT_CAP_ID_RC_LINK_DECL, "rcld", - "Root Complex Link Declaration" }, + "Root Complex Link Declaration", pcieadm_cap_info_vers, + { { 1, 0x1c, pcieadm_cap_rcld } } }, { PCIE_EXT_CAP_ID_RC_INT_LINKCTRL, "rcilc", "Root Complex Internal Link Control" }, { PCIE_EXT_CAP_ID_RC_EVNT_CEA, "rcecea", diff --git a/usr/src/cmd/pcieadm/pcieadm_devs.c b/usr/src/cmd/pcieadm/pcieadm_devs.c index dc157d8d2a..2459662c1a 100644 --- a/usr/src/cmd/pcieadm/pcieadm_devs.c +++ b/usr/src/cmd/pcieadm/pcieadm_devs.c @@ -10,7 +10,7 @@ */ /* - * Copyright 2021 Oxide Computer Company + * Copyright 2022 Oxide Computer Company */ #include <err.h> @@ -28,6 +28,7 @@ typedef struct pcieadm_show_devs { boolean_t psd_funcs; int psd_nfilts; char **psd_filts; + boolean_t *psd_used; uint_t psd_nprint; } pcieadm_show_devs_t; @@ -291,20 +292,24 @@ pcieadm_show_devs_match(pcieadm_show_devs_t *psd, const char *filt = psd->psd_filts[i]; if (strcmp(filt, psdo->psdo_path) == 0) { + psd->psd_used[i] = B_TRUE; return (B_TRUE); } if (strcmp(filt, bdf) == 0) { + psd->psd_used[i] = B_TRUE; return (B_TRUE); } if (psdo->psdo_driver != NULL && strcmp(filt, psdo->psdo_driver) == 0) { + psd->psd_used[i] = B_TRUE; return (B_TRUE); } if (psdo->psdo_driver != NULL && psdo->psdo_instance != -1 && strcmp(filt, dinst) == 0) { + psd->psd_used[i] = B_TRUE; return (B_TRUE); } @@ -313,6 +318,7 @@ pcieadm_show_devs_match(pcieadm_show_devs_t *psd, } if (strcmp(filt, psdo->psdo_path) == 0) { + psd->psd_used[i] = B_TRUE; return (B_TRUE); } } @@ -488,7 +494,7 @@ pcieadm_show_devs_help(const char *fmt, ...) int pcieadm_show_devs(pcieadm_t *pcip, int argc, char *argv[]) { - int c; + int c, ret; uint_t flags = 0; const char *fields = NULL; pcieadm_show_devs_t psd; @@ -557,6 +563,11 @@ pcieadm_show_devs(pcieadm_t *pcip, int argc, char *argv[]) if (argc > 0) { psd.psd_nfilts = argc; psd.psd_filts = argv; + psd.psd_used = calloc(argc, sizeof (boolean_t)); + if (psd.psd_used == NULL) { + err(EXIT_FAILURE, "failed to allocate filter tracking " + "memory"); + } } oferr = ofmt_open(fields, pcieadm_show_dev_ofmt, flags, 0, @@ -568,9 +579,18 @@ pcieadm_show_devs(pcieadm_t *pcip, int argc, char *argv[]) pcieadm_di_walk(pcip, &walk); - if (psd.psd_nprint > 0) { - return (EXIT_SUCCESS); - } else { - return (EXIT_FAILURE); + ret = EXIT_SUCCESS; + for (int i = 0; i < psd.psd_nfilts; i++) { + if (!psd.psd_used[i]) { + warnx("filter '%s' did not match any devices", + psd.psd_filts[i]); + ret = EXIT_FAILURE; + } } + + if (psd.psd_nprint == 0) { + ret = EXIT_FAILURE; + } + + return (ret); } diff --git a/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/LDAPAuthentication.rawhlp b/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/LDAPAuthentication.rawhlp index a2d86b8c9c..2951b9d9c5 100644 --- a/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/LDAPAuthentication.rawhlp +++ b/usr/src/cmd/print/printmgr/com/sun/admin/pm/client/raw-help/LDAPAuthentication.rawhlp @@ -45,7 +45,7 @@ different server name if appropriate. 2. Check the Distinguished Name (DN) for correctness. You may enter a different distinguished name of another user if appropriate. This may be the DN of any directory user who has permissions (directory update privileges) to -update printer entries in the LDAP directory for the current ldapclient (1M) +update printer entries in the LDAP directory for the current ldapclient(8) naming service (NS) domain. <p> @@ -84,7 +84,7 @@ server specified then the first one will be used. <p> The Print Manager always displays printer entries from the current -ldapclient (1M) server. If this is not the domain Master LDAP server then +ldapclient(8) server. If this is not the domain Master LDAP server then the list of printers displayed may <b>not</b> be the current list of printers, this is because the ldapclient replica server may not have been updated by the master server and so be out of sync with the master. Replica servers can have @@ -105,7 +105,7 @@ Users can use the ldap command line utilities (ldapadd (1) & ldapmodify (1)) to update printer entries in the directory, but this is not recommended. If these utilities are used then the user <b>must ensure</b> that the printer-name attribute value is unique within the ou=printers container. If it is not unique -the result of modifies done by the print manager (or lpset (1M)) may not be +the result of modifies done by the print manager (or lpset(8)) may not be predictable. <p> diff --git a/usr/src/cmd/ps/Makefile b/usr/src/cmd/ps/Makefile index d1b61c7874..50f4f0f390 100644 --- a/usr/src/cmd/ps/Makefile +++ b/usr/src/cmd/ps/Makefile @@ -29,44 +29,31 @@ OBJS=ps.o ucbps.o SRCS=$(OBJS:%.o=%.c) include ../Makefile.cmd +include ../Makefile.cmd.64 +include ../Makefile.ctf + +LDLIBS += -lproject XGETFLAGS += -a -x ps.xcl DCFILE= $(PROG).dc ROOTUCBPROG = $(ROOT)/usr/ucb/$(PROG) -ROOTUCBPROG32 = $(ROOT)/usr/ucb/$(MACH32)/$(PROG) -ROOTUCBPROG64 = $(ROOT)/usr/ucb/$(MACH64)/$(PROG) - -$(64ONLY)SUBDIRS= $(MACH) -$(BUILD64)SUBDIRS += $(MACH64) - -all := TARGET = all -install := TARGET = install -clean := TARGET = clean -clobber := TARGET = clobber -lint := TARGET = lint .KEEP_STATE: -all: $(SUBDIRS) +all: $(PROG) -clean clobber lint: $(SUBDIRS) +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) -install: $(SUBDIRS) - -$(RM) $(ROOTPROG) - -$(LN) $(ISAEXEC) $(ROOTPROG) +install: $(PROG) $(ROOTPROG) -$(RM) $(ROOTUCBPROG) - -$(LN) $(ISAEXEC) $(ROOTUCBPROG) - $(64ONLY)-$(RM) $(ROOTUCBPROG32) - $(64ONLY)-$(LN) $(ROOTPROG32) $(ROOTUCBPROG32) - $(BUILD64)-$(RM) $(ROOTUCBPROG64) - $(BUILD64)-$(LN) $(ROOTPROG64) $(ROOTUCBPROG64) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) + -$(LN) $(ROOTPROG) $(ROOTUCBPROG) -FRC: +clean: + $(RM) $(OBJS) $(DCFILE): $(PROG).c $(RM) $(DCFILE) diff --git a/usr/src/cmd/ps/Makefile.com b/usr/src/cmd/ps/Makefile.com deleted file mode 100644 index d9209ba95a..0000000000 --- a/usr/src/cmd/ps/Makefile.com +++ /dev/null @@ -1,54 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# Copyright (c) 2018, Joyent, Inc. - -PROG= ps - -OBJS= ps.o ucbps.o - -SRCS= $(OBJS:%.o=../%.c) - -include ../../Makefile.cmd - -CFLAGS += $(CCVERBOSE) -LDLIBS += -lproject - -# not linted -SMATCH=off - -.KEEP_STATE: - -%.o: ../%.c - $(COMPILE.c) $< - -$(PROG): $(OBJS) - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -clean: - $(RM) $(OBJS) - -lint: - $(LINT.c) $(SRCS) $(LDLIBS) diff --git a/usr/src/cmd/ps/amd64/Makefile b/usr/src/cmd/ps/amd64/Makefile deleted file mode 100644 index c33134f58c..0000000000 --- a/usr/src/cmd/ps/amd64/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com -include ../../Makefile.cmd.64 - -all: $(PROG) - -install: all $(ROOTPROG64) - -include ../../Makefile.targ diff --git a/usr/src/cmd/ps/i386/Makefile b/usr/src/cmd/ps/i386/Makefile deleted file mode 100644 index 3f3aa6352a..0000000000 --- a/usr/src/cmd/ps/i386/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 1998-2000 by Sun Microsystems, Inc. -# All rights reserved. -# -# cmd/ps/i386/Makefile -# - -include ../Makefile.com - -lint := LINTFLAGS = -x - -all: $(PROG) - -install: all $(ROOTPROG32) - -include ../../Makefile.targ diff --git a/usr/src/cmd/ps/sparcv9/Makefile b/usr/src/cmd/ps/sparcv9/Makefile deleted file mode 100644 index aaa2f3ee7a..0000000000 --- a/usr/src/cmd/ps/sparcv9/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ps/sparcv9/Makefile -# - -include ../Makefile.com -include ../../Makefile.cmd.64 - -CFLAGS64 += $(CCVERBOSE) - -lint := LINTFLAGS64 = -x -m64 - -all: $(PROG) - -install: all $(ROOTPROG64) - -include ../../Makefile.targ diff --git a/usr/src/cmd/ps/ucbps.c b/usr/src/cmd/ps/ucbps.c index 3110e95313..6abeb1baea 100644 --- a/usr/src/cmd/ps/ucbps.c +++ b/usr/src/cmd/ps/ucbps.c @@ -167,7 +167,6 @@ ucbmain(int argc, char **argv) struct dirent *dentp; char psname[100]; char asname[100]; - int pdlen; size_t len; (void) setlocale(LC_ALL, ""); @@ -391,21 +390,24 @@ ucbmain(int argc, char **argv) exit(1); } - (void) strcpy(psname, procdir); - pdlen = strlen(psname); - psname[pdlen++] = '/'; - /* for each active process --- */ while ((dentp = readdir(dirp)) != NULL) { int psfd; /* file descriptor for /proc/nnnnn/psinfo */ int asfd; /* file descriptor for /proc/nnnnn/as */ + int n; if (dentp->d_name[0] == '.') /* skip . and .. */ continue; - (void) strcpy(psname + pdlen, dentp->d_name); - (void) strcpy(asname, psname); - (void) strcat(psname, "/psinfo"); - (void) strcat(asname, "/as"); + n = snprintf(psname, sizeof (psname), "%s/%s/psinfo", + procdir, dentp->d_name); + if (n < 0 || n >= sizeof (psname)) + exit(1); + + n = snprintf(asname, sizeof (asname), "%s/%s/as", + procdir, dentp->d_name); + if (n < 0 || n >= sizeof (psname)) + exit(1); + retry: if ((psfd = open(psname, O_RDONLY)) == -1) continue; @@ -544,7 +546,7 @@ closeit: } static void -usage() /* print usage message and quit */ +usage(void) /* print usage message and quit */ { static char usage1[] = "ps [ -aceglnrSuUvwx ] [ -t term ] [ num ]"; diff --git a/usr/src/cmd/script/script.c b/usr/src/cmd/script/script.c index 313a35df8a..0e73a9fd9b 100644 --- a/usr/src/cmd/script/script.c +++ b/usr/src/cmd/script/script.c @@ -3,8 +3,8 @@ * Use is subject to license terms. */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ /* @@ -33,8 +33,8 @@ #include <sys/file.h> #include <errno.h> -int grantpt(); -int unlockpt(); +int grantpt(); +int unlockpt(); char *ptsname(); void doinput() __NORETURN; void dooutput(); @@ -42,13 +42,13 @@ void doshell(); void fixtty(); void fail(); void done() __NORETURN; -void getmaster(); -void getslave(); +void getmanager(); +void getsubsid(); char *shell; FILE *fscript; -int master; /* file descriptor for master pseudo-tty */ -int slave; /* file descriptor for slave pseudo-tty */ +int manager; /* file descriptor for manager pseudo-tty */ +int subsid; /* file descriptor for subsidiary pseudo-tty */ int child; int subchild; char *fname = "typescript"; @@ -59,7 +59,7 @@ struct termios b; struct winsize size; int lb; int l; -char *mptname = "/dev/ptmx"; /* master pseudo-tty device */ +char *mptname = "/dev/ptmx"; /* manager pseudo-tty device */ int aflg; @@ -103,7 +103,7 @@ main(int argc, char *argv[]) } setbuf(fscript, NULL); chown(fname, ruidt, gidt); - getmaster(); + getmanager(); printf(gettext("Script started, file is %s\n"), fname); fixtty(); @@ -146,7 +146,7 @@ doinput() break; } } - (void) write(master, ibuf, cc); + (void) write(manager, ibuf, cc); } done(); } @@ -157,7 +157,7 @@ sigwinch() struct winsize ws; if (ioctl(0, TIOCGWINSZ, &ws) == 0) - (void) ioctl(master, TIOCSWINSZ, &ws); + (void) ioctl(manager, TIOCSWINSZ, &ws); } #include <sys/wait.h> @@ -190,7 +190,7 @@ dooutput() strftime(tbuf, BUFSIZ, "%c", localtime(&tvec)); fprintf(fscript, gettext("Script started on %s\n"), tbuf); for (;;) { - cc = read(master, obuf, sizeof (obuf)); + cc = read(manager, obuf, sizeof (obuf)); if (cc <= 0) break; (void) write(1, obuf, cc); @@ -204,13 +204,13 @@ doshell() { setpgrp(); /* relinquish control terminal */ - getslave(); - (void) close(master); + getsubsid(); + (void) close(manager); (void) fclose(fscript); - (void) dup2(slave, 0); - (void) dup2(slave, 1); - (void) dup2(slave, 2); - (void) close(slave); + (void) dup2(subsid, 0); + (void) dup2(subsid, 1); + (void) dup2(subsid, 2); + (void) close(subsid); execl(shell, shell, "-i", (char *)0); perror(shell); fail(); @@ -249,7 +249,7 @@ done() strftime(tbuf, BUFSIZ, "%c", localtime(&tvec)); fprintf(fscript, gettext("\nscript done on %s\n"), tbuf); (void) fclose(fscript); - (void) close(master); + (void) close(manager); } else { (void) ioctl(0, TCSETSW, (char *)&b); printf(gettext("Script done, file is %s\n"), fname); @@ -258,11 +258,11 @@ done() } void -getmaster() +getmanager() { struct stat stb; - if ((master = open(mptname, O_RDWR)) >= 0) { /* a pseudo-tty is free */ + if ((manager = open(mptname, O_RDWR)) >= 0) { /* a pseudo-tty is free */ (void) ioctl(0, TCGETS, (char *)&b); (void) ioctl(0, TIOCGWINSZ, (char *)&size); return; @@ -274,21 +274,21 @@ getmaster() } void -getslave() +getsubsid() { - char *slavename; /* name of slave pseudo-tty */ - - grantpt(master); /* change permissions of slave */ - unlockpt(master); /* unlock slave */ - slavename = ptsname(master); /* get name of slave */ - slave = open(slavename, O_RDWR); /* open slave */ - if (slave < 0) { /* error on opening slave */ - perror(slavename); + char *subsidname; /* name of subsidiary pseudo-tty */ + + grantpt(manager); /* change permissions of subsidiary */ + unlockpt(manager); /* unlock subsidiary */ + subsidname = ptsname(manager); /* get name of subsidiary */ + subsid = open(subsidname, O_RDWR); /* open subsidiary */ + if (subsid < 0) { /* error opening subsidiary */ + perror(subsidname); fail(); } - ioctl(slave, I_PUSH, "ptem"); /* push pt hw emulation module */ - ioctl(slave, I_PUSH, "ldterm"); /* push line discipline */ + ioctl(subsid, I_PUSH, "ptem"); /* push pt hw emulation module */ + ioctl(subsid, I_PUSH, "ldterm"); /* push line discipline */ - (void) ioctl(slave, TCSETSF, (char *)&b); - (void) ioctl(slave, TIOCSWINSZ, (char *)&size); + (void) ioctl(subsid, TCSETSF, (char *)&b); + (void) ioctl(subsid, TIOCSWINSZ, (char *)&size); } diff --git a/usr/src/cmd/sgs/ar/common/ar.msg b/usr/src/cmd/sgs/ar/common/ar.msg index 6682ca42af..2c165d0afa 100644 --- a/usr/src/cmd/sgs/ar/common/ar.msg +++ b/usr/src/cmd/sgs/ar/common/ar.msg @@ -21,7 +21,7 @@ # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright 2021 Oxide Computer Company +# Copyright 2022 Oxide Computer Company # @ _START_ @@ -33,7 +33,7 @@ @ MSG_USAGE "usage: ar -d[-SvV] archive file ...\n \ ar -m[-abiSvV] [posname] archive file ...\n \ ar -p[-vV][-sS] archive [file ...]\n \ - ar -q[-cuvSV] [file ...]\n \ + ar -q[-csuvSV] [file ...]\n \ ar -r[-cuvSV] [-abi] [posname] [file ...]\n \ ar -s[-vV] archive\n \ ar -t[-vV][-sS] archive [file ...]\n \ @@ -56,6 +56,8 @@ included in archive or not\n" @ MSG_INTERNAL_02 "ar: internal header generation error\n" +@ MSG_BAD_CREATE "ar: failed to create %s: %s, is the path correct?\n" + @ MSG_SYS_OPEN "ar: cannot open %s: %s\n" @ MSG_SYS_CLOSE "ar: cannot close %s: %s\n" @ MSG_SYS_WRITE "ar: %s: cannot write: %s\n" diff --git a/usr/src/cmd/sgs/ar/common/file.c b/usr/src/cmd/sgs/ar/common/file.c index 77e91c5898..c729617132 100644 --- a/usr/src/cmd/sgs/ar/common/file.c +++ b/usr/src/cmd/sgs/ar/common/file.c @@ -21,6 +21,7 @@ /* * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company */ /* @@ -1187,7 +1188,8 @@ writefile(Cmd_info *cmd_info) ar_outfile.fd = open(ar_outfile.path, O_RDWR|O_CREAT|O_LARGEFILE, 0666); if (ar_outfile.fd == -1) { int err = errno; - (void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN), + (void) fprintf(stderr, new_archive ? + MSG_INTL(MSG_BAD_CREATE) : MSG_INTL(MSG_SYS_OPEN), ar_outfile.path, strerror(err)); exit(1); } diff --git a/usr/src/cmd/sgs/ar/common/main.c b/usr/src/cmd/sgs/ar/common/main.c index 3f918e15db..3b95560816 100644 --- a/usr/src/cmd/sgs/ar/common/main.c +++ b/usr/src/cmd/sgs/ar/common/main.c @@ -27,7 +27,7 @@ /* * Copyright (c) 2018, Joyent, Inc. - * Copyright 2021 Oxide Computer Company + * Copyright 2022 Oxide Computer Company */ #include "inc.h" @@ -141,7 +141,7 @@ main(int argc, char **argv, char *envp[]) boolean_t req_r = (cmd_info->opt_flgs & r_FLAG) && (cmd_info->opt_flgs & (a_FLAG | b_FLAG)); boolean_t req_s = (cmd_info->opt_flgs & s_FLAG) && - (cmd_info->opt_flgs & r_FLAG) == 0; + (cmd_info->opt_flgs & (r_FLAG | q_FLAG)) == 0; if (req_arg || req_r || req_s) { (void) fprintf(stderr, MSG_INTL(MSG_NOT_FOUND_AR), diff --git a/usr/src/cmd/sgs/lex/Makefile.com b/usr/src/cmd/sgs/lex/Makefile.com index c8100b1e3f..1b40639314 100644 --- a/usr/src/cmd/sgs/lex/Makefile.com +++ b/usr/src/cmd/sgs/lex/Makefile.com @@ -55,9 +55,8 @@ SRCDIR = ../common CSTD= $(CSTD_GNU99) +# unused labels in yaccpar CERRWARN += -_gcc=-Wno-unused-label -CERRWARN += $(CNOWARN_UNINIT) -CERRWARN += -_gcc=-Wno-parentheses # Override default source file derivation rule (in Makefile.lib) # from objects diff --git a/usr/src/cmd/sgs/lex/common/sub1.c b/usr/src/cmd/sgs/lex/common/sub1.c index f1d3fa601b..e63a55e34b 100644 --- a/usr/src/cmd/sgs/lex/common/sub1.c +++ b/usr/src/cmd/sgs/lex/common/sub1.c @@ -131,15 +131,16 @@ warning(char *s, ...) { va_list ap; - if (!eof) - if (!yyline) + if (!eof) { + if (!yyline) { (void) fprintf(errorf, "Command line: "); - else { + } else { (void) fprintf(errorf, !no_input ? "" : "\"%s\":", sargv[optind]); (void) fprintf(errorf, "line %d: ", yyline); } + } (void) fprintf(errorf, "Warning: "); va_start(ap, s); (void) vfprintf(errorf, s, ap); @@ -171,8 +172,8 @@ index(int a, CHR *s) int alpha(int c) { - return ('a' <= c && c <= 'z' || - 'A' <= c && c <= 'Z'); + return (('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z')); } int @@ -209,7 +210,7 @@ scopy(CHR *s, CHR *t) { CHR *i; i = t; - while (*i++ = *s++) + while ((*i++ = *s++) != 0) ; } @@ -494,7 +495,7 @@ cpycom(CHR *p) (void) putc(*t++, fout); } (void) putc('\n', fout); - while (c = gch()) { + while ((c = gch()) != 0) { while (c == '*') { (void) putc((char)c, fout); if ((c = gch()) == '/') { @@ -570,7 +571,7 @@ cpyact(void) goto swt; (void) putwc(c, fout); savline = yyline; - while (c = gch()) { + while ((c = gch()) != 0) { while (c == '*') { (void) putwc(c, fout); if ((c = gch()) == '/') { @@ -591,7 +592,7 @@ cpyact(void) case '"': /* character string */ mth = c; (void) putwc(c, fout); - while (c = gch()) { + while ((c = gch()) != 0) { if (c == '\\') { (void) putwc(c, fout); c = gch(); diff --git a/usr/src/cmd/sgs/lex/common/sub2.c b/usr/src/cmd/sgs/lex/common/sub2.c index 84ff4e4699..399503d7d9 100644 --- a/usr/src/cmd/sgs/lex/common/sub2.c +++ b/usr/src/cmd/sgs/lex/common/sub2.c @@ -462,9 +462,9 @@ nextstate(int s, int c) for (i = 0; i < num; i++) { curpos = *pos++; j = name[curpos]; - if ((!ISOPERATOR(j)) && j == c || - j == RSTR && c == right[curpos] || - j == RCCL && member(c, (CHR *) left[curpos])) { + if ((!ISOPERATOR(j) && j == c) || + (j == RSTR && c == right[curpos]) || + (j == RCCL && member(c, (CHR *) left[curpos]))) { f = foll[curpos]; number = *f; newpos = f+1; diff --git a/usr/src/cmd/sgs/lex/common/sub3.c b/usr/src/cmd/sgs/lex/common/sub3.c index 107881958d..4b9cea94ab 100644 --- a/usr/src/cmd/sgs/lex/common/sub3.c +++ b/usr/src/cmd/sgs/lex/common/sub3.c @@ -134,12 +134,13 @@ remch(wchar_t c) * Make sure no EUC chars are used in reg. exp. */ if (!handleeuc) { - if (!isascii(c)) + if (!isascii(c)) { if (iswprint(c)) warning( "Non-ASCII character '%wc' in pattern; use -w or -e lex option.", c); else warning( "Non-ASCII character of value %#x in pattern; use -w or -e lex option.", c); + } /* In any case, we don't need to construct ncgidtbl[]. */ return; } @@ -301,7 +302,7 @@ repbycgid(void) symbol[j] = FALSE; s = (CHR *) left[i]; - while (cc = *s++) { + while ((cc = *s++) != 0) { if (cc == RANGE) { int low, high, i; /* @@ -388,7 +389,7 @@ repbycgid(void) static void setsymbol(int i) { - if (i > sizeof (symbol)) + if (i > (int)sizeof (symbol)) error("setsymbol: (SYSERR) %d out of range", i); symbol[i] = TRUE; } diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg index 86d8d2e9f3..4184f8c1e3 100644 --- a/usr/src/cmd/sgs/libld/common/libld.msg +++ b/usr/src/cmd/sgs/libld/common/libld.msg @@ -88,7 +88,7 @@ \t\t\tspecify library for which this file is a filter\n" @ MSG_ARG_DETAIL_CG "\t[-G], [-shared]\n\ \t\t\tcreate a shared object\n" -@ MSG_ARG_DETAIL_H "\t[-h name], [--soname name]\n\ +@ MSG_ARG_DETAIL_H "\t[-h name], [-soname name]\n\ \t\t\tuse 'name' as internal shared object identifier\n" @ MSG_ARG_DETAIL_I "\t[-i]\t\tignore LD_LIBRARY_PATH setting\n" @ MSG_ARG_DETAIL_CI "\t[-I name]\tuse 'name' as path of interpreter\n" @@ -976,7 +976,7 @@ -z type=reloc)" @ MSG_MARG_RPATH "runpath option (-R, -rpath)" @ MSG_MARG_SO "shared object option (-G, -shared, -z type=shared)" -@ MSG_MARG_SONAME "soname option (-h, --soname)" +@ MSG_MARG_SONAME "soname option (-h, -soname)" @ MSG_MARG_STRIP "strip option (-s, --strip-all)" @ MSG_MARG_TYPE_KMOD "-z type=kmod" diff --git a/usr/src/cmd/sgs/tools/SUNWonld-README b/usr/src/cmd/sgs/tools/SUNWonld-README index 5429da0a1e..3e9f4432fc 100644 --- a/usr/src/cmd/sgs/tools/SUNWonld-README +++ b/usr/src/cmd/sgs/tools/SUNWonld-README @@ -1625,7 +1625,7 @@ Bugid Risk Synopsis -------------------------------------------------------------------------------- -------------- -Illumos +illumos -------------- Bugid Risk Synopsis ================================================================================ @@ -1686,3 +1686,4 @@ Bugid Risk Synopsis 14308 discard SHF_EXCLUDE sections when linking kernel modules 14319 ld shouldn't warn about SHF_EXCLUDE unknown sections 14401 elfdump should understand LLVM section types +4795 /usr/bin/ld manpage and help should indicate '-soname' not '--soname' diff --git a/usr/src/cmd/smbsrv/testoplock/tol_main.c b/usr/src/cmd/smbsrv/testoplock/tol_main.c index 126f3a17f5..5382802b82 100644 --- a/usr/src/cmd/smbsrv/testoplock/tol_main.c +++ b/usr/src/cmd/smbsrv/testoplock/tol_main.c @@ -12,6 +12,7 @@ /* * Copyright 2018 Nexenta Systems, Inc. All rights reserved. * Copyright 2019 Joyent, Inc. + * Copyright 2022 RackTop Systems, Inc. */ /* @@ -190,10 +191,18 @@ do_close(int fid) printf(" close fid %d already closed\n"); return; } + + smb_llist_enter(&node->n_ofile_list, RW_READER); + mutex_enter(&node->n_oplock.ol_mutex); + smb_oplock_break_CLOSE(ofile->f_node, ofile); smb_llist_remove(&node->n_ofile_list, ofile); node->n_open_count--; + + mutex_exit(&node->n_oplock.ol_mutex); + smb_llist_exit(&node->n_ofile_list); + ofile->f_refcnt--; bzero(ofile->TargetOplockKey, SMB_LEASE_KEY_SZ); @@ -331,6 +340,7 @@ do_brk_setinfo(int fid, char *arg2) static void do_move(int fid, char *arg2) { + smb_node_t *node = &test_node; smb_ofile_t *ofile = &ofile_array[fid]; smb_ofile_t *of2; int fid2; @@ -346,7 +356,12 @@ do_move(int fid, char *arg2) } of2 = &ofile_array[fid2]; + mutex_enter(&node->n_oplock.ol_mutex); + smb_oplock_move(&test_node, ofile, of2); + + mutex_exit(&node->n_oplock.ol_mutex); + printf(" move %d %d\n", fid, fid2); } @@ -384,6 +399,8 @@ main(int argc, char *argv[]) if (isatty(0)) prompt = "> "; + mutex_init(&node->n_mutex, NULL, MUTEX_DEFAULT, NULL); + smb_llist_constructor(&node->n_ofile_list, sizeof (smb_ofile_t), offsetof(smb_ofile_t, f_node_lnd)); diff --git a/usr/src/cmd/svc/milestone/network-routing-setup.xml b/usr/src/cmd/svc/milestone/network-routing-setup.xml index da16da8e4d..bc7560fa98 100644 --- a/usr/src/cmd/svc/milestone/network-routing-setup.xml +++ b/usr/src/cmd/svc/milestone/network-routing-setup.xml @@ -100,7 +100,7 @@ <instance name='default' enabled='true' > - <!-- Properties in this group are used by routeadm (1M) --> + <!-- Properties in this group are used by routeadm(8) --> <property_group name='routeadm' type='framework'> <stability value='Evolving' /> <!-- set if routeadm -e/d ipv4-routing is explicitly invoked --> diff --git a/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c b/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c index 4697128c90..82c296a669 100644 --- a/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c +++ b/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c @@ -22,6 +22,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + * Copyright 2022 OmniOS Community Edition (OmniOSce) Association. */ /* @@ -32,15 +33,15 @@ * * When a device is added to the system: * - * 1. Search for any vdevs whose devid matches that of the newly added + * 1. Search for any vdevs whose devid matches that of the newly added * device. * - * 2. If no vdevs are found, then search for any vdevs whose devfs path + * 2. If no vdevs are found, then search for any vdevs whose devfs path * matches that of the new device. * * 3. If no vdevs match by either method, then ignore the event. * - * 4. Attempt to online the device with a flag to indicate that it should + * 4. Attempt to online the device with a flag to indicate that it should * be unspared when resilvering completes. If this succeeds, then the * same device was inserted and we should continue normally. * @@ -319,11 +320,11 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data) * string. However, we allow substring matches in the following * cases: * - * <path>: This is a devpath, and the target is one - * of its children. + * <path>: This is a devpath, and the target is one + * of its children. * - * <path/> This is a devid for a whole disk, and - * the target is one of its children. + * <path/> This is a devid for a whole disk, and + * the target is one of its children. */ if (path[len] != '\0' && path[len] != ':' && path[len - 1] != '/') @@ -555,7 +556,7 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data) vdev_state_t newstate; nvlist_t *tgt; - syseventd_print(9, "zfsdle_vdev_online: searching for %s in pool %s\n", + syseventd_print(9, "%s: searching for %s in pool %s\n", __func__, devname, zpool_get_name(zhp)); if ((tgt = zpool_find_vdev_by_physpath(zhp, devname, @@ -568,6 +569,11 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data) verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk) == 0); + syseventd_print(9, "%s: " + "found %s in pool %s (wholedisk: %s)\n", __func__, + path, zpool_get_name(zhp), + wholedisk != 0 ? "true" : "false"); + (void) strlcpy(fullpath, path, sizeof (fullpath)); if (wholedisk) { fullpath[strlen(fullpath) - 2] = '\0'; @@ -581,12 +587,13 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data) } if (zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) { - syseventd_print(9, "zfsdle_vdev_online: setting device" - " device %s to ONLINE state in pool %s.\n", - fullpath, zpool_get_name(zhp)); - if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) + syseventd_print(9, "%s: " + "setting device %s to ONLINE state in pool %s.\n", + __func__, fullpath, zpool_get_name(zhp)); + if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) { (void) zpool_vdev_online(zhp, fullpath, 0, &newstate); + } } zpool_close(zhp); return (1); diff --git a/usr/src/cmd/truss/codes.c b/usr/src/cmd/truss/codes.c index fd6e02bad6..21460008d4 100644 --- a/usr/src/cmd/truss/codes.c +++ b/usr/src/cmd/truss/codes.c @@ -1502,8 +1502,8 @@ const struct ioc { { (uint_t)IPTUN_GET_6TO4RELAY, "IPTUN_GET_6TO4RELAY", NULL}, /* zcons ioctls */ - { (uint_t)ZC_HOLDSLAVE, "ZC_HOLDSLAVE", NULL }, - { (uint_t)ZC_RELEASESLAVE, "ZC_RELEASESLAVE", NULL }, + { (uint_t)ZC_HOLDSUBSID, "ZC_HOLDSUBSID", NULL }, + { (uint_t)ZC_RELEASESUBSID, "ZC_RELEASESUBSID", NULL }, /* hid ioctls - ('h' << 8) - hid.h */ { (uint_t)HIDIOCKMGDIRECT, "HIDIOCKMGDIRECT", NULL }, diff --git a/usr/src/cmd/ttymon/parms.h b/usr/src/cmd/ttymon/parms.h index b293eb45a2..9299147f7c 100644 --- a/usr/src/cmd/ttymon/parms.h +++ b/usr/src/cmd/ttymon/parms.h @@ -19,13 +19,12 @@ * * CDDL HEADER END */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.3 */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ +#ifndef _PARMS_H +#define _PARMS_H /* If running SVR3, #define both ATTSVR3 and ATTSV */ #define ATTSVR3 /* System V Release 3 */ @@ -155,8 +154,8 @@ #define DEFAULT_BAUDRATE "9600" /* */ /*define permission modes for the device */ -#define M_DEVICEMODE (mode_t) 0600 /* MASTER device mode */ -#define S_DEVICEMODE (mode_t) 0600 /* SLAVE device mode */ +#define M_DEVICEMODE (mode_t) 0600 /* manager device mode */ +#define S_DEVICEMODE (mode_t) 0600 /* subsidiary device mode */ #define R_DEVICEMODE (mode_t) 0600 /* default mode to restore */ /* NO_MODEM_CTRL - define this if you have very old hardware @@ -232,7 +231,7 @@ /* define USRSPOOLLOCKS if you like your lock files in /var/spool/locks * be sure other programs such as 'cu' and 'ct' know about this * - * WARNING: if you do not define USRSPOOLLOCKS, then $LOCK in + * WARNING: if you do not define USRSPOOLLOCKS, then $LOCK in * uudemon.cleanup must be changed. */ #define USRSPOOLLOCKS /* define to use /var/spool/locks for LCK files */ @@ -241,3 +240,5 @@ * this entails sleeping between reads at low baud rates. */ #define PKSPEEDUP /* */ + +#endif /* !_PARMS_H */ diff --git a/usr/src/cmd/varpd/Makefile b/usr/src/cmd/varpd/Makefile new file mode 100644 index 0000000000..4d9e29cd26 --- /dev/null +++ b/usr/src/cmd/varpd/Makefile @@ -0,0 +1,64 @@ +# +# 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 Joyent, Inc. +# + +PROG= varpd +OBJS = varpd.o +SRCS = $(OBJS:%.o=../%.c) +MANIFEST = varpd.xml +ROOTLIBVARPD = $(ROOTLIB)/varpd +ROOTLIBVARPDPROG= $(PROG:%=$(ROOTLIBVARPD)/%) + + +include ../Makefile.cmd +include ../Makefile.ctf + +ROOTMANIFESTDIR= $(ROOTSVCNETWORK) + +CLEANFILES += $(OBJS) +CPPFLAGS += -D_REENTRANT +CFLAGS += $(CCVERBOSE) +LDLIBS += -lvarpd -lumem -lscf +$(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG + +CSTD= $(CSTD_GNU99) + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) + +clean: + -$(RM) $(CLEANFILES) + +%.o: ../%.c + $(COMPILE.c) $< + $(POST_PROCESS_O) + +check: $(CHKMANIFEST) + +install: $(PROG) $(ROOTLIBVARPDPROG) $(ROOTMANIFEST) + +$(ROOTLIBVARPD): + $(INS.dir) + +$(ROOTLIBVARPD)/%: % $(ROOTLIBVARPD) + $(INS.file) + +FRC: + +include ../Makefile.targ diff --git a/usr/src/cmd/varpd/varpd.c b/usr/src/cmd/varpd/varpd.c new file mode 100644 index 0000000000..3eb969c371 --- /dev/null +++ b/usr/src/cmd/varpd/varpd.c @@ -0,0 +1,526 @@ +/* + * 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) 2021 Joyent, Inc. + */ + +/* + * virtual arp daemon -- varpd + * + * The virtual arp daemon is the user land counterpart to the overlay driver. To + * truly understand its purpose and how it fits into things, you should read the + * overlay big theory statement in uts/common/io/overlay/overlay.c. + * + * varpd's purpose it to provide a means for looking up the destination on the + * underlay network for a host on an overlay network and to also be a door + * server such that dladm(8) via libdladm can configure and get useful status + * information. The heavy lifting is all done by libvarpd and the various lookup + * plugins. + * + * When varpd first starts up, we take care of chdiring into /var/run/varpd, + * which is also where we create /var/run/varpd/varpd.door, our door server. + * After that we daemonize and only after we daemonize do we go ahead and load + * plugins. The reason that we don't load plugins before daemonizing is that + * they could very well be creating threads and thus lose them all. In general, + * we want to make things easier on our children and not require them to be + * fork safe. + * + * Once it's spun up, the main varpd thread sits in sigsuspend and really just + * hangs out waiting for something, libvarpd handles everything else. + */ + +#include <libvarpd.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <libgen.h> +#include <stdarg.h> +#include <stdlib.h> +#include <paths.h> +#include <limits.h> +#include <sys/corectl.h> +#include <signal.h> +#include <strings.h> +#include <sys/wait.h> +#include <unistd.h> +#include <thread.h> +#include <priv.h> +#include <libscf.h> + +#define VARPD_EXIT_REQUESTED SMF_EXIT_OK +#define VARPD_EXIT_FATAL SMF_EXIT_ERR_FATAL +#define VARPD_EXIT_USAGE SMF_EXIT_ERR_CONFIG + +#define VARPD_RUNDIR "/var/run/varpd" +#define VARPD_DEFAULT_DOOR "/var/run/varpd/varpd.door" + +#define VARPD_PG "varpd" +#define VARPD_PROP_INC "include_path" + +static varpd_handle_t *varpd_handle; +static const char *varpd_pname; +static volatile boolean_t varpd_exit = B_FALSE; + +/* + * Debug builds are automatically wired up for umem debugging. + */ +#ifdef DEBUG +const char * +_umem_debug_init() +{ + return ("default,verbose"); +} + +const char * +_umem_logging_init(void) +{ + return ("fail,contents"); +} +#endif /* DEBUG */ + +static void +varpd_vwarn(FILE *out, const char *fmt, va_list ap) +{ + int error = errno; + + (void) fprintf(out, "%s: ", varpd_pname); + (void) vfprintf(out, fmt, ap); + + if (fmt[strlen(fmt) - 1] != '\n') + (void) fprintf(out, ": %s\n", strerror(error)); +} + +static void +varpd_fatal(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + varpd_vwarn(stderr, fmt, ap); + va_end(ap); + + exit(VARPD_EXIT_FATAL); +} + +static void +varpd_dfatal(int dfd, const char *fmt, ...) +{ + int status = VARPD_EXIT_FATAL; + va_list ap; + + va_start(ap, fmt); + varpd_vwarn(stdout, fmt, ap); + va_end(ap); + + /* Take a single shot at this */ + (void) write(dfd, &status, sizeof (status)); + exit(status); +} + +/* ARGSUSED */ +static int +varpd_plugin_walk_cb(varpd_handle_t *vph, const char *name, void *unused) +{ + (void) printf("loaded %s!\n", name); + return (0); +} + +static int +varpd_dir_setup(void) +{ + int fd; + + if (mkdir(VARPD_RUNDIR, 0700) != 0) { + if (errno != EEXIST) + varpd_fatal("failed to create %s: %s", VARPD_RUNDIR, + strerror(errno)); + } + + fd = open(VARPD_RUNDIR, O_RDONLY); + if (fd < 0) + varpd_fatal("failed to open %s: %s", VARPD_RUNDIR, + strerror(errno)); + + if (fchown(fd, UID_NETADM, GID_NETADM) != 0) + varpd_fatal("failed to chown %s: %s\n", VARPD_RUNDIR, + strerror(errno)); + + return (fd); +} + +/* + * Because varpd is generally run under SMF, we opt to keep its stdout and + * stderr to be whatever our parent set them up to be. + */ +static void +varpd_fd_setup(void) +{ + int dupfd; + + closefrom(STDERR_FILENO + 1); + dupfd = open(_PATH_DEVNULL, O_RDONLY); + if (dupfd < 0) + varpd_fatal("failed to open %s: %s", _PATH_DEVNULL, + strerror(errno)); + if (dup2(dupfd, STDIN_FILENO) == -1) + varpd_fatal("failed to dup out stdin: %s", strerror(errno)); +} + +/* + * We borrow fmd's daemonization style. Basically, the parent waits for the + * child to successfully set up a door and recover all of the old configurations + * before we say that we're good to go. + */ +static int +varpd_daemonize(int dirfd) +{ + char path[PATH_MAX]; + struct rlimit rlim; + sigset_t set, oset; + int estatus, pfds[2]; + pid_t child; + priv_set_t *pset; + + /* + * Set a per-process core path to be inside of /var/run/varpd. Make sure + * that we aren't limited in our dump size. + */ + (void) snprintf(path, sizeof (path), + "/var/run/varpd/core.%s.%%p", varpd_pname); + (void) core_set_process_path(path, strlen(path) + 1, getpid()); + + rlim.rlim_cur = RLIM_INFINITY; + rlim.rlim_max = RLIM_INFINITY; + (void) setrlimit(RLIMIT_CORE, &rlim); + + /* + * Claim as many file descriptors as the system will let us. + */ + if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) { + rlim.rlim_cur = rlim.rlim_max; + (void) setrlimit(RLIMIT_NOFILE, &rlim); + } + + /* + * chdir /var/run/varpd + */ + if (fchdir(dirfd) != 0) + varpd_fatal("failed to chdir to %s", VARPD_RUNDIR); + + + /* + * At this point block all signals going in so we don't have the parent + * mistakingly exit when the child is running, but never block SIGABRT. + */ + if (sigfillset(&set) != 0) + abort(); + if (sigdelset(&set, SIGABRT) != 0) + abort(); + if (sigprocmask(SIG_BLOCK, &set, &oset) != 0) + abort(); + + /* + * Do the fork+setsid dance. + */ + if (pipe(pfds) != 0) + varpd_fatal("failed to create pipe for daemonizing"); + + if ((child = fork()) == -1) + varpd_fatal("failed to fork for daemonizing"); + + if (child != 0) { + /* We'll be exiting shortly, so allow for silent failure */ + (void) close(pfds[1]); + if (read(pfds[0], &estatus, sizeof (estatus)) == + sizeof (estatus)) + _exit(estatus); + + if (waitpid(child, &estatus, 0) == child && WIFEXITED(estatus)) + _exit(WEXITSTATUS(estatus)); + + _exit(VARPD_EXIT_FATAL); + } + + /* + * Drop privileges here. + * + * We should make sure we keep around PRIV_NET_PRIVADDR and + * PRIV_SYS_DLCONFIG, but drop everything else; however, keep basic + * privs and have our child drop them. + * + * We should also run as netadm:netadm and drop all of our groups. + */ + if (setgroups(0, NULL) != 0) + abort(); + if (setgid(GID_NETADM) == -1 || seteuid(UID_NETADM) == -1) + abort(); + if ((pset = priv_allocset()) == NULL) + abort(); + priv_basicset(pset); + if (priv_delset(pset, PRIV_PROC_EXEC) == -1 || + priv_delset(pset, PRIV_PROC_INFO) == -1 || + priv_delset(pset, PRIV_PROC_FORK) == -1 || + priv_delset(pset, PRIV_PROC_SESSION) == -1 || + priv_delset(pset, PRIV_FILE_LINK_ANY) == -1 || + priv_addset(pset, PRIV_SYS_DL_CONFIG) == -1 || + priv_addset(pset, PRIV_NET_PRIVADDR) == -1) { + abort(); + } + /* + * Remove privs from the permitted set. That will cause them to be + * removed from the effective set. We want to make sure that in the case + * of a vulnerability, something can't get back in here and wreak more + * havoc. But if we want non-basic privs in the effective set, we have + * to request them explicitly. + */ + if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) == -1) + abort(); + if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pset) == -1) + abort(); + + priv_freeset(pset); + + if (close(pfds[0]) != 0) + abort(); + if (setsid() == -1) + abort(); + if (sigprocmask(SIG_SETMASK, &oset, NULL) != 0) + abort(); + (void) umask(0022); + + return (pfds[1]); +} + +static int +varpd_setup_lookup_threads(void) +{ + int ret; + long i, ncpus = sysconf(_SC_NPROCESSORS_ONLN) * 2 + 1; + + if (ncpus <= 0) + abort(); + for (i = 0; i < ncpus; i++) { + thread_t thr; + + ret = thr_create(NULL, 0, libvarpd_overlay_lookup_run, + varpd_handle, THR_DETACHED | THR_DAEMON, &thr); + if (ret != 0) + return (ret); + } + + return (0); +} + +static void +varpd_cleanup(void) +{ + varpd_exit = B_TRUE; +} + +/* + * Load default information from SMF and apply any of if necessary. We recognize + * the following properties: + * + * varpd/include_path Treat these as a series of -i options. + * + * If we're not under SMF, just move on. + */ +static void +varpd_load_smf(int dfd) +{ + char *fmri, *inc; + scf_simple_prop_t *prop; + + if ((fmri = getenv("SMF_FMRI")) == NULL) + return; + + if ((prop = scf_simple_prop_get(NULL, fmri, VARPD_PG, + VARPD_PROP_INC)) == NULL) + return; + + while ((inc = scf_simple_prop_next_astring(prop)) != NULL) { + int err = libvarpd_plugin_load(varpd_handle, inc); + if (err != 0) { + varpd_dfatal(dfd, "failed to load from %s: %s\n", + inc, strerror(err)); + } + } + + scf_simple_prop_free(prop); +} + +/* + * There are a bunch of things we need to do to be a proper daemon here. + * + * o Ensure that /var/run/varpd exists or create it + * o make stdin /dev/null (stdout?) + * o Ensure any other fds that we somehow inherited are closed, eg. + * closefrom() + * o Properly daemonize + * o Mask all signals except sigabrt before creating our first door -- all + * other doors will inherit from that. + * o Have the main thread sigsuspend looking for most things that are + * actionable... + */ +int +main(int argc, char *argv[]) +{ + int err, c, dirfd, dfd, i; + const char *doorpath = VARPD_DEFAULT_DOOR; + sigset_t set; + struct sigaction act; + int nincpath = 0, nextincpath = 0; + char **incpath = NULL; + + varpd_pname = basename(argv[0]); + + /* + * We want to clean up our file descriptors before we do anything else + * as we can't assume that libvarpd won't open file descriptors, etc. + */ + varpd_fd_setup(); + + if ((err = libvarpd_create(&varpd_handle)) != 0) { + varpd_fatal("failed to open a libvarpd handle"); + return (1); + } + + while ((c = getopt(argc, argv, ":i:d:")) != -1) { + switch (c) { + case 'i': + if (nextincpath == nincpath) { + if (nincpath == 0) + nincpath = 16; + else + nincpath *= 2; + incpath = realloc(incpath, sizeof (char *) * + nincpath); + if (incpath == NULL) { + (void) fprintf(stderr, "failed to " + "allocate memory for the %dth " + "-I option: %s\n", nextincpath + 1, + strerror(errno)); + } + + } + incpath[nextincpath] = optarg; + nextincpath++; + break; + case 'd': + doorpath = optarg; + break; + default: + (void) fprintf(stderr, "unknown option: %c\n", c); + return (1); + } + } + + dirfd = varpd_dir_setup(); + + (void) libvarpd_plugin_walk(varpd_handle, varpd_plugin_walk_cb, NULL); + + dfd = varpd_daemonize(dirfd); + + /* + * Now that we're in the child, go ahead and load all of our plug-ins. + * We do this, in part, because these plug-ins may need threads of their + * own and fork won't preserve those and we'd rather the plug-ins don't + * have to learn about fork-handlers. + */ + for (i = 0; i < nextincpath; i++) { + err = libvarpd_plugin_load(varpd_handle, incpath[i]); + if (err != 0) { + varpd_dfatal(dfd, "failed to load from %s: %s\n", + incpath[i], strerror(err)); + } + } + + varpd_load_smf(dfd); + + if ((err = libvarpd_persist_enable(varpd_handle, VARPD_RUNDIR)) != 0) + varpd_dfatal(dfd, "failed to enable varpd persistence: %s\n", + strerror(err)); + + if ((err = libvarpd_persist_restore(varpd_handle)) != 0) + varpd_dfatal(dfd, "failed to enable varpd persistence: %s\n", + strerror(err)); + + /* + * The ur-door thread will inherit from this signal mask. So set it to + * what we want before doing anything else. In addition, so will our + * threads that handle varpd lookups. + */ + if (sigfillset(&set) != 0) + varpd_dfatal(dfd, "failed to fill a signal set..."); + + if (sigdelset(&set, SIGABRT) != 0) + varpd_dfatal(dfd, "failed to unmask SIGABRT"); + + if (sigprocmask(SIG_BLOCK, &set, NULL) != 0) + varpd_dfatal(dfd, "failed to set our door signal mask"); + + if ((err = varpd_setup_lookup_threads()) != 0) + varpd_dfatal(dfd, "failed to create lookup threads: %s\n", + strerror(err)); + + if ((err = libvarpd_door_server_create(varpd_handle, doorpath)) != 0) + varpd_dfatal(dfd, "failed to create door server at %s: %s\n", + doorpath, strerror(err)); + + /* + * At this point, finish up signal initialization and finally go ahead, + * notify the parent that we're okay, and enter the sigsuspend loop. + */ + bzero(&act, sizeof (struct sigaction)); + act.sa_handler = varpd_cleanup; + if (sigfillset(&act.sa_mask) != 0) + varpd_dfatal(dfd, "failed to fill sigaction mask"); + act.sa_flags = 0; + if (sigaction(SIGHUP, &act, NULL) != 0) + varpd_dfatal(dfd, "failed to register HUP handler"); + if (sigdelset(&set, SIGHUP) != 0) + varpd_dfatal(dfd, "failed to remove HUP from mask"); + if (sigaction(SIGQUIT, &act, NULL) != 0) + varpd_dfatal(dfd, "failed to register QUIT handler"); + if (sigdelset(&set, SIGQUIT) != 0) + varpd_dfatal(dfd, "failed to remove QUIT from mask"); + if (sigaction(SIGINT, &act, NULL) != 0) + varpd_dfatal(dfd, "failed to register INT handler"); + if (sigdelset(&set, SIGINT) != 0) + varpd_dfatal(dfd, "failed to remove INT from mask"); + if (sigaction(SIGTERM, &act, NULL) != 0) + varpd_dfatal(dfd, "failed to register TERM handler"); + if (sigdelset(&set, SIGTERM) != 0) + varpd_dfatal(dfd, "failed to remove TERM from mask"); + + err = 0; + (void) write(dfd, &err, sizeof (err)); + (void) close(dfd); + + for (;;) { + if (sigsuspend(&set) == -1) + if (errno == EFAULT) + abort(); + if (varpd_exit == B_TRUE) + break; + } + + libvarpd_door_server_destroy(varpd_handle); + libvarpd_destroy(varpd_handle); + + return (VARPD_EXIT_REQUESTED); +} diff --git a/usr/src/cmd/varpd/varpd.xml b/usr/src/cmd/varpd/varpd.xml new file mode 100644 index 0000000000..df7015a3d6 --- /dev/null +++ b/usr/src/cmd/varpd/varpd.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> +<!-- +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, Joyent, Inc. +--> + +<service_bundle type="manifest" name="illumos:varpd" > + + <service name="network/varpd" type="service" version="1" > + + <create_default_instance enabled="true" /> + + <single_instance/> + + <dependency name="varpd-network-physical" + grouping="require_all" + restart_on="none" + type="service"> + <service_fmri value="svc:/network/physical:default" /> + </dependency> + + <dependency name="varpd-device-local" + grouping="require_all" + restart_on="none" + type="service"> + <service_fmri value="svc:/system/device/local:default" /> + </dependency> + + <exec_method + type="method" + name="start" + exec="/usr/lib/varpd/varpd" + timeout_seconds="60" /> + + <exec_method + type="method" + name="stop" + exec=":kill" + timeout_seconds="10" /> + + <property_group name='varpd' type='application'> + <property name='include_path' type='astring'> + <astring_list> + <value_node value='/usr/lib/varpd'/> + </astring_list> + </property> + </property_group> + + <stability value='Unstable' /> + + <template> + <common_name> + <loctext xml:lang="C">virtual ARP daemon + </loctext> + </common_name> + </template> + </service> +</service_bundle> diff --git a/usr/src/cmd/vscan/vscand/vs_main.c b/usr/src/cmd/vscan/vscand/vs_main.c index bcc4a055ae..5e13bf5870 100644 --- a/usr/src/cmd/vscan/vscand/vs_main.c +++ b/usr/src/cmd/vscan/vscand/vs_main.c @@ -139,7 +139,7 @@ vscand_sig_handler(int sig) /* * main * - * main must return SMF return code (see smf_method (5)) if vscand + * main must return SMF return code (see smf_method(7)) if vscand * is invoked directly by smf (see manifest: vscan.xml) * Exit codes: SMF_EXIT_ERR_CONFIG - error * SMF_EXIT_ERR_FATAL - fatal error diff --git a/usr/src/cmd/zoneadmd/zcons.c b/usr/src/cmd/zoneadmd/zcons.c index 49a935c638..130b97d984 100644 --- a/usr/src/cmd/zoneadmd/zcons.c +++ b/usr/src/cmd/zoneadmd/zcons.c @@ -57,7 +57,7 @@ * | +-[Anchor]--+ * | | ptem | * V +-----------+ - * +---master---+---slave---+ + * +---manager--+-subsidiary+ * | | * | zcons driver | * | zonename="myzone" | @@ -71,7 +71,7 @@ * to online new instances of zcons as needed. Care is taken to * prune and manage these appropriately; see init_console_dev() and * destroy_console_dev(). The end result is the creation of the - * zcons(4D) instance and an open file descriptor to the master side. + * zcons(4D) instance and an open file descriptor to the manager side. * zcons instances are associated with zones via their zonename device * property. This the console instance to persist across reboots, * and while the zone is halted. @@ -79,7 +79,7 @@ * - Acting as a server for 'zlogin -C' instances. When zlogin -C is * run, zlogin connects to zoneadmd via unix domain socket. zoneadmd * functions as a two-way proxy for console I/O, relaying user input - * to the master side of the console, and relaying output from the + * to the manager side of the console, and relaying output from the * zone to the user. */ @@ -265,34 +265,35 @@ destroy_console_devs(zlog_t *zlogp) char conspath[MAXPATHLEN]; di_node_t root; struct cb_data cb; - int masterfd; - int slavefd; + int managerfd; + int subfd; /* - * Signal the master side to release its handle on the slave side by - * issuing a ZC_RELEASESLAVE ioctl. + * Signal the manager side to release its handle on the subsidiary side + * by issuing a ZC_RELEASESUBSID ioctl. */ (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s", - zone_name, ZCONS_MASTER_NAME); - if ((masterfd = open(conspath, O_RDWR | O_NOCTTY)) != -1) { + zone_name, ZCONS_MANAGER_NAME); + if ((managerfd = open(conspath, O_RDWR | O_NOCTTY)) != -1) { (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s", - zone_name, ZCONS_SLAVE_NAME); - if ((slavefd = open(conspath, O_RDWR | O_NOCTTY)) != -1) { - if (ioctl(masterfd, ZC_RELEASESLAVE, - (caddr_t)(intptr_t)slavefd) != 0) + zone_name, ZCONS_SUBSIDIARY_NAME); + if ((subfd = open(conspath, O_RDWR | O_NOCTTY)) != -1) { + if (ioctl(managerfd, ZC_RELEASESUBSID, + (caddr_t)(intptr_t)subfd) != 0) zerror(zlogp, B_TRUE, "WARNING: error while " - "releasing slave handle of zone console for" - " %s", zone_name); - (void) close(slavefd); + "releasing subsidiary handle of zone " + "console for %s", zone_name); + (void) close(subfd); } else { - zerror(zlogp, B_TRUE, "WARNING: could not open slave " - "side of zone console for %s to release slave " - "handle", zone_name); + zerror(zlogp, B_TRUE, "WARNING: could not open " + "subsidiary side of zone console for %s to " + "release subsidiary handle", zone_name); } - (void) close(masterfd); + (void) close(managerfd); } else { - zerror(zlogp, B_TRUE, "WARNING: could not open master side of " - "zone console for %s to release slave handle", zone_name); + zerror(zlogp, B_TRUE, "WARNING: could not open manager side of " + "zone console for %s to release subsidiary handle", + zone_name); } bzero(&cb, sizeof (cb)); @@ -323,8 +324,8 @@ destroy_console_devs(zlog_t *zlogp) * sanity checking, and are careful to reuse a console if one exists. * * Once the device is in the device tree, we kick devfsadm via di_init_devs() - * to ensure that the appropriate symlinks (to the master and slave console - * devices) are placed in /dev in the global zone. + * to ensure that the appropriate symlinks (to the manager and subsidiary + * console devices) are placed in /dev in the global zone. */ static int init_console_dev(zlog_t *zlogp) @@ -336,8 +337,8 @@ init_console_dev(zlog_t *zlogp) di_devlink_handle_t dl = NULL; int rv = -1; int ndevs; - int masterfd; - int slavefd; + int managerfd; + int subfd; int i; /* @@ -405,23 +406,26 @@ devlinks: } /* - * Open the master side of the console and issue the ZC_HOLDSLAVE ioctl, - * which will cause the master to retain a reference to the slave. - * This prevents ttymon from blowing through the slave's STREAMS anchor. + * Open the manager side of the console and issue the ZC_HOLDSUBSID + * ioctl, which will cause the manager to retain a reference to the + * subsidiary. This prevents ttymon from blowing through the + * subsidiary's STREAMS anchor. */ (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s", - zone_name, ZCONS_MASTER_NAME); - if ((masterfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) { - zerror(zlogp, B_TRUE, "ERROR: could not open master side of " - "zone console for %s to acquire slave handle", zone_name); + zone_name, ZCONS_MANAGER_NAME); + if ((managerfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) { + zerror(zlogp, B_TRUE, "ERROR: could not open manager side of " + "zone console for %s to acquire subsidiary handle", + zone_name); goto error; } (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s", - zone_name, ZCONS_SLAVE_NAME); - if ((slavefd = open(conspath, O_RDWR | O_NOCTTY)) == -1) { - zerror(zlogp, B_TRUE, "ERROR: could not open slave side of zone" - " console for %s to acquire slave handle", zone_name); - (void) close(masterfd); + zone_name, ZCONS_SUBSIDIARY_NAME); + if ((subfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) { + zerror(zlogp, B_TRUE, "ERROR: could not open subsidiary side " + "of zone console for %s to acquire subsidiary handle", + zone_name); + (void) close(managerfd); goto error; } /* @@ -430,7 +434,7 @@ devlinks: * 1 sec. and retry a few times before we fail to boot the zone. */ for (i = 0; i < 5; i++) { - if (ioctl(masterfd, ZC_HOLDSLAVE, (caddr_t)(intptr_t)slavefd) + if (ioctl(managerfd, ZC_HOLDSUBSID, (caddr_t)(intptr_t)subfd) == 0) { rv = 0; break; @@ -440,11 +444,11 @@ devlinks: (void) sleep(1); } if (rv != 0) - zerror(zlogp, B_TRUE, "ERROR: error while acquiring slave " - "handle of zone console for %s", zone_name); + zerror(zlogp, B_TRUE, "ERROR: error while acquiring " + "subsidiary handle of zone console for %s", zone_name); - (void) close(slavefd); - (void) close(masterfd); + (void) close(subfd); + (void) close(managerfd); error: if (ddef_hdl) @@ -700,7 +704,7 @@ test_client(int clifd) /* * This routine drives the console I/O loop. It polls for input from the - * master side of the console (output to the console), and from the client + * manager side of the console (output to the console), and from the client * (input from the console user). Additionally, it polls on the server fd, * and disconnects any clients that might try to hook up with the zone while * the console is in use. @@ -904,17 +908,17 @@ init_console(zlog_t *zlogp) void serve_console(zlog_t *zlogp) { - int masterfd; + int managerfd; zone_state_t zstate; char conspath[MAXPATHLEN]; (void) snprintf(conspath, sizeof (conspath), - "/dev/zcons/%s/%s", zone_name, ZCONS_MASTER_NAME); + "/dev/zcons/%s/%s", zone_name, ZCONS_MANAGER_NAME); for (;;) { - masterfd = open(conspath, O_RDWR|O_NONBLOCK|O_NOCTTY); - if (masterfd == -1) { - zerror(zlogp, B_TRUE, "failed to open console master"); + managerfd = open(conspath, O_RDWR|O_NONBLOCK|O_NOCTTY); + if (managerfd == -1) { + zerror(zlogp, B_TRUE, "failed to open console manager"); (void) mutex_lock(&lock); goto death; } @@ -926,14 +930,14 @@ serve_console(zlog_t *zlogp) * messages, we wouldn't be able to use read(2), as it fails * (EBADMSG) when a message with a control element is received. */ - if (ioctl(masterfd, I_SRDOPT, RNORM|RPROTDIS) == -1) { + if (ioctl(managerfd, I_SRDOPT, RNORM|RPROTDIS) == -1) { zerror(zlogp, B_TRUE, "failed to set options on " - "console master"); + "console manager"); (void) mutex_lock(&lock); goto death; } - do_console_io(zlogp, masterfd, serverfd); + do_console_io(zlogp, managerfd, serverfd); /* * We would prefer not to do this, but hostile zone processes @@ -942,7 +946,7 @@ serve_console(zlog_t *zlogp) * we dismantle the stream and reopen the console when we * take another lap. */ - (void) close(masterfd); + (void) close(managerfd); (void) mutex_lock(&lock); /* |
