From nobody Tue Jan 24 22:14:28 2023 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4P1h8h55V3z3bgw9; Tue, 24 Jan 2023 22:14:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4P1h8h3r1bz3Lc1; Tue, 24 Jan 2023 22:14:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1674598468; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=n7A3U5DiSa4nufDRb+hhQtyv3WU2BjaOlgXScy2UqLQ=; b=lDf1sPkTjQbXrDViQHAY1SCdmfu/axDIjOUuCW3XJH803Za47h6LkjcSjPRijsILRgRi7N pcar693q1RranLq9u0VwVSWESFSn6OX/1cLXg2Lp1vB0xMQr2c/x5gNG6gnGa7+5Aw6l+y CMQAMuy8wR6GX2xeX0APIF1IriR/vxEJ7qMWA/s/lvcwBnaP+AIK+PF0eII1L/DYZfrG0Z IRQ/FDXVd8RGxoxmhAX0F56iDxGXoKaVARGeb3vi2gIo/Txhafl5M/YD6895Ceno7oM9/R knitUY09xNwdIAAtYDIxDBg2zjXVMUZuj1C4Rf3S9rmbJtZ2OhShZD//ntZg+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1674598468; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=n7A3U5DiSa4nufDRb+hhQtyv3WU2BjaOlgXScy2UqLQ=; b=a6b0z+5/6iiDu99JvMCRygUJ37qIVfNrcjrY7cr5XVPeaHH15HReHI24utz5iogGvjIkL4 07wjBw4FqACJOYSvNu9vT40fG8MlrXcR2vsaJApcSSNyz+vlqXZ9cD3PkU3JikXA8Oyi/z 8INsGbld69CrPVdclpvSPbyTALnd6wIS8s9vU/481n+ETckvZYJS3+6+nGCiB2akcXyUVL PR7GK71WmeKjGUkd0lOrqteUDGGcjb3O/QHoTiDmjOuDe+bYXPdKze8Yb6je281XBZJTay XeJBxoMFmYDcti/YZAhEymkmrw4mnyK02ekMYquM5OXulcewFi/LnO1of+kSjg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1674598468; a=rsa-sha256; cv=none; b=oqsoiRah2ThmiYDOpU08/aUEcWfbP+xQr3W+uVAMQtqh/K3+AQNRW28QeN+lPC0KFkRqTK eNTZfSI4eS0TXCowsfaaKPwA+hmpqoi20wTVaplvHcG2m85R/dMvCiRntN/TDZZq11nr1T 4jIrwceFb9a+UvemirKrGA++l7hf0VmX1Y2RsYxShOe0Vht/vbvqJ0WBxXUAyAlW9kreYd HZhDDhlhJYKuk6lvNT72eYpAnpffA39DZAIWYAjx5PtwJFqj9uhDscq2GmNK8Sk1vf7IMQ AekVl9s96NZhiXsHW1GbnkzERBhdd2OHUfbv7h3AkuPcRtMQszVWYCo97FzmBA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4P1h8h2xySzQhM; Tue, 24 Jan 2023 22:14:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 30OMESGk089863; Tue, 24 Jan 2023 22:14:28 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 30OMESZU089862; Tue, 24 Jan 2023 22:14:28 GMT (envelope-from git) Date: Tue, 24 Jan 2023 22:14:28 GMT Message-Id: <202301242214.30OMESZU089862@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Warner Losh Subject: git: 85ce7697ca58 - stable/13 - kboot: Rework hostdisk.c to allow easier ZFS support. List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: imp X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 85ce7697ca5850a37086c1bbfc825103fb25c052 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=85ce7697ca5850a37086c1bbfc825103fb25c052 commit 85ce7697ca5850a37086c1bbfc825103fb25c052 Author: Warner Losh AuthorDate: 2023-01-13 21:20:09 +0000 Commit: Warner Losh CommitDate: 2023-01-24 21:49:46 +0000 kboot: Rework hostdisk.c to allow easier ZFS support. Keep a list of disks and partitions that we have. Keep track of the sizes of the media and sector and use that to implement DIOCGMEDIASIZE and DIOCGSECTORSIZE. Proivde a way to lookup disks by name. Sponsored by: Netflix Reviewed by: kevans (prior version) Differential Revision: https://reviews.freebsd.org/D38013 (cherry picked from commit 1a13008e9874748958a3415a3d0c34b95acbf2e2) --- stand/kboot/hostdisk.c | 137 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 114 insertions(+), 23 deletions(-) diff --git a/stand/kboot/hostdisk.c b/stand/kboot/hostdisk.c index 628450ef8bb5..cbe8faabca96 100644 --- a/stand/kboot/hostdisk.c +++ b/stand/kboot/hostdisk.c @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include "host_syscall.h" #include "kboot.h" @@ -40,6 +41,7 @@ static int hostdisk_close(struct open_file *f); static int hostdisk_ioctl(struct open_file *f, u_long cmd, void *data); static int hostdisk_print(int verbose); static char *hostdisk_fmtdev(struct devdesc *vdev); +static int hostdisk_parsedev(struct devdesc **idev, const char *devspec, const char **path); struct devsw hostdisk = { .dv_name = "/dev", @@ -52,6 +54,7 @@ struct devsw hostdisk = { .dv_print = hostdisk_print, .dv_cleanup = nullsys, .dv_fmtdev = hostdisk_fmtdev, + .dv_parsedev = hostdisk_parsedev, }; /* @@ -67,13 +70,16 @@ typedef struct hdinfo { STAILQ_ENTRY(hdinfo) hd_link; /* link in device list */ hdinfo_list_t hd_children; struct hdinfo *hd_parent; - const char *hd_name; - uint64_t hd_size; + const char *hd_dev; + uint64_t hd_size; /* In bytes */ uint64_t hd_sectors; uint64_t hd_sectorsize; int hd_flags; } hdinfo_t; +#define dev2hd(d) ((hdinfo_t *)d->d_opendata) +#define hd_name(hd) ((hd->hd_dev + 5)) + static hdinfo_list_t hdinfo = STAILQ_HEAD_INITIALIZER(hdinfo); typedef bool fef_cb_t(struct host_dirent64 *, void *); @@ -107,14 +113,20 @@ foreach_file(const char *dir, fef_cb_t cb, void *argp, u_int flags) } static void -hostdisk_add_part(struct hdinfo *hd, const char *drv, uint64_t secs) +hostdisk_add_part(hdinfo_t *hd, const char *drv, uint64_t secs) { - struct hdinfo *md; + hdinfo_t *md; + char *dev; - printf("hd %s adding %s %ju\n", hd->hd_name, drv, (uintmax_t)secs); + printf("hd %s adding %s %ju\n", hd->hd_dev, drv, (uintmax_t)secs); if ((md = calloc(1, sizeof(*md))) == NULL) return; - md->hd_name = strdup(drv); + if (asprintf(&dev, "/dev/%s", drv) == -1) { + printf("hostdisk: no memory\n"); + free(md); + return; + } + md->hd_dev = dev; md->hd_sectors = secs; md->hd_sectorsize = hd->hd_sectorsize; md->hd_size = md->hd_sectors * md->hd_sectorsize; @@ -125,15 +137,16 @@ hostdisk_add_part(struct hdinfo *hd, const char *drv, uint64_t secs) static bool hostdisk_one_part(struct host_dirent64 *dent, void *argp) { - struct hdinfo *hd = argp; + hdinfo_t *hd = argp; char szfn[1024]; uint64_t sz; - if (strncmp(dent->d_name, hd->hd_name, strlen(hd->hd_name)) != 0) + /* Need to skip /dev/ at start of hd_name */ + if (strncmp(dent->d_name, hd_name(hd), strlen(hd_name(hd))) != 0) return (true); /* Find out how big this is -- no size not a disk */ snprintf(szfn, sizeof(szfn), "%s/%s/%s/size", SYSBLK, - hd->hd_name, dent->d_name); + hd_name(hd), dent->d_name); if (!file2u64(szfn, &sz)) return true; hostdisk_add_part(hd, dent->d_name, sz); @@ -141,23 +154,29 @@ hostdisk_one_part(struct host_dirent64 *dent, void *argp) } static void -hostdisk_add_parts(struct hdinfo *hd) +hostdisk_add_parts(hdinfo_t *hd) { char fn[1024]; - snprintf(fn, sizeof(fn), "%s/%s", SYSBLK, hd->hd_name); + snprintf(fn, sizeof(fn), "%s/%s", SYSBLK, hd_name(hd)); foreach_file(fn, hostdisk_one_part, hd, 0); } static void hostdisk_add_drive(const char *drv, uint64_t secs) { - struct hdinfo *hd; + hdinfo_t *hd = NULL; + char *dev = NULL; char fn[1024]; if ((hd = calloc(1, sizeof(*hd))) == NULL) return; - hd->hd_name = strdup(drv); + if (asprintf(&dev, "/dev/%s", drv) == -1) { + printf("hostdisk: no memory\n"); + free(hd); + return; + } + hd->hd_dev = dev; hd->hd_sectors = secs; snprintf(fn, sizeof(fn), "%s/%s/queue/hw_sector_size", SYSBLK, drv); @@ -174,10 +193,30 @@ hostdisk_add_drive(const char *drv, uint64_t secs) hostdisk_add_parts(hd); return; err: + free(dev); free(hd); return; } +/* Find a disk / partition by its filename */ + +static hdinfo_t * +hostdisk_find(const char *fn) +{ + hdinfo_t *hd, *md; + + STAILQ_FOREACH(hd, &hdinfo, hd_link) { + if (strcmp(hd->hd_dev, fn) == 0) + return (hd); + STAILQ_FOREACH(md, &hd->hd_children, hd_link) { + if (strcmp(md->hd_dev, fn) == 0) + return (md); + } + } + return (NULL); +} + + static bool hostdisk_one_disk(struct host_dirent64 *dent, void *argp __unused) { @@ -252,16 +291,17 @@ static int hostdisk_open(struct open_file *f, ...) { struct devdesc *desc; + const char *fn; va_list vl; va_start(vl, f); desc = va_arg(vl, struct devdesc *); va_end(vl); - desc->d_unit = host_open(desc->d_opendata, O_RDONLY, 0); + fn = dev2hd(desc)->hd_dev; + desc->d_unit = host_open(fn, O_RDONLY, 0); if (desc->d_unit <= 0) { - printf("hostdisk_open: couldn't open %s: %d\n", - (char *)desc->d_opendata, desc->d_unit); + printf("hostdisk_open: couldn't open %s: %d\n", fn, errno); return (ENOENT); } @@ -280,8 +320,20 @@ hostdisk_close(struct open_file *f) static int hostdisk_ioctl(struct open_file *f, u_long cmd, void *data) { - - return (EINVAL); + struct devdesc *desc = f->f_devdata; + hdinfo_t *hd = dev2hd(desc); + + switch (cmd) { + case DIOCGSECTORSIZE: + *(u_int *)data = hd->hd_sectorsize; + break; + case DIOCGMEDIASIZE: + *(uint64_t *)data = hd->hd_size; + break; + default: + return (ENOTTY); + } + return (0); } static int @@ -297,8 +349,8 @@ hostdisk_print(int verbose) STAILQ_FOREACH(hd, &hdinfo, hd_link) { snprintf(line, sizeof(line), - " /dev/%s: %ju X %ju: %ju bytes\n", - hd->hd_name, + " %s: %ju X %ju: %ju bytes\n", + hd->hd_dev, (uintmax_t)hd->hd_sectors, (uintmax_t)hd->hd_sectorsize, (uintmax_t)hd->hd_size); @@ -306,8 +358,8 @@ hostdisk_print(int verbose) break; STAILQ_FOREACH(md, &hd->hd_children, hd_link) { snprintf(line, sizeof(line), - " /dev/%s: %ju X %ju: %ju bytes\n", - md->hd_name, + " %s: %ju X %ju: %ju bytes\n", + md->hd_dev, (uintmax_t)md->hd_sectors, (uintmax_t)md->hd_sectorsize, (uintmax_t)md->hd_size); @@ -323,5 +375,44 @@ done: static char * hostdisk_fmtdev(struct devdesc *vdev) { - return (vdev->d_opendata); + + return ((char *)hd_name(dev2hd(vdev))); +} + +static int +hostdisk_parsedev(struct devdesc **idev, const char *devspec, const char **path) +{ + const char *cp; + struct devdesc *dev; + hdinfo_t *hd; + int len; + char *fn; + + /* Must start with /dev */ + if (strncmp(devspec, "/dev", 4) != 0) + return (EINVAL); + /* Must have a : in it */ + cp = strchr(devspec, ':'); + if (cp == NULL) + return (EINVAL); + /* XXX Stat the /dev or defer error handling to open(2) call? */ + if (path != NULL) + *path = cp + 1; + len = cp - devspec; + fn = strdup(devspec); + fn[len] = '\0'; + hd = hostdisk_find(fn); + if (hd == NULL) { + printf("Can't find hdinfo for %s\n", fn); + return (EINVAL); + } + free(fn); + dev = malloc(sizeof(*dev)); + if (dev == NULL) + return (ENOMEM); + dev->d_unit = 0; + dev->d_dev = &hostdisk; + dev->d_opendata = hd; + *idev = dev; + return (0); }