diff options
Diffstat (limited to 'usr.sbin')
25 files changed, 42 insertions, 3474 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 51908818e550..90c23dc26cc5 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -56,7 +56,6 @@ SUBDIR= adduser \ nfsuserd \ nmtree \ nologin \ - nvmfd \ pciconf \ periodic \ pnfsdscopymr \ @@ -175,7 +174,6 @@ SUBDIR.${MK_NETGRAPH}+= flowctl SUBDIR.${MK_NETGRAPH}+= ngctl SUBDIR.${MK_NETGRAPH}+= nghook SUBDIR.${MK_NIS}+= rpc.yppasswdd -SUBDIR.${MK_NIS}+= rpc.ypupdated SUBDIR.${MK_NIS}+= rpc.ypxfrd SUBDIR.${MK_NIS}+= ypbind SUBDIR.${MK_NIS}+= ypldap diff --git a/usr.sbin/autofs/common.c b/usr.sbin/autofs/common.c index 18756752876c..6b98214162ae 100644 --- a/usr.sbin/autofs/common.c +++ b/usr.sbin/autofs/common.c @@ -149,7 +149,7 @@ create_directory(const char *path) error = mkdir(partial, 0755); if (error != 0 && errno != EEXIST) { log_warn("cannot create %s", partial); - return; + break; } } diff --git a/usr.sbin/bhyve/pci_xhci.c b/usr.sbin/bhyve/pci_xhci.c index 0871bbb87fe5..ff12e40359e2 100644 --- a/usr.sbin/bhyve/pci_xhci.c +++ b/usr.sbin/bhyve/pci_xhci.c @@ -406,7 +406,7 @@ pci_xhci_usbcmd_write(struct pci_xhci_softc *sc, uint32_t cmd) * XHCI 4.19.3 USB2 RxDetect->Polling, * USB3 Polling->U0 */ - if (dev->dev_ue->ue_usbver == 2) + if (dev->hci.hci_usbver == 2) port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_POLL); else @@ -2590,7 +2590,7 @@ pci_xhci_reset_port(struct pci_xhci_softc *sc, int portn, int warm) port->portsc |= XHCI_PS_PED | XHCI_PS_SPEED_SET(dev->hci.hci_speed); - if (warm && dev->dev_ue->ue_usbver == 3) { + if (warm && dev->hci.hci_usbver == 3) { port->portsc |= XHCI_PS_WRC; } @@ -2620,7 +2620,7 @@ pci_xhci_init_port(struct pci_xhci_softc *sc, int portn) port->portsc = XHCI_PS_CCS | /* connected */ XHCI_PS_PP; /* port power */ - if (dev->dev_ue->ue_usbver == 2) { + if (dev->hci.hci_usbver == 2) { port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_POLL) | XHCI_PS_SPEED_SET(dev->hci.hci_speed); } else { @@ -2785,8 +2785,8 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl) cookie = NULL; while ((name = nvlist_next(slots_nvl, &type, &cookie)) != NULL) { - if (usb2_port == ((sc->usb2_port_start) + XHCI_MAX_DEVS/2) || - usb3_port == ((sc->usb3_port_start) + XHCI_MAX_DEVS/2)) { + if (usb2_port == ((sc->usb2_port_start) + XHCI_MAX_DEVS / 2) || + usb3_port == ((sc->usb3_port_start) + XHCI_MAX_DEVS / 2)) { WPRINTF(("pci_xhci max number of USB 2 or 3 " "devices reached, max %d", XHCI_MAX_DEVS/2)); goto bad; @@ -2834,12 +2834,25 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl) dev->hci.hci_intr = pci_xhci_dev_intr; dev->hci.hci_event = pci_xhci_dev_event; dev->hci.hci_speed = USB_SPEED_MAX; + dev->hci.hci_usbver = -1; - if (ue->ue_usbver == 2) { + devsc = ue->ue_probe(&dev->hci, nvl); + if (devsc == NULL) { + free(dev); + goto bad; + } + dev->dev_sc = devsc; + + if (dev->hci.hci_usbver == -1) + dev->hci.hci_usbver = ue->ue_usbver; + + if (dev->hci.hci_usbver == 2) { if (usb2_port == sc->usb2_port_start + XHCI_MAX_DEVS / 2) { WPRINTF(("pci_xhci max number of USB 2 devices " "reached, max %d", XHCI_MAX_DEVS / 2)); + free(dev->dev_sc); + free(dev); goto bad; } dev->hci.hci_port = usb2_port; @@ -2849,6 +2862,8 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl) XHCI_MAX_DEVS / 2) { WPRINTF(("pci_xhci max number of USB 3 devices " "reached, max %d", XHCI_MAX_DEVS / 2)); + free(dev->dev_sc); + free(dev); goto bad; } dev->hci.hci_port = usb3_port; @@ -2857,13 +2872,10 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl) XHCI_DEVINST_PTR(sc, dev->hci.hci_port) = dev; dev->hci.hci_address = 0; - devsc = ue->ue_init(&dev->hci, nvl); - if (devsc == NULL) { + if (ue->ue_init(dev->dev_sc)) goto bad; - } dev->dev_ue = ue; - dev->dev_sc = devsc; if (dev->hci.hci_speed == USB_SPEED_MAX) dev->hci.hci_speed = ue->ue_usbspeed; @@ -2885,6 +2897,8 @@ portsfinal: bad: for (i = 1; i <= XHCI_MAX_DEVS; i++) { + if (XHCI_DEVINST_PTR(sc, i) != NULL) + free(XHCI_DEVINST_PTR(sc, i)->dev_sc); free(XHCI_DEVINST_PTR(sc, i)); } @@ -3232,6 +3246,7 @@ pci_xhci_snapshot(struct vm_snapshot_meta *meta) SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_address, meta, ret, done); SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_port, meta, ret, done); SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_speed, meta, ret, done); + SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_usbver, meta, ret, done); } SNAPSHOT_VAR_OR_LEAVE(sc->usb2_port_start, meta, ret, done); diff --git a/usr.sbin/bhyve/usb_emul.h b/usr.sbin/bhyve/usb_emul.h index 85dedfeacd3b..43b6b53b5205 100644 --- a/usr.sbin/bhyve/usb_emul.h +++ b/usr.sbin/bhyve/usb_emul.h @@ -52,7 +52,8 @@ struct usb_devemu { int ue_usbspeed; /* usb device speed */ /* instance creation */ - void *(*ue_init)(struct usb_hci *hci, nvlist_t *nvl); + void *(*ue_probe)(struct usb_hci *hci, nvlist_t *nvl); + int (*ue_init)(void *sc); /* handlers */ int (*ue_request)(void *sc, struct usb_data_xfer *xfer); @@ -86,6 +87,7 @@ struct usb_hci { int hci_address; int hci_port; int hci_speed; + int hci_usbver; }; /* diff --git a/usr.sbin/bhyve/usb_mouse.c b/usr.sbin/bhyve/usb_mouse.c index a37941c0cd9d..82b1159d5f61 100644 --- a/usr.sbin/bhyve/usb_mouse.c +++ b/usr.sbin/bhyve/usb_mouse.c @@ -295,20 +295,28 @@ umouse_event(uint8_t button, int x, int y, void *arg) } static void * -umouse_init(struct usb_hci *hci, nvlist_t *nvl __unused) +umouse_probe(struct usb_hci *hci, nvlist_t *nvl __unused) { struct umouse_softc *sc; sc = calloc(1, sizeof(struct umouse_softc)); sc->hci = hci; + return (sc); +} + +static int +umouse_init(void *scarg) +{ + struct umouse_softc *sc = (struct umouse_softc *)scarg; + sc->hid.protocol = 1; /* REPORT protocol */ pthread_mutex_init(&sc->mtx, NULL); pthread_mutex_init(&sc->ev_mtx, NULL); console_ptr_register(umouse_event, sc, 10); - return (sc); + return (0); } #define UREQ(x,y) ((x) | ((y) << 8)) @@ -811,6 +819,7 @@ static struct usb_devemu ue_mouse = { .ue_emu = "tablet", .ue_usbver = 3, .ue_usbspeed = USB_SPEED_HIGH, + .ue_probe = umouse_probe, .ue_init = umouse_init, .ue_request = umouse_request, .ue_data = umouse_data_handler, diff --git a/usr.sbin/inetd/builtins.c b/usr.sbin/inetd/builtins.c index 9609faf0b104..21ce44c77033 100644 --- a/usr.sbin/inetd/builtins.c +++ b/usr.sbin/inetd/builtins.c @@ -606,6 +606,8 @@ ident_stream(int s, struct servtab *sep) */ if (initgroups(pw->pw_name, pw->pw_gid) == -1) iderror(lport, fport, s, ID_UNKNOWN); + if (setegid(pw->pw_gid) == -1) + iderror(lport, fport, s, ID_UNKNOWN); if (seteuid(pw->pw_uid) == -1) iderror(lport, fport, s, ID_UNKNOWN); /* diff --git a/usr.sbin/nvmfd/Makefile b/usr.sbin/nvmfd/Makefile deleted file mode 100644 index dc3dcc5e3a5c..000000000000 --- a/usr.sbin/nvmfd/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -.include <src.opts.mk> -.PATH: ${SRCTOP}/sys/libkern - -PACKAGE=nvme-tools -PROG= nvmfd -SRCS= nvmfd.c controller.c ctl.c devices.c discovery.c gsb_crc32.c io.c -CFLAGS+= -I${SRCTOP}/lib/libnvmf -MAN= nvmfd.8 -LIBADD+= nvmf pthread util nv - -.include <bsd.prog.mk> - -CFLAGS.ctl.c= -I${SRCTOP}/sys -CWARNFLAGS.gsb_crc32.c= -Wno-cast-align diff --git a/usr.sbin/nvmfd/Makefile.depend b/usr.sbin/nvmfd/Makefile.depend deleted file mode 100644 index c4c6125c7a7c..000000000000 --- a/usr.sbin/nvmfd/Makefile.depend +++ /dev/null @@ -1,20 +0,0 @@ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - include \ - include/arpa \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - lib/libnv \ - lib/libnvmf \ - lib/libthr \ - lib/libutil \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/usr.sbin/nvmfd/controller.c b/usr.sbin/nvmfd/controller.c deleted file mode 100644 index e9435bce69da..000000000000 --- a/usr.sbin/nvmfd/controller.c +++ /dev/null @@ -1,244 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2023-2024 Chelsio Communications, Inc. - * Written by: John Baldwin <jhb@FreeBSD.org> - */ - -#include <err.h> -#include <errno.h> -#include <libnvmf.h> -#include <stdlib.h> - -#include "internal.h" - -struct controller { - struct nvmf_qpair *qp; - - uint64_t cap; - uint32_t vs; - uint32_t cc; - uint32_t csts; - - bool shutdown; - - struct nvme_controller_data cdata; -}; - -static bool -update_cc(struct controller *c, uint32_t new_cc) -{ - uint32_t changes; - - if (c->shutdown) - return (false); - if (!nvmf_validate_cc(c->qp, c->cap, c->cc, new_cc)) - return (false); - - changes = c->cc ^ new_cc; - c->cc = new_cc; - - /* Handle shutdown requests. */ - if (NVMEV(NVME_CC_REG_SHN, changes) != 0 && - NVMEV(NVME_CC_REG_SHN, new_cc) != 0) { - c->csts &= ~NVMEM(NVME_CSTS_REG_SHST); - c->csts |= NVMEF(NVME_CSTS_REG_SHST, NVME_SHST_COMPLETE); - c->shutdown = true; - } - - if (NVMEV(NVME_CC_REG_EN, changes) != 0) { - if (NVMEV(NVME_CC_REG_EN, new_cc) == 0) { - /* Controller reset. */ - c->csts = 0; - c->shutdown = true; - } else - c->csts |= NVMEF(NVME_CSTS_REG_RDY, 1); - } - return (true); -} - -static void -handle_property_get(const struct controller *c, const struct nvmf_capsule *nc, - const struct nvmf_fabric_prop_get_cmd *pget) -{ - struct nvmf_fabric_prop_get_rsp rsp; - - nvmf_init_cqe(&rsp, nc, 0); - - switch (le32toh(pget->ofst)) { - case NVMF_PROP_CAP: - if (pget->attrib.size != NVMF_PROP_SIZE_8) - goto error; - rsp.value.u64 = htole64(c->cap); - break; - case NVMF_PROP_VS: - if (pget->attrib.size != NVMF_PROP_SIZE_4) - goto error; - rsp.value.u32.low = htole32(c->vs); - break; - case NVMF_PROP_CC: - if (pget->attrib.size != NVMF_PROP_SIZE_4) - goto error; - rsp.value.u32.low = htole32(c->cc); - break; - case NVMF_PROP_CSTS: - if (pget->attrib.size != NVMF_PROP_SIZE_4) - goto error; - rsp.value.u32.low = htole32(c->csts); - break; - default: - goto error; - } - - nvmf_send_response(nc, &rsp); - return; -error: - nvmf_send_generic_error(nc, NVME_SC_INVALID_FIELD); -} - -static void -handle_property_set(struct controller *c, const struct nvmf_capsule *nc, - const struct nvmf_fabric_prop_set_cmd *pset) -{ - switch (le32toh(pset->ofst)) { - case NVMF_PROP_CC: - if (pset->attrib.size != NVMF_PROP_SIZE_4) - goto error; - if (!update_cc(c, le32toh(pset->value.u32.low))) - goto error; - break; - default: - goto error; - } - - nvmf_send_success(nc); - return; -error: - nvmf_send_generic_error(nc, NVME_SC_INVALID_FIELD); -} - -static void -handle_fabrics_command(struct controller *c, - const struct nvmf_capsule *nc, const struct nvmf_fabric_cmd *fc) -{ - switch (fc->fctype) { - case NVMF_FABRIC_COMMAND_PROPERTY_GET: - handle_property_get(c, nc, - (const struct nvmf_fabric_prop_get_cmd *)fc); - break; - case NVMF_FABRIC_COMMAND_PROPERTY_SET: - handle_property_set(c, nc, - (const struct nvmf_fabric_prop_set_cmd *)fc); - break; - case NVMF_FABRIC_COMMAND_CONNECT: - warnx("CONNECT command on connected queue"); - nvmf_send_generic_error(nc, NVME_SC_COMMAND_SEQUENCE_ERROR); - break; - case NVMF_FABRIC_COMMAND_DISCONNECT: - warnx("DISCONNECT command on admin queue"); - nvmf_send_error(nc, NVME_SCT_COMMAND_SPECIFIC, - NVMF_FABRIC_SC_INVALID_QUEUE_TYPE); - break; - default: - warnx("Unsupported fabrics command %#x", fc->fctype); - nvmf_send_generic_error(nc, NVME_SC_INVALID_OPCODE); - break; - } -} - -static void -handle_identify_command(const struct controller *c, - const struct nvmf_capsule *nc, const struct nvme_command *cmd) -{ - uint8_t cns; - - cns = le32toh(cmd->cdw10) & 0xFF; - switch (cns) { - case 1: - break; - default: - warnx("Unsupported CNS %#x for IDENTIFY", cns); - goto error; - } - - nvmf_send_controller_data(nc, &c->cdata, sizeof(c->cdata)); - return; -error: - nvmf_send_generic_error(nc, NVME_SC_INVALID_FIELD); -} - -void -controller_handle_admin_commands(struct controller *c, handle_command *cb, - void *cb_arg) -{ - struct nvmf_qpair *qp = c->qp; - const struct nvme_command *cmd; - struct nvmf_capsule *nc; - int error; - - for (;;) { - error = nvmf_controller_receive_capsule(qp, &nc); - if (error != 0) { - if (error != ECONNRESET) - warnc(error, "Failed to read command capsule"); - break; - } - - cmd = nvmf_capsule_sqe(nc); - - /* - * Only permit Fabrics commands while a controller is - * disabled. - */ - if (NVMEV(NVME_CC_REG_EN, c->cc) == 0 && - cmd->opc != NVME_OPC_FABRICS_COMMANDS) { - warnx("Unsupported admin opcode %#x while disabled\n", - cmd->opc); - nvmf_send_generic_error(nc, - NVME_SC_COMMAND_SEQUENCE_ERROR); - nvmf_free_capsule(nc); - continue; - } - - if (cb(nc, cmd, cb_arg)) { - nvmf_free_capsule(nc); - continue; - } - - switch (cmd->opc) { - case NVME_OPC_FABRICS_COMMANDS: - handle_fabrics_command(c, nc, - (const struct nvmf_fabric_cmd *)cmd); - break; - case NVME_OPC_IDENTIFY: - handle_identify_command(c, nc, cmd); - break; - default: - warnx("Unsupported admin opcode %#x", cmd->opc); - nvmf_send_generic_error(nc, NVME_SC_INVALID_OPCODE); - break; - } - nvmf_free_capsule(nc); - } -} - -struct controller * -init_controller(struct nvmf_qpair *qp, - const struct nvme_controller_data *cdata) -{ - struct controller *c; - - c = calloc(1, sizeof(*c)); - c->qp = qp; - c->cap = nvmf_controller_cap(c->qp); - c->vs = cdata->ver; - c->cdata = *cdata; - - return (c); -} - -void -free_controller(struct controller *c) -{ - free(c); -} diff --git a/usr.sbin/nvmfd/ctl.c b/usr.sbin/nvmfd/ctl.c deleted file mode 100644 index 73e90e1411bd..000000000000 --- a/usr.sbin/nvmfd/ctl.c +++ /dev/null @@ -1,137 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2023 Chelsio Communications, Inc. - * Written by: John Baldwin <jhb@FreeBSD.org> - */ - -#include <sys/param.h> -#include <sys/linker.h> -#include <sys/nv.h> -#include <sys/time.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <libnvmf.h> -#include <string.h> - -#include <cam/ctl/ctl.h> -#include <cam/ctl/ctl_io.h> -#include <cam/ctl/ctl_ioctl.h> - -#include "internal.h" - -static int ctl_fd = -1; -static int ctl_port; - -static void -open_ctl(void) -{ - if (ctl_fd > 0) - return; - - ctl_fd = open(CTL_DEFAULT_DEV, O_RDWR); - if (ctl_fd == -1 && errno == ENOENT) { - if (kldload("ctl") == -1) - err(1, "Failed to load ctl.ko"); - ctl_fd = open(CTL_DEFAULT_DEV, O_RDWR); - } - if (ctl_fd == -1) - err(1, "Failed to open %s", CTL_DEFAULT_DEV); -} - -void -init_ctl_port(const char *subnqn, const struct nvmf_association_params *params) -{ - char result_buf[256]; - struct ctl_port_entry entry; - struct ctl_req req; - nvlist_t *nvl; - - open_ctl(); - - nvl = nvlist_create(0); - - nvlist_add_string(nvl, "subnqn", subnqn); - - /* XXX: Hardcoded in discovery.c */ - nvlist_add_stringf(nvl, "portid", "%u", 1); - - nvlist_add_stringf(nvl, "max_io_qsize", "%u", params->max_io_qsize); - - memset(&req, 0, sizeof(req)); - strlcpy(req.driver, "nvmf", sizeof(req.driver)); - req.reqtype = CTL_REQ_CREATE; - req.args = nvlist_pack(nvl, &req.args_len); - if (req.args == NULL) - errx(1, "Failed to pack nvlist for CTL_PORT/CTL_REQ_CREATE"); - req.result = result_buf; - req.result_len = sizeof(result_buf); - if (ioctl(ctl_fd, CTL_PORT_REQ, &req) != 0) - err(1, "ioctl(CTL_PORT/CTL_REQ_CREATE)"); - if (req.status == CTL_LUN_ERROR) - errx(1, "Failed to create CTL port: %s", req.error_str); - if (req.status != CTL_LUN_OK) - errx(1, "Failed to create CTL port: %d", req.status); - - nvlist_destroy(nvl); - nvl = nvlist_unpack(result_buf, req.result_len, 0); - if (nvl == NULL) - errx(1, "Failed to unpack nvlist from CTL_PORT/CTL_REQ_CREATE"); - - ctl_port = nvlist_get_number(nvl, "port_id"); - nvlist_destroy(nvl); - - memset(&entry, 0, sizeof(entry)); - entry.targ_port = ctl_port; - if (ioctl(ctl_fd, CTL_ENABLE_PORT, &entry) != 0) - errx(1, "ioctl(CTL_ENABLE_PORT)"); -} - -void -shutdown_ctl_port(const char *subnqn) -{ - struct ctl_req req; - nvlist_t *nvl; - - open_ctl(); - - nvl = nvlist_create(0); - - nvlist_add_string(nvl, "subnqn", subnqn); - - memset(&req, 0, sizeof(req)); - strlcpy(req.driver, "nvmf", sizeof(req.driver)); - req.reqtype = CTL_REQ_REMOVE; - req.args = nvlist_pack(nvl, &req.args_len); - if (req.args == NULL) - errx(1, "Failed to pack nvlist for CTL_PORT/CTL_REQ_REMOVE"); - if (ioctl(ctl_fd, CTL_PORT_REQ, &req) != 0) - err(1, "ioctl(CTL_PORT/CTL_REQ_REMOVE)"); - if (req.status == CTL_LUN_ERROR) - errx(1, "Failed to remove CTL port: %s", req.error_str); - if (req.status != CTL_LUN_OK) - errx(1, "Failed to remove CTL port: %d", req.status); - - nvlist_destroy(nvl); -} - -void -ctl_handoff_qpair(struct nvmf_qpair *qp, - const struct nvmf_fabric_connect_cmd *cmd, - const struct nvmf_fabric_connect_data *data) -{ - struct ctl_nvmf req; - int error; - - memset(&req, 0, sizeof(req)); - req.type = CTL_NVMF_HANDOFF; - error = nvmf_handoff_controller_qpair(qp, cmd, data, &req.data.handoff); - if (error != 0) { - warnc(error, "Failed to prepare qpair for handoff"); - return; - } - - if (ioctl(ctl_fd, CTL_NVMF, &req) != 0) - warn("ioctl(CTL_NVMF/CTL_NVMF_HANDOFF)"); -} diff --git a/usr.sbin/nvmfd/devices.c b/usr.sbin/nvmfd/devices.c deleted file mode 100644 index fafc1077f207..000000000000 --- a/usr.sbin/nvmfd/devices.c +++ /dev/null @@ -1,386 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2023-2024 Chelsio Communications, Inc. - * Written by: John Baldwin <jhb@FreeBSD.org> - */ - -#include <sys/disk.h> -#include <sys/gsb_crc32.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <net/ieee_oui.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <libnvmf.h> -#include <libutil.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "internal.h" - -#define RAMDISK_PREFIX "ramdisk:" - -struct backing_device { - enum { RAMDISK, FILE, CDEV } type; - union { - int fd; /* FILE, CDEV */ - void *mem; /* RAMDISK */ - }; - u_int sector_size; - uint64_t nlbas; - uint64_t eui64; -}; - -static struct backing_device *devices; -static u_int ndevices; - -static uint64_t -generate_eui64(uint32_t low) -{ - return (OUI_FREEBSD_NVME_LOW << 16 | low); -} - -static uint32_t -crc32(const void *buf, size_t len) -{ - return (calculate_crc32c(0xffffffff, buf, len) ^ 0xffffffff); -} - -static void -init_ramdisk(const char *config, struct backing_device *dev) -{ - static uint32_t ramdisk_idx = 1; - uint64_t num; - - dev->type = RAMDISK; - dev->sector_size = 512; - if (expand_number(config, &num)) - errx(1, "Invalid ramdisk specification: %s", config); - if ((num % dev->sector_size) != 0) - errx(1, "Invalid ramdisk size %ju", (uintmax_t)num); - dev->mem = calloc(num, 1); - dev->nlbas = num / dev->sector_size; - dev->eui64 = generate_eui64('M' << 24 | ramdisk_idx++); -} - -static void -init_filedevice(const char *config, int fd, struct stat *sb, - struct backing_device *dev) -{ - dev->type = FILE; - dev->fd = fd; - dev->sector_size = 512; - if ((sb->st_size % dev->sector_size) != 0) - errx(1, "File size is not a multiple of 512: %s", config); - dev->nlbas = sb->st_size / dev->sector_size; - dev->eui64 = generate_eui64('F' << 24 | - (crc32(config, strlen(config)) & 0xffffff)); -} - -static void -init_chardevice(const char *config, int fd, struct backing_device *dev) -{ - off_t len; - - dev->type = CDEV; - dev->fd = fd; - if (ioctl(fd, DIOCGSECTORSIZE, &dev->sector_size) != 0) - err(1, "Failed to fetch sector size for %s", config); - if (ioctl(fd, DIOCGMEDIASIZE, &len) != 0) - err(1, "Failed to fetch sector size for %s", config); - dev->nlbas = len / dev->sector_size; - dev->eui64 = generate_eui64('C' << 24 | - (crc32(config, strlen(config)) & 0xffffff)); -} - -static void -init_device(const char *config, struct backing_device *dev) -{ - struct stat sb; - int fd; - - /* Check for a RAM disk. */ - if (strncmp(RAMDISK_PREFIX, config, strlen(RAMDISK_PREFIX)) == 0) { - init_ramdisk(config + strlen(RAMDISK_PREFIX), dev); - return; - } - - fd = open(config, O_RDWR); - if (fd == -1) - err(1, "Failed to open %s", config); - if (fstat(fd, &sb) == -1) - err(1, "fstat"); - switch (sb.st_mode & S_IFMT) { - case S_IFCHR: - init_chardevice(config, fd, dev); - break; - case S_IFREG: - init_filedevice(config, fd, &sb, dev); - break; - default: - errx(1, "Invalid file type for %s", config); - } -} - -void -register_devices(int ac, char **av) -{ - ndevices = ac; - devices = calloc(ndevices, sizeof(*devices)); - - for (int i = 0; i < ac; i++) - init_device(av[i], &devices[i]); -} - -u_int -device_count(void) -{ - return (ndevices); -} - -static struct backing_device * -lookup_device(uint32_t nsid) -{ - if (nsid == 0 || nsid > ndevices) - return (NULL); - return (&devices[nsid - 1]); -} - -void -device_active_nslist(uint32_t nsid, struct nvme_ns_list *nslist) -{ - u_int count; - - memset(nslist, 0, sizeof(*nslist)); - count = 0; - nsid++; - while (nsid <= ndevices) { - nslist->ns[count] = htole32(nsid); - count++; - if (count == nitems(nslist->ns)) - break; - nsid++; - } -} - -bool -device_identification_descriptor(uint32_t nsid, void *buf) -{ - struct backing_device *dev; - char *p; - - dev = lookup_device(nsid); - if (dev == NULL) - return (false); - - memset(buf, 0, 4096); - - p = buf; - - /* EUI64 */ - *p++ = 1; - *p++ = 8; - p += 2; - be64enc(p, dev->eui64); - return (true); -} - -bool -device_namespace_data(uint32_t nsid, struct nvme_namespace_data *nsdata) -{ - struct backing_device *dev; - - dev = lookup_device(nsid); - if (dev == NULL) - return (false); - - memset(nsdata, 0, sizeof(*nsdata)); - nsdata->nsze = htole64(dev->nlbas); - nsdata->ncap = nsdata->nsze; - nsdata->nuse = nsdata->ncap; - nsdata->nlbaf = 1 - 1; - nsdata->flbas = NVMEF(NVME_NS_DATA_FLBAS_FORMAT, 0); - nsdata->lbaf[0] = NVMEF(NVME_NS_DATA_LBAF_LBADS, - ffs(dev->sector_size) - 1); - - be64enc(nsdata->eui64, dev->eui64); - return (true); -} - -static bool -read_buffer(int fd, void *buf, size_t len, off_t offset) -{ - ssize_t nread; - char *dst; - - dst = buf; - while (len > 0) { - nread = pread(fd, dst, len, offset); - if (nread == -1 && errno == EINTR) - continue; - if (nread <= 0) - return (false); - dst += nread; - len -= nread; - offset += nread; - } - return (true); -} - -void -device_read(uint32_t nsid, uint64_t lba, u_int nlb, - const struct nvmf_capsule *nc) -{ - struct backing_device *dev; - char *p, *src; - off_t off; - size_t len; - - dev = lookup_device(nsid); - if (dev == NULL) { - nvmf_send_generic_error(nc, - NVME_SC_INVALID_NAMESPACE_OR_FORMAT); - return; - } - - if (lba + nlb < lba || lba + nlb > dev->nlbas) { - nvmf_send_generic_error(nc, NVME_SC_LBA_OUT_OF_RANGE); - return; - } - - off = lba * dev->sector_size; - len = nlb * dev->sector_size; - if (nvmf_capsule_data_len(nc) != len) { - nvmf_send_generic_error(nc, NVME_SC_INVALID_FIELD); - return; - } - - if (dev->type == RAMDISK) { - p = NULL; - src = (char *)dev->mem + off; - } else { - p = malloc(len); - if (!read_buffer(dev->fd, p, len, off)) { - free(p); - nvmf_send_generic_error(nc, - NVME_SC_INTERNAL_DEVICE_ERROR); - return; - } - src = p; - } - - nvmf_send_controller_data(nc, src, len); - free(p); -} - -static bool -write_buffer(int fd, const void *buf, size_t len, off_t offset) -{ - ssize_t nwritten; - const char *src; - - src = buf; - while (len > 0) { - nwritten = pwrite(fd, src, len, offset); - if (nwritten == -1 && errno == EINTR) - continue; - if (nwritten <= 0) - return (false); - src += nwritten; - len -= nwritten; - offset += nwritten; - } - return (true); -} - -void -device_write(uint32_t nsid, uint64_t lba, u_int nlb, - const struct nvmf_capsule *nc) -{ - struct backing_device *dev; - char *p, *dst; - off_t off; - size_t len; - int error; - - dev = lookup_device(nsid); - if (dev == NULL) { - nvmf_send_generic_error(nc, - NVME_SC_INVALID_NAMESPACE_OR_FORMAT); - return; - } - - if (lba + nlb < lba || lba + nlb > dev->nlbas) { - nvmf_send_generic_error(nc, NVME_SC_LBA_OUT_OF_RANGE); - return; - } - - off = lba * dev->sector_size; - len = nlb * dev->sector_size; - if (nvmf_capsule_data_len(nc) != len) { - nvmf_send_generic_error(nc, NVME_SC_INVALID_FIELD); - return; - } - - if (dev->type == RAMDISK) { - p = NULL; - dst = (char *)dev->mem + off; - } else { - p = malloc(len); - dst = p; - } - - error = nvmf_receive_controller_data(nc, 0, dst, len); - if (error != 0) { - nvmf_send_generic_error(nc, NVME_SC_TRANSIENT_TRANSPORT_ERROR); - free(p); - return; - } - - if (dev->type != RAMDISK) { - if (!write_buffer(dev->fd, p, len, off)) { - free(p); - nvmf_send_generic_error(nc, - NVME_SC_INTERNAL_DEVICE_ERROR); - return; - } - } - free(p); - nvmf_send_success(nc); -} - -void -device_flush(uint32_t nsid, const struct nvmf_capsule *nc) -{ - struct backing_device *dev; - - dev = lookup_device(nsid); - if (dev == NULL) { - nvmf_send_generic_error(nc, - NVME_SC_INVALID_NAMESPACE_OR_FORMAT); - return; - } - - switch (dev->type) { - case RAMDISK: - break; - case FILE: - if (fdatasync(dev->fd) == -1) { - nvmf_send_error(nc, NVME_SCT_MEDIA_ERROR, - NVME_SC_WRITE_FAULTS); - return; - } - break; - case CDEV: - if (ioctl(dev->fd, DIOCGFLUSH) == -1) { - nvmf_send_error(nc, NVME_SCT_MEDIA_ERROR, - NVME_SC_WRITE_FAULTS); - return; - } - } - - nvmf_send_success(nc); -} diff --git a/usr.sbin/nvmfd/discovery.c b/usr.sbin/nvmfd/discovery.c deleted file mode 100644 index 2cfe56731d7c..000000000000 --- a/usr.sbin/nvmfd/discovery.c +++ /dev/null @@ -1,342 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2023-2024 Chelsio Communications, Inc. - * Written by: John Baldwin <jhb@FreeBSD.org> - */ - -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <assert.h> -#include <err.h> -#include <libnvmf.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "internal.h" - -struct io_controller_data { - struct nvme_discovery_log_entry entry; - bool wildcard; -}; - -struct discovery_controller { - struct nvme_discovery_log *discovery_log; - size_t discovery_log_len; - int s; -}; - -struct discovery_thread_arg { - struct controller *c; - struct nvmf_qpair *qp; - int s; -}; - -static struct io_controller_data *io_controllers; -static struct nvmf_association *discovery_na; -static u_int num_io_controllers; - -static bool -init_discovery_log_entry(struct nvme_discovery_log_entry *entry, int s, - const char *subnqn) -{ - struct sockaddr_storage ss; - socklen_t len; - bool wildcard; - - len = sizeof(ss); - if (getsockname(s, (struct sockaddr *)&ss, &len) == -1) - err(1, "getsockname"); - - memset(entry, 0, sizeof(*entry)); - entry->trtype = NVMF_TRTYPE_TCP; - switch (ss.ss_family) { - case AF_INET: - { - struct sockaddr_in *sin; - - sin = (struct sockaddr_in *)&ss; - entry->adrfam = NVMF_ADRFAM_IPV4; - snprintf(entry->trsvcid, sizeof(entry->trsvcid), "%u", - htons(sin->sin_port)); - if (inet_ntop(AF_INET, &sin->sin_addr, entry->traddr, - sizeof(entry->traddr)) == NULL) - err(1, "inet_ntop"); - wildcard = (sin->sin_addr.s_addr == htonl(INADDR_ANY)); - break; - } - case AF_INET6: - { - struct sockaddr_in6 *sin6; - - sin6 = (struct sockaddr_in6 *)&ss; - entry->adrfam = NVMF_ADRFAM_IPV6; - snprintf(entry->trsvcid, sizeof(entry->trsvcid), "%u", - htons(sin6->sin6_port)); - if (inet_ntop(AF_INET6, &sin6->sin6_addr, entry->traddr, - sizeof(entry->traddr)) == NULL) - err(1, "inet_ntop"); - wildcard = (memcmp(&sin6->sin6_addr, &in6addr_any, - sizeof(in6addr_any)) == 0); - break; - } - default: - errx(1, "Unsupported address family %u", ss.ss_family); - } - entry->subtype = NVMF_SUBTYPE_NVME; - if (flow_control_disable) - entry->treq |= (1 << 2); - entry->portid = htole16(1); - entry->cntlid = htole16(NVMF_CNTLID_DYNAMIC); - entry->aqsz = NVME_MAX_ADMIN_ENTRIES; - strlcpy(entry->subnqn, subnqn, sizeof(entry->subnqn)); - return (wildcard); -} - -void -init_discovery(void) -{ - struct nvmf_association_params aparams; - - memset(&aparams, 0, sizeof(aparams)); - aparams.sq_flow_control = false; - aparams.dynamic_controller_model = true; - aparams.max_admin_qsize = NVME_MAX_ADMIN_ENTRIES; - aparams.tcp.pda = 0; - aparams.tcp.header_digests = header_digests; - aparams.tcp.data_digests = data_digests; - aparams.tcp.maxh2cdata = maxh2cdata; - discovery_na = nvmf_allocate_association(NVMF_TRTYPE_TCP, true, - &aparams); - if (discovery_na == NULL) - err(1, "Failed to create discovery association"); -} - -void -discovery_add_io_controller(int s, const char *subnqn) -{ - struct io_controller_data *icd; - - io_controllers = reallocf(io_controllers, (num_io_controllers + 1) * - sizeof(*io_controllers)); - - icd = &io_controllers[num_io_controllers]; - num_io_controllers++; - - icd->wildcard = init_discovery_log_entry(&icd->entry, s, subnqn); -} - -static void -build_discovery_log_page(struct discovery_controller *dc) -{ - struct sockaddr_storage ss; - socklen_t len; - char traddr[256]; - u_int i, nentries; - uint8_t adrfam; - - if (dc->discovery_log != NULL) - return; - - len = sizeof(ss); - if (getsockname(dc->s, (struct sockaddr *)&ss, &len) == -1) { - warn("build_discovery_log_page: getsockname"); - return; - } - - memset(traddr, 0, sizeof(traddr)); - switch (ss.ss_family) { - case AF_INET: - { - struct sockaddr_in *sin; - - sin = (struct sockaddr_in *)&ss; - adrfam = NVMF_ADRFAM_IPV4; - if (inet_ntop(AF_INET, &sin->sin_addr, traddr, - sizeof(traddr)) == NULL) { - warn("build_discovery_log_page: inet_ntop"); - return; - } - break; - } - case AF_INET6: - { - struct sockaddr_in6 *sin6; - - sin6 = (struct sockaddr_in6 *)&ss; - adrfam = NVMF_ADRFAM_IPV6; - if (inet_ntop(AF_INET6, &sin6->sin6_addr, traddr, - sizeof(traddr)) == NULL) { - warn("build_discovery_log_page: inet_ntop"); - return; - } - break; - } - default: - assert(false); - } - - nentries = 0; - for (i = 0; i < num_io_controllers; i++) { - if (io_controllers[i].wildcard && - io_controllers[i].entry.adrfam != adrfam) - continue; - nentries++; - } - - dc->discovery_log_len = sizeof(*dc->discovery_log) + - nentries * sizeof(struct nvme_discovery_log_entry); - dc->discovery_log = calloc(dc->discovery_log_len, 1); - dc->discovery_log->numrec = nentries; - dc->discovery_log->recfmt = 0; - nentries = 0; - for (i = 0; i < num_io_controllers; i++) { - if (io_controllers[i].wildcard && - io_controllers[i].entry.adrfam != adrfam) - continue; - - dc->discovery_log->entries[nentries] = io_controllers[i].entry; - if (io_controllers[i].wildcard) - memcpy(dc->discovery_log->entries[nentries].traddr, - traddr, sizeof(traddr)); - } -} - -static void -handle_get_log_page_command(const struct nvmf_capsule *nc, - const struct nvme_command *cmd, struct discovery_controller *dc) -{ - uint64_t offset; - uint32_t length; - - switch (nvmf_get_log_page_id(cmd)) { - case NVME_LOG_DISCOVERY: - break; - default: - warnx("Unsupported log page %u for discovery controller", - nvmf_get_log_page_id(cmd)); - goto error; - } - - build_discovery_log_page(dc); - - offset = nvmf_get_log_page_offset(cmd); - if (offset >= dc->discovery_log_len) - goto error; - - length = nvmf_get_log_page_length(cmd); - if (length > dc->discovery_log_len - offset) - length = dc->discovery_log_len - offset; - - nvmf_send_controller_data(nc, (char *)dc->discovery_log + offset, - length); - return; -error: - nvmf_send_generic_error(nc, NVME_SC_INVALID_FIELD); -} - -static bool -discovery_command(const struct nvmf_capsule *nc, const struct nvme_command *cmd, - void *arg) -{ - struct discovery_controller *dc = arg; - - switch (cmd->opc) { - case NVME_OPC_GET_LOG_PAGE: - handle_get_log_page_command(nc, cmd, dc); - return (true); - default: - return (false); - } -} - -static void * -discovery_thread(void *arg) -{ - struct discovery_thread_arg *dta = arg; - struct discovery_controller dc; - - pthread_detach(pthread_self()); - - memset(&dc, 0, sizeof(dc)); - dc.s = dta->s; - - controller_handle_admin_commands(dta->c, discovery_command, &dc); - - free(dc.discovery_log); - free_controller(dta->c); - - nvmf_free_qpair(dta->qp); - - close(dta->s); - free(dta); - return (NULL); -} - -void -handle_discovery_socket(int s) -{ - struct nvmf_fabric_connect_data data; - struct nvme_controller_data cdata; - struct nvmf_qpair_params qparams; - struct discovery_thread_arg *dta; - struct nvmf_capsule *nc; - struct nvmf_qpair *qp; - pthread_t thr; - int error; - - memset(&qparams, 0, sizeof(qparams)); - qparams.tcp.fd = s; - - nc = NULL; - qp = nvmf_accept(discovery_na, &qparams, &nc, &data); - if (qp == NULL) { - warnx("Failed to create discovery qpair: %s", - nvmf_association_error(discovery_na)); - goto error; - } - - if (strcmp(data.subnqn, NVMF_DISCOVERY_NQN) != 0) { - warn("Discovery qpair with invalid SubNQN: %.*s", - (int)sizeof(data.subnqn), data.subnqn); - nvmf_connect_invalid_parameters(nc, true, - offsetof(struct nvmf_fabric_connect_data, subnqn)); - goto error; - } - - /* Just use a controller ID of 1 for all discovery controllers. */ - error = nvmf_finish_accept(nc, 1); - if (error != 0) { - warnc(error, "Failed to send CONNECT reponse"); - goto error; - } - - nvmf_init_discovery_controller_data(qp, &cdata); - - dta = malloc(sizeof(*dta)); - dta->qp = qp; - dta->s = s; - dta->c = init_controller(qp, &cdata); - - error = pthread_create(&thr, NULL, discovery_thread, dta); - if (error != 0) { - warnc(error, "Failed to create discovery thread"); - free_controller(dta->c); - free(dta); - goto error; - } - - nvmf_free_capsule(nc); - return; - -error: - if (nc != NULL) - nvmf_free_capsule(nc); - if (qp != NULL) - nvmf_free_qpair(qp); - close(s); -} diff --git a/usr.sbin/nvmfd/internal.h b/usr.sbin/nvmfd/internal.h deleted file mode 100644 index f70dc78881c6..000000000000 --- a/usr.sbin/nvmfd/internal.h +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2023-2024 Chelsio Communications, Inc. - * Written by: John Baldwin <jhb@FreeBSD.org> - */ - -#ifndef __INTERNAL_H__ -#define __INTERNAL_H__ - -#include <stdbool.h> - -struct controller; -struct nvme_command; -struct nvme_controller_data; -struct nvme_ns_list; -struct nvmf_capsule; -struct nvmf_qpair; - -typedef bool handle_command(const struct nvmf_capsule *, - const struct nvme_command *, void *); - -extern bool data_digests; -extern bool header_digests; -extern bool flow_control_disable; -extern bool kernel_io; -extern uint32_t maxh2cdata; - -/* controller.c */ -void controller_handle_admin_commands(struct controller *c, - handle_command *cb, void *cb_arg); -struct controller *init_controller(struct nvmf_qpair *qp, - const struct nvme_controller_data *cdata); -void free_controller(struct controller *c); - -/* discovery.c */ -void init_discovery(void); -void handle_discovery_socket(int s); -void discovery_add_io_controller(int s, const char *subnqn); - -/* io.c */ -void init_io(const char *subnqn); -void handle_io_socket(int s); -void shutdown_io(void); - -/* devices.c */ -void register_devices(int ac, char **av); -u_int device_count(void); -void device_active_nslist(uint32_t nsid, struct nvme_ns_list *nslist); -bool device_identification_descriptor(uint32_t nsid, void *buf); -bool device_namespace_data(uint32_t nsid, struct nvme_namespace_data *nsdata); -void device_read(uint32_t nsid, uint64_t lba, u_int nlb, - const struct nvmf_capsule *nc); -void device_write(uint32_t nsid, uint64_t lba, u_int nlb, - const struct nvmf_capsule *nc); -void device_flush(uint32_t nsid, const struct nvmf_capsule *nc); - -/* ctl.c */ -void init_ctl_port(const char *subnqn, - const struct nvmf_association_params *params); -void ctl_handoff_qpair(struct nvmf_qpair *qp, - const struct nvmf_fabric_connect_cmd *cmd, - const struct nvmf_fabric_connect_data *data); -void shutdown_ctl_port(const char *subnqn); - -#endif /* !__INTERNAL_H__ */ diff --git a/usr.sbin/nvmfd/io.c b/usr.sbin/nvmfd/io.c deleted file mode 100644 index 4407360257a2..000000000000 --- a/usr.sbin/nvmfd/io.c +++ /dev/null @@ -1,676 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2023-2024 Chelsio Communications, Inc. - * Written by: John Baldwin <jhb@FreeBSD.org> - */ - -#include <sys/sysctl.h> -#include <err.h> -#include <errno.h> -#include <libnvmf.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "internal.h" - -struct io_controller { - struct controller *c; - - u_int num_io_queues; - u_int active_io_queues; - struct nvmf_qpair **io_qpairs; - int *io_sockets; - - struct nvme_firmware_page fp; - struct nvme_health_information_page hip; - uint16_t partial_dur; - uint16_t partial_duw; - - uint16_t cntlid; - char hostid[16]; - char hostnqn[NVME_NQN_FIELD_SIZE]; -}; - -static struct nvmf_association *io_na; -static pthread_cond_t io_cond; -static pthread_mutex_t io_na_mutex; -static struct io_controller *io_controller; -static const char *nqn; -static char serial[NVME_SERIAL_NUMBER_LENGTH]; - -void -init_io(const char *subnqn) -{ - struct nvmf_association_params aparams; - u_long hostid; - size_t len; - - memset(&aparams, 0, sizeof(aparams)); - aparams.sq_flow_control = !flow_control_disable; - aparams.dynamic_controller_model = true; - aparams.max_admin_qsize = NVME_MAX_ADMIN_ENTRIES; - aparams.max_io_qsize = NVMF_MAX_IO_ENTRIES; - aparams.tcp.pda = 0; - aparams.tcp.header_digests = header_digests; - aparams.tcp.data_digests = data_digests; - aparams.tcp.maxh2cdata = maxh2cdata; - io_na = nvmf_allocate_association(NVMF_TRTYPE_TCP, true, - &aparams); - if (io_na == NULL) - err(1, "Failed to create I/O controller association"); - - nqn = subnqn; - - /* Generate a serial number from the kern.hostid node. */ - len = sizeof(hostid); - if (sysctlbyname("kern.hostid", &hostid, &len, NULL, 0) == -1) - err(1, "sysctl: kern.hostid"); - - nvmf_controller_serial(serial, sizeof(serial), hostid); - - pthread_cond_init(&io_cond, NULL); - pthread_mutex_init(&io_na_mutex, NULL); - - if (kernel_io) - init_ctl_port(subnqn, &aparams); -} - -void -shutdown_io(void) -{ - if (kernel_io) - shutdown_ctl_port(nqn); -} - -static void -handle_get_log_page(struct io_controller *ioc, const struct nvmf_capsule *nc, - const struct nvme_command *cmd) -{ - uint64_t offset; - uint32_t numd; - size_t len; - uint8_t lid; - - lid = le32toh(cmd->cdw10) & 0xff; - numd = le32toh(cmd->cdw10) >> 16 | le32toh(cmd->cdw11) << 16; - offset = le32toh(cmd->cdw12) | (uint64_t)le32toh(cmd->cdw13) << 32; - - if (offset % 3 != 0) - goto error; - - len = (numd + 1) * 4; - - switch (lid) { - case NVME_LOG_ERROR: - { - void *buf; - - if (len % sizeof(struct nvme_error_information_entry) != 0) - goto error; - - buf = calloc(1, len); - nvmf_send_controller_data(nc, buf, len); - free(buf); - return; - } - case NVME_LOG_HEALTH_INFORMATION: - if (len != sizeof(ioc->hip)) - goto error; - - nvmf_send_controller_data(nc, &ioc->hip, sizeof(ioc->hip)); - return; - case NVME_LOG_FIRMWARE_SLOT: - if (len != sizeof(ioc->fp)) - goto error; - - nvmf_send_controller_data(nc, &ioc->fp, sizeof(ioc->fp)); - return; - default: - warnx("Unsupported page %#x for GET_LOG_PAGE\n", lid); - goto error; - } - -error: - nvmf_send_generic_error(nc, NVME_SC_INVALID_FIELD); -} - -static bool -handle_io_identify_command(const struct nvmf_capsule *nc, - const struct nvme_command *cmd) -{ - struct nvme_namespace_data nsdata; - struct nvme_ns_list nslist; - uint32_t nsid; - uint8_t cns; - - cns = le32toh(cmd->cdw10) & 0xFF; - switch (cns) { - case 0: /* Namespace data. */ - if (!device_namespace_data(le32toh(cmd->nsid), &nsdata)) { - nvmf_send_generic_error(nc, - NVME_SC_INVALID_NAMESPACE_OR_FORMAT); - return (true); - } - - nvmf_send_controller_data(nc, &nsdata, sizeof(nsdata)); - return (true); - case 2: /* Active namespace list. */ - nsid = le32toh(cmd->nsid); - if (nsid >= 0xfffffffe) { - nvmf_send_generic_error(nc, NVME_SC_INVALID_FIELD); - return (true); - } - - device_active_nslist(nsid, &nslist); - nvmf_send_controller_data(nc, &nslist, sizeof(nslist)); - return (true); - case 3: /* Namespace Identification Descriptor list. */ - if (!device_identification_descriptor(le32toh(cmd->nsid), - &nsdata)) { - nvmf_send_generic_error(nc, - NVME_SC_INVALID_NAMESPACE_OR_FORMAT); - return (true); - } - - nvmf_send_controller_data(nc, &nsdata, sizeof(nsdata)); - return (true); - default: - return (false); - } -} - -static void -handle_set_features(struct io_controller *ioc, const struct nvmf_capsule *nc, - const struct nvme_command *cmd) -{ - struct nvme_completion cqe; - uint8_t fid; - - fid = NVMEV(NVME_FEAT_SET_FID, le32toh(cmd->cdw10)); - switch (fid) { - case NVME_FEAT_NUMBER_OF_QUEUES: - { - uint32_t num_queues; - - if (ioc->num_io_queues != 0) { - nvmf_send_generic_error(nc, - NVME_SC_COMMAND_SEQUENCE_ERROR); - return; - } - - num_queues = le32toh(cmd->cdw11) & 0xffff; - - /* 5.12.1.7: 65535 is invalid. */ - if (num_queues == 65535) - goto error; - - /* Fabrics requires the same number of SQs and CQs. */ - if (le32toh(cmd->cdw11) >> 16 != num_queues) - goto error; - - /* Convert to 1's based */ - num_queues++; - - /* Lock to synchronize with handle_io_qpair. */ - pthread_mutex_lock(&io_na_mutex); - ioc->num_io_queues = num_queues; - ioc->io_qpairs = calloc(num_queues, sizeof(*ioc->io_qpairs)); - ioc->io_sockets = calloc(num_queues, sizeof(*ioc->io_sockets)); - pthread_mutex_unlock(&io_na_mutex); - - nvmf_init_cqe(&cqe, nc, 0); - cqe.cdw0 = cmd->cdw11; - nvmf_send_response(nc, &cqe); - return; - } - case NVME_FEAT_ASYNC_EVENT_CONFIGURATION: - { - uint32_t aer_mask; - - aer_mask = le32toh(cmd->cdw11); - - /* Check for any reserved or unimplemented feature bits. */ - if ((aer_mask & 0xffffc000) != 0) - goto error; - - /* No AERs are generated by this daemon. */ - nvmf_send_success(nc); - return; - } - default: - warnx("Unsupported feature ID %u for SET_FEATURES", fid); - goto error; - } - -error: - nvmf_send_generic_error(nc, NVME_SC_INVALID_FIELD); -} - -static bool -admin_command(const struct nvmf_capsule *nc, const struct nvme_command *cmd, - void *arg) -{ - struct io_controller *ioc = arg; - - switch (cmd->opc) { - case NVME_OPC_GET_LOG_PAGE: - handle_get_log_page(ioc, nc, cmd); - return (true); - case NVME_OPC_IDENTIFY: - return (handle_io_identify_command(nc, cmd)); - case NVME_OPC_SET_FEATURES: - handle_set_features(ioc, nc, cmd); - return (true); - case NVME_OPC_ASYNC_EVENT_REQUEST: - /* Ignore and never complete. */ - return (true); - case NVME_OPC_KEEP_ALIVE: - nvmf_send_success(nc); - return (true); - default: - return (false); - } -} - -static void -handle_admin_qpair(struct io_controller *ioc) -{ - pthread_setname_np(pthread_self(), "admin queue"); - - controller_handle_admin_commands(ioc->c, admin_command, ioc); - - pthread_mutex_lock(&io_na_mutex); - for (u_int i = 0; i < ioc->num_io_queues; i++) { - if (ioc->io_qpairs[i] == NULL || ioc->io_sockets[i] == -1) - continue; - close(ioc->io_sockets[i]); - ioc->io_sockets[i] = -1; - } - - /* Wait for I/O threads to notice. */ - while (ioc->active_io_queues > 0) - pthread_cond_wait(&io_cond, &io_na_mutex); - - io_controller = NULL; - pthread_mutex_unlock(&io_na_mutex); - - free_controller(ioc->c); - - free(ioc); -} - -static bool -handle_io_fabrics_command(const struct nvmf_capsule *nc, - const struct nvmf_fabric_cmd *fc) -{ - switch (fc->fctype) { - case NVMF_FABRIC_COMMAND_CONNECT: - warnx("CONNECT command on connected queue"); - nvmf_send_generic_error(nc, NVME_SC_COMMAND_SEQUENCE_ERROR); - break; - case NVMF_FABRIC_COMMAND_DISCONNECT: - { - const struct nvmf_fabric_disconnect_cmd *dis = - (const struct nvmf_fabric_disconnect_cmd *)fc; - if (dis->recfmt != htole16(0)) { - nvmf_send_error(nc, NVME_SCT_COMMAND_SPECIFIC, - NVMF_FABRIC_SC_INCOMPATIBLE_FORMAT); - break; - } - nvmf_send_success(nc); - return (true); - } - default: - warnx("Unsupported fabrics command %#x", fc->fctype); - nvmf_send_generic_error(nc, NVME_SC_INVALID_OPCODE); - break; - } - - return (false); -} - -static void -hip_add(uint64_t pair[2], uint64_t addend) -{ - uint64_t old, new; - - old = le64toh(pair[0]); - new = old + addend; - pair[0] = htole64(new); - if (new < old) - pair[1] += htole64(1); -} - -static uint64_t -cmd_lba(const struct nvme_command *cmd) -{ - return ((uint64_t)le32toh(cmd->cdw11) << 32 | le32toh(cmd->cdw10)); -} - -static u_int -cmd_nlb(const struct nvme_command *cmd) -{ - return ((le32toh(cmd->cdw12) & 0xffff) + 1); -} - -static void -handle_read(struct io_controller *ioc, const struct nvmf_capsule *nc, - const struct nvme_command *cmd) -{ - size_t len; - - len = nvmf_capsule_data_len(nc); - device_read(le32toh(cmd->nsid), cmd_lba(cmd), cmd_nlb(cmd), nc); - hip_add(ioc->hip.host_read_commands, 1); - - len /= 512; - len += ioc->partial_dur; - if (len > 1000) - hip_add(ioc->hip.data_units_read, len / 1000); - ioc->partial_dur = len % 1000; -} - -static void -handle_write(struct io_controller *ioc, const struct nvmf_capsule *nc, - const struct nvme_command *cmd) -{ - size_t len; - - len = nvmf_capsule_data_len(nc); - device_write(le32toh(cmd->nsid), cmd_lba(cmd), cmd_nlb(cmd), nc); - hip_add(ioc->hip.host_write_commands, 1); - - len /= 512; - len += ioc->partial_duw; - if (len > 1000) - hip_add(ioc->hip.data_units_written, len / 1000); - ioc->partial_duw = len % 1000; -} - -static void -handle_flush(const struct nvmf_capsule *nc, const struct nvme_command *cmd) -{ - device_flush(le32toh(cmd->nsid), nc); -} - -static bool -handle_io_commands(struct io_controller *ioc, struct nvmf_qpair *qp) -{ - const struct nvme_command *cmd; - struct nvmf_capsule *nc; - int error; - bool disconnect; - - disconnect = false; - - while (!disconnect) { - error = nvmf_controller_receive_capsule(qp, &nc); - if (error != 0) { - if (error != ECONNRESET) - warnc(error, "Failed to read command capsule"); - break; - } - - cmd = nvmf_capsule_sqe(nc); - - switch (cmd->opc) { - case NVME_OPC_FLUSH: - if (cmd->nsid == htole32(0xffffffff)) { - nvmf_send_generic_error(nc, - NVME_SC_INVALID_NAMESPACE_OR_FORMAT); - break; - } - handle_flush(nc, cmd); - break; - case NVME_OPC_WRITE: - handle_write(ioc, nc, cmd); - break; - case NVME_OPC_READ: - handle_read(ioc, nc, cmd); - break; - case NVME_OPC_FABRICS_COMMANDS: - disconnect = handle_io_fabrics_command(nc, - (const struct nvmf_fabric_cmd *)cmd); - break; - default: - warnx("Unsupported NVM opcode %#x", cmd->opc); - nvmf_send_generic_error(nc, NVME_SC_INVALID_OPCODE); - break; - } - nvmf_free_capsule(nc); - } - - return (disconnect); -} - -static void -handle_io_qpair(struct io_controller *ioc, struct nvmf_qpair *qp, int qid) -{ - char name[64]; - bool disconnect; - - snprintf(name, sizeof(name), "I/O queue %d", qid); - pthread_setname_np(pthread_self(), name); - - disconnect = handle_io_commands(ioc, qp); - - pthread_mutex_lock(&io_na_mutex); - if (disconnect) - ioc->io_qpairs[qid - 1] = NULL; - if (ioc->io_sockets[qid - 1] != -1) { - close(ioc->io_sockets[qid - 1]); - ioc->io_sockets[qid - 1] = -1; - } - ioc->active_io_queues--; - if (ioc->active_io_queues == 0) - pthread_cond_broadcast(&io_cond); - pthread_mutex_unlock(&io_na_mutex); -} - -static void -connect_admin_qpair(int s, struct nvmf_qpair *qp, struct nvmf_capsule *nc, - const struct nvmf_fabric_connect_data *data) -{ - struct nvme_controller_data cdata; - struct io_controller *ioc; - int error; - - /* Can only have one active I/O controller at a time. */ - pthread_mutex_lock(&io_na_mutex); - if (io_controller != NULL) { - pthread_mutex_unlock(&io_na_mutex); - nvmf_send_error(nc, NVME_SCT_COMMAND_SPECIFIC, - NVMF_FABRIC_SC_CONTROLLER_BUSY); - goto error; - } - - error = nvmf_finish_accept(nc, 2); - if (error != 0) { - pthread_mutex_unlock(&io_na_mutex); - warnc(error, "Failed to send CONNECT response"); - goto error; - } - - ioc = calloc(1, sizeof(*ioc)); - ioc->cntlid = 2; - memcpy(ioc->hostid, data->hostid, sizeof(ioc->hostid)); - memcpy(ioc->hostnqn, data->hostnqn, sizeof(ioc->hostnqn)); - - nvmf_init_io_controller_data(qp, serial, nqn, device_count(), - NVMF_IOCCSZ, &cdata); - - ioc->fp.afi = NVMEF(NVME_FIRMWARE_PAGE_AFI_SLOT, 1); - memcpy(ioc->fp.revision[0], cdata.fr, sizeof(cdata.fr)); - - ioc->hip.power_cycles[0] = 1; - - ioc->c = init_controller(qp, &cdata); - - io_controller = ioc; - pthread_mutex_unlock(&io_na_mutex); - - nvmf_free_capsule(nc); - - handle_admin_qpair(ioc); - close(s); - return; - -error: - nvmf_free_capsule(nc); - close(s); -} - -static void -connect_io_qpair(int s, struct nvmf_qpair *qp, struct nvmf_capsule *nc, - const struct nvmf_fabric_connect_data *data, uint16_t qid) -{ - struct io_controller *ioc; - int error; - - pthread_mutex_lock(&io_na_mutex); - if (io_controller == NULL) { - pthread_mutex_unlock(&io_na_mutex); - warnx("Attempt to create I/O qpair without admin qpair"); - nvmf_send_generic_error(nc, NVME_SC_COMMAND_SEQUENCE_ERROR); - goto error; - } - - if (memcmp(io_controller->hostid, data->hostid, - sizeof(data->hostid)) != 0) { - pthread_mutex_unlock(&io_na_mutex); - warnx("hostid mismatch for I/O qpair CONNECT"); - nvmf_connect_invalid_parameters(nc, true, - offsetof(struct nvmf_fabric_connect_data, hostid)); - goto error; - } - if (le16toh(data->cntlid) != io_controller->cntlid) { - pthread_mutex_unlock(&io_na_mutex); - warnx("cntlid mismatch for I/O qpair CONNECT"); - nvmf_connect_invalid_parameters(nc, true, - offsetof(struct nvmf_fabric_connect_data, cntlid)); - goto error; - } - if (memcmp(io_controller->hostnqn, data->hostnqn, - sizeof(data->hostid)) != 0) { - pthread_mutex_unlock(&io_na_mutex); - warnx("host NQN mismatch for I/O qpair CONNECT"); - nvmf_connect_invalid_parameters(nc, true, - offsetof(struct nvmf_fabric_connect_data, hostnqn)); - goto error; - } - - if (io_controller->num_io_queues == 0) { - pthread_mutex_unlock(&io_na_mutex); - warnx("Attempt to create I/O qpair without enabled queues"); - nvmf_send_generic_error(nc, NVME_SC_COMMAND_SEQUENCE_ERROR); - goto error; - } - if (qid > io_controller->num_io_queues) { - pthread_mutex_unlock(&io_na_mutex); - warnx("Attempt to create invalid I/O qpair %u", qid); - nvmf_connect_invalid_parameters(nc, false, - offsetof(struct nvmf_fabric_connect_cmd, qid)); - goto error; - } - if (io_controller->io_qpairs[qid - 1] != NULL) { - pthread_mutex_unlock(&io_na_mutex); - warnx("Attempt to re-create I/O qpair %u", qid); - nvmf_send_generic_error(nc, NVME_SC_COMMAND_SEQUENCE_ERROR); - goto error; - } - - error = nvmf_finish_accept(nc, io_controller->cntlid); - if (error != 0) { - pthread_mutex_unlock(&io_na_mutex); - warnc(error, "Failed to send CONNECT response"); - goto error; - } - - ioc = io_controller; - ioc->active_io_queues++; - ioc->io_qpairs[qid - 1] = qp; - ioc->io_sockets[qid - 1] = s; - pthread_mutex_unlock(&io_na_mutex); - - nvmf_free_capsule(nc); - - handle_io_qpair(ioc, qp, qid); - return; - -error: - nvmf_free_capsule(nc); - close(s); -} - -static void * -io_socket_thread(void *arg) -{ - struct nvmf_fabric_connect_data data; - struct nvmf_qpair_params qparams; - const struct nvmf_fabric_connect_cmd *cmd; - struct nvmf_capsule *nc; - struct nvmf_qpair *qp; - int s; - - pthread_detach(pthread_self()); - - s = (intptr_t)arg; - memset(&qparams, 0, sizeof(qparams)); - qparams.tcp.fd = s; - - nc = NULL; - qp = nvmf_accept(io_na, &qparams, &nc, &data); - if (qp == NULL) { - warnx("Failed to create I/O qpair: %s", - nvmf_association_error(io_na)); - goto error; - } - - if (kernel_io) { - ctl_handoff_qpair(qp, nvmf_capsule_sqe(nc), &data); - goto error; - } - - if (strcmp(data.subnqn, nqn) != 0) { - warn("I/O qpair with invalid SubNQN: %.*s", - (int)sizeof(data.subnqn), data.subnqn); - nvmf_connect_invalid_parameters(nc, true, - offsetof(struct nvmf_fabric_connect_data, subnqn)); - goto error; - } - - /* Is this an admin or I/O queue pair? */ - cmd = nvmf_capsule_sqe(nc); - if (cmd->qid == 0) - connect_admin_qpair(s, qp, nc, &data); - else - connect_io_qpair(s, qp, nc, &data, le16toh(cmd->qid)); - nvmf_free_qpair(qp); - return (NULL); - -error: - if (nc != NULL) - nvmf_free_capsule(nc); - if (qp != NULL) - nvmf_free_qpair(qp); - close(s); - return (NULL); -} - -void -handle_io_socket(int s) -{ - pthread_t thr; - int error; - - error = pthread_create(&thr, NULL, io_socket_thread, - (void *)(uintptr_t)s); - if (error != 0) { - warnc(error, "Failed to create I/O qpair thread"); - close(s); - } -} diff --git a/usr.sbin/nvmfd/nvmfd.8 b/usr.sbin/nvmfd/nvmfd.8 deleted file mode 100644 index 1076583c417c..000000000000 --- a/usr.sbin/nvmfd/nvmfd.8 +++ /dev/null @@ -1,131 +0,0 @@ -.\" -.\" SPDX-License-Identifier: BSD-2-Clause -.\" -.\" Copyright (c) 2024 Chelsio Communications, Inc. -.\" -.Dd July 25, 2024 -.Dt NVMFD 8 -.Os -.Sh NAME -.Nm nvmfd -.Nd "NVMeoF controller daemon" -.Sh SYNOPSIS -.Nm -.Fl K -.Op Fl dFGg -.Op Fl H Ar MAXH2CDATA -.Op Fl P Ar port -.Op Fl p Ar port -.Op Fl t Ar transport -.Op Fl n Ar subnqn -.Nm -.Op Fl dFGg -.Op Fl H Ar MAXH2CDATA -.Op Fl P Ar port -.Op Fl p Ar port -.Op Fl t Ar transport -.Op Fl n Ar subnqn -.Ar device -.Op Ar device ... -.Sh DESCRIPTION -.Nm -accepts incoming NVMeoF connections for both I/O and discovery controllers. -.Nm -can either implement a single dynamic I/O controller in user mode or hand -off incoming I/O controller connections to -.Xr nvmft 4 . -A dynamic discovery controller service is always provided in user mode. -.Pp -The following options are available: -.Bl -tag -width "-t transport" -.It Fl F -Permit remote hosts to disable SQ flow control. -.It Fl G -Permit remote hosts to enable PDU data digests for the TCP transport. -.It Fl g -Permit remote hosts to enable PDU header digests for the TCP transport. -.It Fl H -Set the MAXH2CDATA value advertised to the remote host for the TCP transport. -This value is in bytes and determines the maximum data payload size for -data PDUs sent by the remote host. -The value must be at least 4096 and defaults to 256KiB. -.It Fl K -Enable kernel mode which hands off incoming I/O controller connections to -.Xr nvmft 4 . -.It Fl P Ar port -Use -.Ar port -as the listen TCP port for the discovery controller service. -The default value is 8009. -.It Fl d -Enable debug mode. -The daemon sends any errors to standard output and does not place -itself in the background. -.It Fl p Ar port -Use -.Ar port -as the listen TCP port for the I/O controller service. -By default an unused ephemeral port will be chosen. -.It Fl n Ar subnqn -The Subsystem NVMe Qualified Name for the I/O controller. -If an explicit NQN is not given, a default value is generated from the -current host's UUID obtained from the -.Vt kern.hostuuid -sysctl. -.It Fl t Ar transport -The transport type to use. -The default transport is -.Dq tcp . -.It Ar device -When implementing a user mode I/O controller, -one or more -.Ar device -arguments must be specified. -Each -.Ar device -describes the backing store for a namespace exported to remote hosts. -Devices can be specified using one of the following syntaxes: -.Bl -tag -width "ramdisk:size" -.It Pa pathname -File or disk device -.It ramdisk : Ns Ar size -Allocate a memory disk with the given -.Ar size . -.Ar size -may use any of the suffixes supported by -.Xr expand_number 3 . -.El -.El -.Sh FILES -.Bl -tag -width "/var/run/nvmfd.pid" -compact -.It Pa /var/run/nvmfd.pid -The default location of the -.Nm -PID file. -.El -.Sh EXIT STATUS -.Ex -std -.Sh SEE ALSO -.Xr ctl 4 , -.Xr nvmft 4 , -.Xr ctladm 8 , -.Xr ctld 8 -.Sh HISTORY -The -.Nm -module first appeared in -.Fx 15.0 . -.Sh AUTHORS -The -.Nm -subsystem was developed by -.An John Baldwin Aq Mt jhb@FreeBSD.org -under sponsorship from Chelsio Communications, Inc. -.Sh BUGS -The discovery controller and kernel mode functionality of -.Nm -should be merged into -.Xr ctld 8 . -.Pp -Additional parameters such as -queue sizes should be configurable. diff --git a/usr.sbin/nvmfd/nvmfd.c b/usr.sbin/nvmfd/nvmfd.c deleted file mode 100644 index df6f400b40e5..000000000000 --- a/usr.sbin/nvmfd/nvmfd.c +++ /dev/null @@ -1,271 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2023-2024 Chelsio Communications, Inc. - * Written by: John Baldwin <jhb@FreeBSD.org> - */ - -#include <sys/param.h> -#include <sys/event.h> -#include <sys/linker.h> -#include <sys/module.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <assert.h> -#include <err.h> -#include <errno.h> -#include <libnvmf.h> -#include <libutil.h> -#include <netdb.h> -#include <signal.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "internal.h" - -bool data_digests = false; -bool header_digests = false; -bool flow_control_disable = false; -bool kernel_io = false; -uint32_t maxh2cdata = 256 * 1024; - -static const char *subnqn; -static volatile bool quit = false; - -static void -usage(void) -{ - fprintf(stderr, "nvmfd -K [-dFGg] [-H MAXH2CDATA] [-P port] [-p port] [-t transport] [-n subnqn]\n" - "nvmfd [-dFGg] [-H MAXH2CDATA] [-P port] [-p port] [-t transport] [-n subnqn]\n" - "\tdevice [device [...]]\n" - "\n" - "Devices use one of the following syntaxes:\n" - "\tpathame - file or disk device\n" - "\tramdisk:size - memory disk of given size\n"); - exit(1); -} - -static void -handle_sig(int sig __unused) -{ - quit = true; -} - -static void -register_listen_socket(int kqfd, int s, void *udata) -{ - struct kevent kev; - - if (listen(s, -1) != 0) - err(1, "listen"); - - EV_SET(&kev, s, EVFILT_READ, EV_ADD, 0, 0, udata); - if (kevent(kqfd, &kev, 1, NULL, 0, NULL) == -1) - err(1, "kevent: failed to add listen socket"); -} - -static void -create_passive_sockets(int kqfd, const char *port, bool discovery) -{ - struct addrinfo hints, *ai, *list; - bool created; - int error, s; - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_PASSIVE; - hints.ai_family = AF_UNSPEC; - hints.ai_protocol = IPPROTO_TCP; - error = getaddrinfo(NULL, port, &hints, &list); - if (error != 0) - errx(1, "%s", gai_strerror(error)); - created = false; - - for (ai = list; ai != NULL; ai = ai->ai_next) { - s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (s == -1) - continue; - - if (bind(s, ai->ai_addr, ai->ai_addrlen) != 0) { - close(s); - continue; - } - - if (discovery) { - register_listen_socket(kqfd, s, (void *)1); - } else { - register_listen_socket(kqfd, s, (void *)2); - discovery_add_io_controller(s, subnqn); - } - created = true; - } - - freeaddrinfo(list); - if (!created) - err(1, "Failed to create any listen sockets"); -} - -static void -handle_connections(int kqfd) -{ - struct kevent ev; - int s; - - signal(SIGHUP, handle_sig); - signal(SIGINT, handle_sig); - signal(SIGQUIT, handle_sig); - signal(SIGTERM, handle_sig); - - while (!quit) { - if (kevent(kqfd, NULL, 0, &ev, 1, NULL) == -1) { - if (errno == EINTR) - continue; - err(1, "kevent"); - } - - assert(ev.filter == EVFILT_READ); - - s = accept(ev.ident, NULL, NULL); - if (s == -1) { - warn("accept"); - continue; - } - - switch ((uintptr_t)ev.udata) { - case 1: - handle_discovery_socket(s); - break; - case 2: - handle_io_socket(s); - break; - default: - __builtin_unreachable(); - } - } -} - -int -main(int ac, char **av) -{ - struct pidfh *pfh; - const char *dport, *ioport, *transport; - pid_t pid; - uint64_t value; - int ch, error, kqfd; - bool daemonize; - static char nqn[NVMF_NQN_MAX_LEN]; - - /* 7.4.9.3 Default port for discovery */ - dport = "8009"; - - pfh = NULL; - daemonize = true; - ioport = "0"; - subnqn = NULL; - transport = "tcp"; - while ((ch = getopt(ac, av, "dFgGH:Kn:P:p:t:")) != -1) { - switch (ch) { - case 'd': - daemonize = false; - break; - case 'F': - flow_control_disable = true; - break; - case 'G': - data_digests = true; - break; - case 'g': - header_digests = true; - break; - case 'H': - if (expand_number(optarg, &value) != 0) - errx(1, "Invalid MAXH2CDATA value %s", optarg); - if (value < 4096 || value > UINT32_MAX || - value % 4 != 0) - errx(1, "Invalid MAXH2CDATA value %s", optarg); - maxh2cdata = value; - break; - case 'K': - kernel_io = true; - break; - case 'n': - subnqn = optarg; - break; - case 'P': - dport = optarg; - break; - case 'p': - ioport = optarg; - break; - case 't': - transport = optarg; - break; - default: - usage(); - } - } - - av += optind; - ac -= optind; - - if (kernel_io) { - if (ac > 0) - usage(); - if (modfind("nvmft") == -1 && kldload("nvmft") == -1) - warn("couldn't load nvmft"); - } else { - if (ac < 1) - usage(); - } - - if (strcasecmp(transport, "tcp") == 0) { - } else - errx(1, "Invalid transport %s", transport); - - if (subnqn == NULL) { - error = nvmf_nqn_from_hostuuid(nqn); - if (error != 0) - errc(1, error, "Failed to generate NQN"); - subnqn = nqn; - } - - if (!kernel_io) - register_devices(ac, av); - - init_discovery(); - init_io(subnqn); - - if (daemonize) { - pfh = pidfile_open(NULL, 0600, &pid); - if (pfh == NULL) { - if (errno == EEXIST) - errx(1, "Daemon already running, pid: %jd", - (intmax_t)pid); - warn("Cannot open or create pidfile"); - } - - if (daemon(0, 0) != 0) { - pidfile_remove(pfh); - err(1, "Failed to fork into the background"); - } - - pidfile_write(pfh); - } - - kqfd = kqueue(); - if (kqfd == -1) { - pidfile_remove(pfh); - err(1, "kqueue"); - } - - create_passive_sockets(kqfd, dport, true); - create_passive_sockets(kqfd, ioport, false); - - handle_connections(kqfd); - shutdown_io(); - if (pfh != NULL) - pidfile_remove(pfh); - return (0); -} diff --git a/usr.sbin/rpc.ypupdated/Makefile b/usr.sbin/rpc.ypupdated/Makefile deleted file mode 100644 index 78ee19fc7a6d..000000000000 --- a/usr.sbin/rpc.ypupdated/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -.PATH: ${SRCTOP}/usr.sbin/ypserv ${SRCTOP}/libexec/ypxfr - -PACKAGE=yp -PROG= rpc.ypupdated -MAN= -SRCS= ypupdate_prot_svc.c ypupdate_prot.h ypupdated_main.c \ - yp_error.c update.c ypupdated_server.c \ - yp_dblookup.c yp_dbwrite.c yp_dbdelete.c yp_dbupdate.c - -#CFLAGS+= -DYP -CFLAGS+= -I${SRCTOP}/usr.sbin/ypserv -I. -I${SRCTOP}/libexec/ypxfr - -WARNS?= 1 - -LIBADD= rpcsvc - -CLEANFILES= ypupdate_prot_svc.c ypupdate_prot.h - -RPCDIR= ${SYSROOT:U${DESTDIR}}/usr/include/rpcsvc -RPCGEN= RPCGEN_CPP=${CPP:Q} rpcgen -I -C - -# We need to remove the 'static' keyword from _rpcsvcstate so that -# ypupdated_main.c can see it. -ypupdate_prot_svc.c: ${RPCDIR}/ypupdate_prot.x - rm -f ${.TARGET} - ${RPCGEN} -m ${.ALLSRC} | \ - sed s/"static int _rpcsvcstate"/"int _rpcsvcstate"/g > ${.TARGET} - -ypupdate_prot.h: ${RPCDIR}/ypupdate_prot.x - ${RPCGEN} -h -o ${.TARGET} ${.ALLSRC} - -.include <bsd.prog.mk> diff --git a/usr.sbin/rpc.ypupdated/Makefile.depend b/usr.sbin/rpc.ypupdated/Makefile.depend deleted file mode 100644 index 352a225b19c6..000000000000 --- a/usr.sbin/rpc.ypupdated/Makefile.depend +++ /dev/null @@ -1,18 +0,0 @@ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - include \ - include/rpc \ - include/rpcsvc \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - lib/librpcsvc \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/usr.sbin/rpc.ypupdated/update.c b/usr.sbin/rpc.ypupdated/update.c deleted file mode 100644 index 332ed752acc4..000000000000 --- a/usr.sbin/rpc.ypupdated/update.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user or with the express written consent of - * Sun Microsystems, Inc. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -/* - * Copyright (C) 1986, 1989, Sun Microsystems, Inc. - */ - -/* - * Administrative tool to add a new user to the publickey database - */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <rpc/rpc.h> -#include <rpc/key_prot.h> -#ifdef YP -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> -#include <sys/wait.h> -#include <netdb.h> -#endif /* YP */ -#include <pwd.h> -#include <string.h> -#include <sys/resource.h> -#include "ypupdated_extern.h" - -#ifdef YP -#define MAXMAPNAMELEN 256 -#else -#define YPOP_CHANGE 1 /* change, do not add */ -#define YPOP_INSERT 2 /* add, do not change */ -#define YPOP_DELETE 3 /* delete this entry */ -#define YPOP_STORE 4 /* add, or change */ -#endif - -#ifdef YP -static char SHELL[] = "/bin/sh"; -static char YPDBPATH[]="/var/yp"; /* This is defined but not used! */ -static char PKMAP[] = "publickey.byname"; -static char UPDATEFILE[] = "updaters"; -static char PKFILE[] = "/etc/publickey"; -#endif /* YP */ - -#ifdef YP -static int _openchild(char *, FILE **, FILE **); - -/* - * Determine if requester is allowed to update the given map, - * and update it if so. Returns the yp status, which is zero - * if there is no access violation. - */ -int -mapupdate(char *requester, char *mapname, u_int op, u_int keylen, char *key, - u_int datalen, char *data) -{ - char updater[MAXMAPNAMELEN + 40]; - FILE *childargs; - FILE *childrslt; -#ifdef WEXITSTATUS - int status; -#else - union wait status; -#endif - pid_t pid; - u_int yperrno; - - -#ifdef DEBUG - printf("%s %s\n", key, data); -#endif - (void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */ - UPDATEFILE, mapname); - pid = _openchild(updater, &childargs, &childrslt); - if (pid < 0) { - return (YPERR_YPERR); - } - - /* - * Write to child - */ - (void)fprintf(childargs, "%s\n", requester); - (void)fprintf(childargs, "%u\n", op); - (void)fprintf(childargs, "%u\n", keylen); - (void)fwrite(key, (int)keylen, 1, childargs); - (void)fprintf(childargs, "\n"); - (void)fprintf(childargs, "%u\n", datalen); - (void)fwrite(data, (int)datalen, 1, childargs); - (void)fprintf(childargs, "\n"); - (void)fclose(childargs); - - /* - * Read from child - */ - (void)fscanf(childrslt, "%d", &yperrno); - (void)fclose(childrslt); - - (void)wait(&status); -#ifdef WEXITSTATUS - if (WEXITSTATUS(status) != 0) -#else - if (status.w_retcode != 0) -#endif - return (YPERR_YPERR); - return (yperrno); -} - -/* - * returns pid, or -1 for failure - */ -static int -_openchild(char *command, FILE **fto, FILE **ffrom) -{ - int i; - pid_t pid; - int pdto[2]; - int pdfrom[2]; - char *com; - struct rlimit rl; - - if (pipe(pdto) < 0) { - goto error1; - } - if (pipe(pdfrom) < 0) { - goto error2; - } - switch (pid = fork()) { - case -1: - goto error3; - - case 0: - /* - * child: read from pdto[0], write into pdfrom[1] - */ - (void)close(0); - (void)dup(pdto[0]); - (void)close(1); - (void)dup(pdfrom[1]); - getrlimit(RLIMIT_NOFILE, &rl); - for (i = rl.rlim_max - 1; i >= 3; i--) { - (void) close(i); - } - com = malloc((unsigned) strlen(command) + 6); - if (com == NULL) { - _exit(~0); - } - (void)sprintf(com, "exec %s", command); - execl(SHELL, basename(SHELL), "-c", com, (char *)NULL); - _exit(~0); - - default: - /* - * parent: write into pdto[1], read from pdfrom[0] - */ - *fto = fdopen(pdto[1], "w"); - (void)close(pdto[0]); - *ffrom = fdopen(pdfrom[0], "r"); - (void)close(pdfrom[1]); - break; - } - return (pid); - - /* - * error cleanup and return - */ -error3: - (void)close(pdfrom[0]); - (void)close(pdfrom[1]); -error2: - (void)close(pdto[0]); - (void)close(pdto[1]); -error1: - return (-1); -} - -static char * -basename(char *path) -{ - char *p; - - p = strrchr(path, '/'); - if (p == NULL) { - return (path); - } else { - return (p + 1); - } -} - -#else /* YP */ - -static int match(char *, char *); - -/* - * Determine if requester is allowed to update the given map, - * and update it if so. Returns the status, which is zero - * if there is no access violation. This function updates - * the local file and then shuts up. - */ -int -localupdate(char *name, char *filename, u_int op, u_int keylen __unused, - char *key, u_int datalen __unused, char *data) -{ - char line[256]; - FILE *rf; - FILE *wf; - char *tmpname; - int err; - - /* - * Check permission - */ - if (strcmp(name, key) != 0) { - return (ERR_ACCESS); - } - if (strcmp(name, "nobody") == 0) { - /* - * Can't change "nobody"s key. - */ - return (ERR_ACCESS); - } - - /* - * Open files - */ - tmpname = malloc(strlen(filename) + 4); - if (tmpname == NULL) { - return (ERR_MALLOC); - } - sprintf(tmpname, "%s.tmp", filename); - rf = fopen(filename, "r"); - if (rf == NULL) { - err = ERR_READ; - goto cleanup; - } - wf = fopen(tmpname, "w"); - if (wf == NULL) { - fclose(rf); - err = ERR_WRITE; - goto cleanup; - } - err = -1; - while (fgets(line, sizeof (line), rf)) { - if (err < 0 && match(line, name)) { - switch (op) { - case YPOP_INSERT: - err = ERR_KEY; - break; - case YPOP_STORE: - case YPOP_CHANGE: - fprintf(wf, "%s %s\n", key, data); - err = 0; - break; - case YPOP_DELETE: - /* do nothing */ - err = 0; - break; - } - } else { - fputs(line, wf); - } - } - if (err < 0) { - switch (op) { - case YPOP_CHANGE: - case YPOP_DELETE: - err = ERR_KEY; - break; - case YPOP_INSERT: - case YPOP_STORE: - err = 0; - fprintf(wf, "%s %s\n", key, data); - break; - } - } - fclose(wf); - fclose(rf); - if (err == 0) { - if (rename(tmpname, filename) < 0) { - err = ERR_DBASE; - goto cleanup; - } - } else { - if (unlink(tmpname) < 0) { - err = ERR_DBASE; - goto cleanup; - } - } -cleanup: - free(tmpname); - return (err); -} - -static int -match(char *line, char *name) -{ - int len; - - len = strlen(name); - return (strncmp(line, name, len) == 0 && - (line[len] == ' ' || line[len] == '\t')); -} -#endif /* !YP */ diff --git a/usr.sbin/rpc.ypupdated/yp_dbdelete.c b/usr.sbin/rpc.ypupdated/yp_dbdelete.c deleted file mode 100644 index d07a8fcd2ff9..000000000000 --- a/usr.sbin/rpc.ypupdated/yp_dbdelete.c +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-4-Clause - * - * Copyright (c) 1995, 1996 - * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> -#include <limits.h> -#include <unistd.h> -#include <db.h> -#include <sys/stat.h> -#include <errno.h> -#include <paths.h> -#include <rpcsvc/yp.h> -#include "ypxfr_extern.h" - -int -yp_del_record(DB *dbp, DBT *key) -{ - int rval; - - if ((rval = (dbp->del)(dbp,key,0))) { - switch (rval) { - case 1: - return(YP_FALSE); - break; - case -1: - default: - (void)(dbp->close)(dbp); - return(YP_BADDB); - break; - } - } - - return(YP_TRUE); -} diff --git a/usr.sbin/rpc.ypupdated/yp_dbupdate.c b/usr.sbin/rpc.ypupdated/yp_dbupdate.c deleted file mode 100644 index af17bf5244ef..000000000000 --- a/usr.sbin/rpc.ypupdated/yp_dbupdate.c +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-4-Clause - * - * Copyright (c) 1996 - * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#include <sys/fcntl.h> - -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <limits.h> -#include <db.h> -#include <unistd.h> -#include <rpcsvc/ypclnt.h> -#include <rpcsvc/ypupdate_prot.h> -#include "ypxfr_extern.h" -#include "ypupdated_extern.h" - -static int -yp_domake(char *map, char *domain) -{ - int pid; - - switch ((pid = fork())) { - case 0: - execlp(MAP_UPDATE_PATH, MAP_UPDATE, map, domain, (char *)NULL); - yp_error("couldn't exec map update process: %s", - strerror(errno)); - exit(1); - break; - case -1: - yp_error("fork() failed: %s", strerror(errno)); - return(YPERR_YPERR); - break; - default: - children++; - break; - } - - return(0); -} - -int -ypmap_update(char *netname, char *map, unsigned int op, unsigned int keylen, - char *keyval, unsigned int datlen, char *datval) -{ - DB *dbp; - DBT key = { NULL, 0 }, data = { NULL, 0 }; - char *yp_last = "YP_LAST_MODIFIED"; - char yplastbuf[32]; - char *domptr; - int rval = 0; - - if ((domptr = strchr(netname, '@')) == NULL) - return(ERR_ACCESS); - domptr++; - - - dbp = yp_open_db_rw(domptr, map, O_RDWR); - if (dbp == NULL) - return(ERR_DBASE); - - key.data = keyval; - key.size = keylen; - data.data = datval; - data.size = datlen; - - switch (op) { - case YPOP_DELETE: /* delete this entry */ - rval = yp_del_record(dbp, &key); - if (rval == YP_TRUE) - rval = 0; - break; - case YPOP_INSERT: /* add, do not change */ - rval = yp_put_record(dbp, &key, &data, 0); - if (rval == YP_TRUE) - rval = 0; - break; - case YPOP_STORE: /* add, or change */ - rval = yp_put_record(dbp, &key, &data, 1); - if (rval == YP_TRUE) - rval = 0; - break; - case YPOP_CHANGE: /* change, do not add */ - if (yp_get_record(domptr, map, &key, &data, 0) != YP_TRUE) { - rval = ERR_KEY; - break; - } - rval = yp_put_record(dbp, &key, &data, 1); - if (rval == YP_TRUE) - rval = 0; - break; - default: - yp_error("unknown update command: (%d)", op); - } - - if (rval) { - (void)(dbp->close)(dbp); - return(rval); - } - - snprintf(yplastbuf, sizeof(yplastbuf), "%jd", (intmax_t)time(NULL)); - key.data = yp_last; - key.size = strlen(yp_last); - data.data = (char *)&yplastbuf; - data.size = strlen(yplastbuf); - if (yp_put_record(dbp, &key, &data, 1) != YP_TRUE) { - yp_error("failed to update timestamp in %s/%s", domptr, map); - (void)(dbp->close)(dbp); - return(ERR_DBASE); - } - - (void)(dbp->close)(dbp); - return(yp_domake(map, domptr)); -} diff --git a/usr.sbin/rpc.ypupdated/ypupdate b/usr.sbin/rpc.ypupdated/ypupdate deleted file mode 100755 index 8795ef3baf80..000000000000 --- a/usr.sbin/rpc.ypupdated/ypupdate +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# -# This script is invoked by rpc.ypupdatedd to propagate NIS maps -# after the master map databases have been modified. It expects -# to be passed two arguments: the name of the map that was updated -# and the name of the domain where the map resides. -# These are passed to /var/yp/Makefile. -# -# Comment out the LOG=yes line to disable logging. -# -# - -LOG=yes -LOGFILE=/var/yp/ypupdate.log - -umask 077 - -if [ ! -f $LOGFILE ]; -then - /usr/bin/touch $LOGFILE - echo "# Edit /usr/libexec/yppwupdate to disable" >> $LOGFILE - echo "# logging to this file from yppasswdd." >> $LOGFILE - echo -n "# Log started on: " >> $LOGFILE - /bin/date >> $LOGFILE -fi - -if [ ! $LOG ]; -then - cd /var/yp/$2; /usr/bin/make -f ../Makefile $1 2>&1 -else - cd /var/yp/$2; /usr/bin/make -f ../Makefile $1 >> $LOGFILE -fi diff --git a/usr.sbin/rpc.ypupdated/ypupdated_extern.h b/usr.sbin/rpc.ypupdated/ypupdated_extern.h deleted file mode 100644 index 90968df36748..000000000000 --- a/usr.sbin/rpc.ypupdated/ypupdated_extern.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - */ - -#include <db.h> - -#define YPOP_CHANGE 1 /* change, do not add */ -#define YPOP_INSERT 2 /* add, do not change */ -#define YPOP_DELETE 3 /* delete this entry */ -#define YPOP_STORE 4 /* add, or change */ - -#define ERR_ACCESS 1 -#define ERR_MALLOC 2 -#define ERR_READ 3 -#define ERR_WRITE 4 -#define ERR_DBASE 5 -#define ERR_KEY 6 - -#ifndef YPLIBDIR -#define YPLIBDIR "/usr/libexec/" -#endif - -#ifndef MAP_UPPATE -#define MAP_UPDATE "ypupdate" -#endif - -#define MAP_UPDATE_PATH YPLIBDIR MAP_UPDATE - -extern int children; -extern void ypu_prog_1(struct svc_req *, register SVCXPRT *); -extern int localupdate(char *, char *, u_int, u_int, char *, u_int, char *); -extern int ypmap_update(char *, char *, u_int, u_int, char *, u_int, char *); -extern int yp_del_record(DB *, DBT *); diff --git a/usr.sbin/rpc.ypupdated/ypupdated_main.c b/usr.sbin/rpc.ypupdated/ypupdated_main.c deleted file mode 100644 index dae956594da0..000000000000 --- a/usr.sbin/rpc.ypupdated/ypupdated_main.c +++ /dev/null @@ -1,287 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-4-Clause - * - * Copyright (c) 1995, 1996 - * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#include "ypupdate_prot.h" -#include <stdio.h> -#include <stdlib.h> /* getenv, exit */ -#include <rpc/pmap_clnt.h> /* for pmap_unset */ -#include <rpc/rpc_com.h> -#include <string.h> /* strcmp */ -#include <signal.h> -#ifdef __cplusplus -#include <sysent.h> /* getdtablesize, open */ -#endif /* __cplusplus */ -#include <memory.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <syslog.h> -#include <sys/wait.h> -#include <errno.h> -#include <err.h> -#include <unistd.h> -#include "ypupdated_extern.h" -#include "yp_extern.h" - -#ifndef SIG_PF -#define SIG_PF void(*)(int) -#endif - -#ifdef DEBUG -#define RPC_SVC_FG -#endif - -#define _RPCSVC_CLOSEDOWN 120 -int _rpcpmstart; /* Started by a port monitor ? */ -static int _rpcfdtype; - /* Whether Stream or Datagram ? */ - /* States a server can be in wrt request */ - -#define _IDLE 0 -#define _SERVED 1 -#define _SERVING 2 - -extern int _rpcsvcstate; /* Set when a request is serviced */ - -int debug; - -char *progname = "rpc.ypupdated"; -char *yp_dir = "/var/yp/"; - -static void -_msgout(char* msg) -{ -#ifdef RPC_SVC_FG - if (_rpcpmstart) - syslog(LOG_ERR, "%s", msg); - else - warnx("%s", msg); -#else - syslog(LOG_ERR, "%s", msg); -#endif -} - -static void -closedown(int sig) -{ - if (_rpcsvcstate == _IDLE) { - extern fd_set svc_fdset; - static int size; - int i, openfd; - - if (_rpcfdtype == SOCK_DGRAM) - exit(0); - if (size == 0) { - size = getdtablesize(); - } - for (i = 0, openfd = 0; i < size && openfd < 2; i++) - if (FD_ISSET(i, &svc_fdset)) - openfd++; - if (openfd <= 1) - exit(0); - } - if (_rpcsvcstate == _SERVED) - _rpcsvcstate = _IDLE; - - (void) signal(SIGALRM, (SIG_PF) closedown); - (void) alarm(_RPCSVC_CLOSEDOWN/2); -} - -static void -ypupdated_svc_run(void) -{ -#ifdef FD_SETSIZE - fd_set readfds; -#else - int readfds; -#endif /* def FD_SETSIZE */ - extern int forked; - int pid; - int fd_setsize = _rpc_dtablesize(); - - /* Establish the identity of the parent ypupdated process. */ - pid = getpid(); - - for (;;) { -#ifdef FD_SETSIZE - readfds = svc_fdset; -#else - readfds = svc_fds; -#endif /* def FD_SETSIZE */ - switch (select(fd_setsize, &readfds, NULL, NULL, - (struct timeval *)0)) { - case -1: - if (errno == EINTR) { - continue; - } - warn("svc_run: - select failed"); - return; - case 0: - continue; - default: - svc_getreqset(&readfds); - if (forked && pid != getpid()) - exit(0); - } - } -} - -static void -reaper(int sig) -{ - int status; - - if (sig == SIGHUP) { -#ifdef foo - load_securenets(); -#endif - return; - } - - if (sig == SIGCHLD) { - while (wait3(&status, WNOHANG, NULL) > 0) - children--; - } else { - (void) pmap_unset(YPU_PROG, YPU_VERS); - exit(0); - } -} - -void -usage(void) -{ - fprintf(stderr, "rpc.ypupdatedd [-p path]\n"); - exit(0); -} - -int -main(int argc, char *argv[]) -{ - register SVCXPRT *transp = NULL; - int sock; - int proto = 0; - struct sockaddr_in saddr; - int asize = sizeof (saddr); - int ch; - - while ((ch = getopt(argc, argv, "p:h")) != -1) { - switch (ch) { - case 'p': - yp_dir = optarg; - break; - default: - usage(); - break; - } - } -#ifdef foo - load_securenets(); -#endif - - if (svc_auth_reg(AUTH_DES, _svcauth_des) == -1) { - yp_error("failed to register AUTH_DES flavor"); - exit(1); - } - - if (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) { - int ssize = sizeof (int); - - if (saddr.sin_family != AF_INET) - exit(1); - if (getsockopt(0, SOL_SOCKET, SO_TYPE, - (char *)&_rpcfdtype, &ssize) == -1) - exit(1); - sock = 0; - _rpcpmstart = 1; - proto = 0; - openlog("rpc.ypupdatedd", LOG_PID, LOG_DAEMON); - } else { -#ifndef RPC_SVC_FG - if (daemon(0,0)) { - err(1, "cannot fork"); - } - openlog("rpc.ypupdated", LOG_PID, LOG_DAEMON); -#endif - sock = RPC_ANYSOCK; - (void) pmap_unset(YPU_PROG, YPU_VERS); - } - - if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) { - transp = svcudp_create(sock); - if (transp == NULL) { - _msgout("cannot create udp service."); - exit(1); - } - if (!_rpcpmstart) - proto = IPPROTO_UDP; - if (!svc_register(transp, YPU_PROG, YPU_VERS, ypu_prog_1, proto)) { - _msgout("unable to register (YPU_PROG, YPU_VERS, udp)."); - exit(1); - } - } - - if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) { - transp = svctcp_create(sock, 0, 0); - if (transp == NULL) { - _msgout("cannot create tcp service."); - exit(1); - } - if (!_rpcpmstart) - proto = IPPROTO_TCP; - if (!svc_register(transp, YPU_PROG, YPU_VERS, ypu_prog_1, proto)) { - _msgout("unable to register (YPU_PROG, YPU_VERS, tcp)."); - exit(1); - } - } - - if (transp == (SVCXPRT *)NULL) { - _msgout("could not create a handle"); - exit(1); - } - if (_rpcpmstart) { - (void) signal(SIGALRM, (SIG_PF) closedown); - (void) alarm(_RPCSVC_CLOSEDOWN/2); - } - - (void) signal(SIGPIPE, SIG_IGN); - (void) signal(SIGCHLD, (SIG_PF) reaper); - (void) signal(SIGTERM, (SIG_PF) reaper); - (void) signal(SIGINT, (SIG_PF) reaper); - (void) signal(SIGHUP, (SIG_PF) reaper); - - ypupdated_svc_run(); - _msgout("svc_run returned"); - exit(1); - /* NOTREACHED */ -} diff --git a/usr.sbin/rpc.ypupdated/ypupdated_server.c b/usr.sbin/rpc.ypupdated/ypupdated_server.c deleted file mode 100644 index 47e52401cd6e..000000000000 --- a/usr.sbin/rpc.ypupdated/ypupdated_server.c +++ /dev/null @@ -1,227 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-4-Clause - * - * Copyright (c) 1995, 1996 - * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * ypupdate server implementation - * - * Written by Bill Paul <wpaul@ctr.columbia.edu> - * Center for Telecommunications Research - * Columbia University, New York City - */ - -#include <sys/cdefs.h> -#include <stdio.h> -#include <rpc/rpc.h> -#include <rpc/key_prot.h> -#include <sys/param.h> -#include <rpcsvc/yp.h> -#include "ypupdate_prot.h" -#include "ypupdated_extern.h" -#include "yp_extern.h" -#include "ypxfr_extern.h" - -int children = 0; -int forked = 0; - -/* - * Try to avoid spoofing: if a client chooses to use a very large - * window and then tries a bunch of randomly chosen encrypted timestamps, - * there's a chance he might stumble onto a valid combination. - * We therefore reject any RPCs with a window size larger than a preset - * value. - */ -#ifndef WINDOW -#define WINDOW (60*60) -#endif - -static enum auth_stat -yp_checkauth(struct svc_req *svcreq) -{ - struct authdes_cred *des_cred; - - switch (svcreq->rq_cred.oa_flavor) { - case AUTH_DES: - des_cred = (struct authdes_cred *) svcreq->rq_clntcred; - if (des_cred->adc_fullname.window > WINDOW) { - yp_error("warning: client-specified window size \ -was too large -- possible spoof attempt"); - return(AUTH_BADCRED); - } - return(AUTH_OK); - break; - case AUTH_UNIX: - case AUTH_NONE: - yp_error("warning: client didn't use DES authentication"); - return(AUTH_TOOWEAK); - break; - default: - yp_error("client used unknown auth flavor"); - return(AUTH_REJECTEDCRED); - break; - } -} - -unsigned int * -ypu_change_1_svc(struct ypupdate_args *args, struct svc_req *svcreq) -{ - struct authdes_cred *des_cred; - static int res; - char *netname; - enum auth_stat astat; - - res = 0; - - astat = yp_checkauth(svcreq); - - if (astat != AUTH_OK) { - svcerr_auth(svcreq->rq_xprt, astat); - return(&res); - } - - des_cred = (struct authdes_cred *) svcreq->rq_clntcred; - netname = des_cred->adc_fullname.name; - - res = localupdate(netname, "/etc/publickey", YPOP_CHANGE, - args->key.yp_buf_len, args->key.yp_buf_val, - args->datum.yp_buf_len, args->datum.yp_buf_val); - - if (res) - return (&res); - - res = ypmap_update(netname, args->mapname, YPOP_CHANGE, - args->key.yp_buf_len, args->key.yp_buf_val, - args->datum.yp_buf_len, args->datum.yp_buf_val); - - return (&res); -} - -unsigned int * -ypu_insert_1_svc(struct ypupdate_args *args, struct svc_req *svcreq) -{ - struct authdes_cred *des_cred; - static int res; - char *netname; - enum auth_stat astat; - - res = 0; - - astat = yp_checkauth(svcreq); - - if (astat != AUTH_OK) { - svcerr_auth(svcreq->rq_xprt, astat); - return(&res); - } - - des_cred = (struct authdes_cred *) svcreq->rq_clntcred; - netname = des_cred->adc_fullname.name; - - res = localupdate(netname, "/etc/publickey", YPOP_INSERT, - args->key.yp_buf_len, args->key.yp_buf_val, - args->datum.yp_buf_len, args->datum.yp_buf_val); - - if (res) - return (&res); - - res = ypmap_update(netname, args->mapname, YPOP_INSERT, - args->key.yp_buf_len, args->key.yp_buf_val, - args->datum.yp_buf_len, args->datum.yp_buf_val); - - return (&res); -} - -unsigned int * -ypu_delete_1_svc(struct ypdelete_args *args, struct svc_req *svcreq) -{ - struct authdes_cred *des_cred; - static int res; - char *netname; - enum auth_stat astat; - - res = 0; - - astat = yp_checkauth(svcreq); - - if (astat != AUTH_OK) { - svcerr_auth(svcreq->rq_xprt, astat); - return(&res); - } - - des_cred = (struct authdes_cred *) svcreq->rq_clntcred; - netname = des_cred->adc_fullname.name; - - res = localupdate(netname, "/etc/publickey", YPOP_DELETE, - args->key.yp_buf_len, args->key.yp_buf_val, - 0, NULL); - - if (res) - return (&res); - - res = ypmap_update(netname, args->mapname, YPOP_DELETE, - args->key.yp_buf_len, args->key.yp_buf_val, - 0, NULL); - - return (&res); -} - -unsigned int * -ypu_store_1_svc(struct ypupdate_args *args, struct svc_req *svcreq) -{ - struct authdes_cred *des_cred; - static int res; - char *netname; - enum auth_stat astat; - - res = 0; - - astat = yp_checkauth(svcreq); - - if (astat != AUTH_OK) { - svcerr_auth(svcreq->rq_xprt, astat); - return(&res); - } - - des_cred = (struct authdes_cred *) svcreq->rq_clntcred; - netname = des_cred->adc_fullname.name; - - res = localupdate(netname, "/etc/publickey", YPOP_STORE, - args->key.yp_buf_len, args->key.yp_buf_val, - args->datum.yp_buf_len, args->datum.yp_buf_val); - - if (res) - return (&res); - - res = ypmap_update(netname, args->mapname, YPOP_STORE, - args->key.yp_buf_len, args->key.yp_buf_val, - args->datum.yp_buf_len, args->datum.yp_buf_val); - - return (&res); -} |