From 9020621eb4a2c88e20128e57dc06402d948d71f7 Mon Sep 17 00:00:00 2001 From: DrBassman Date: Fri, 15 Dec 2023 10:24:47 -0600 Subject: [PATCH] Updated FreeBSD modules for 14.0Release. --- .../geom_ventoy_ko/14.x/32/geom_ventoy.ko.xz | Bin 8124 -> 8736 bytes .../geom_ventoy_ko/14.x/64/geom_ventoy.ko.xz | Bin 7908 -> 7732 bytes .../14.x/sys/geom/ventoy/g_ventoy.c | 1197 +++++++++++++++++ .../14.x/sys/geom/ventoy/g_ventoy.h | 144 ++ .../sys/modules/geom/geom_ventoy/Makefile | 8 + 5 files changed, 1349 insertions(+) create mode 100644 Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.c create mode 100644 Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.h create mode 100644 Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/modules/geom/geom_ventoy/Makefile diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/32/geom_ventoy.ko.xz index 806d4cc1d017b9c9d6223b668a64a7bf9ac02456..29ab4dfcc3e9b47dd4432b9e4fae5db52d4174c8 100644 GIT binary patch literal 8736 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 K000001X)^{6Z$^@ literal 8124 zcmV;tA4A~%H+ooF000E$*0e?f03iVu0001VFXf}^cGDkuT>w9kMTBTO-vU7}hgyf} zrK8g_s^W1udmzr@R%Uq-VlmVX%?eQTp#twhCn7=_Q%0NG6Hj?A zBdm=3>g({vUKFEK2Rsu{SPYo<0y4=-CZ^cT3Aa2kMCPGN|K*)fjS&%!wRqs>l!AWc zh{)~~jq8bvrWOtRn_yGTV7^WdMDgWPH2UiUUkUSrRx7yYaLim1vq>K8?-dZY{C(L& zvuK7zB0+!o!?@G zb_V0{1L8X^SUZ3WV%7pxhq-fFhInj1jZZ`*6lXX(sy#uC`{^?S`;m z^bFPEmZj-e2kdSt*?y^I0C5?Ik0cW9<%rn*GJ}Bel%opE9MnopKr4~)_>)d{0SFBm zte&{hh@m$ii$1ZgJhQLYeQLg9#^1J)^`xo9p*PT`gPP@1RHM`u?%IMh?Yu=k&i-fm zp2EjY_UNI8hnhhf>L5T%Ql$Fqki=d(NFAj_KmZ>*ja?mGg#!TPPg0juh$XDxi;J}X ztXB&=FpuFP07w5X&JU^|CNZFti3S9pP1xo-6u6W9>BIuVvJE7xoPm`|*?!eq6GXb5 zZoCZ{(~3#DspfNFK|hmD);qNZJRr1t`=P_3L{wCLHI8Zf=*0g$Kwove)Wl@l1%+z2 z>ulL+@hrPhB!5Jfqd+yN-mFQ9030#XY;lr`ipwUmDJVU5UC2SEpSn<#J4q6~eVpZK z_q`R?{DDo<=+;V@7Oov`{|9=WaZjc|$O0M%G|@al2U*|Li4@F+7moXq`xH=2i`*sk z8~G|afjG@PkrA(2RWRioN9wcE4*$*k+I&altXh_0>alWl20C&CDhn$1!)ck8*S?qX zq4lL0p)NF&EB|qLd-rE`)%8q-@seK|)vSorpG?gwv=+N=cP?aGn|G22f>^J_6n`u3 zkrNmOmms~sgy$T$s@g`P`aTAi)VLxa%OjbT7>5%Od{V_@(s^gPbwekg7tR(#(!vv> zusH!7IY*!{;CnF{naR`5h{oo-X-kmuhZEt4KYze{9MT7AQDNEBKHpv5`z$?`X8 zW9fD(R&!)vOidx<$`QQzc~FXE!DF8q;sz@B>p9K;^%KsF9G-K*R$zewLXesdnR-9@yb{HaIPs+vO zjFOTF0GmMi_^z8u2aqG~oV*_yX$`g{9e~>n!*$>WUN(gDH+8>tTYP2B%KHj`Rh(u> zAwx)^#Vdki!Vj63uFqC=Sbi&{Rqr&SjPaGaKo~2${gnZ~jIvF|kwevDBxS-}ex}uw zA;F*~Bf#1$`L+{t2RITno;fV6e{z#anVw2M%M4zAnT~=x?KB~RrpxvNW=ckVPu|3@ z8wqY>-)_vPb7xvU=H%*FAk|QV0)AOiA?`6^%Z=a~X&&#Wctn2TAN-_`-)ZdD>#lX? z#xZo^IdeZO_uMkA8>;s|84hxFuSC_&W=UuHM=<+a{1|ZcA?Ie$FRHb3r@mr^be#Qr z$=p$q(A{`G{7uQMbS*O?>GB)Fl&~H*C^>cwK4C4t&=>Yc&DVR=*lae4L?jrFv`%EU zeBm-h5SgaK(x`#HA8WeWopsTGIM4U_30)00TfyOxs z@$Bf7Qqyd|-B-$Il89X{WWaZl9d+jRYuisACww47KVk~L`hLUJeVHILSgzl>K80i{ z<1f9dn7&rfnE4XE-PWqJb@>nc*A=OUqeWQ~dmK%G(w!#)U}$v**5{B#xSN7c;M)?= zN-M{*I(tRw^Ho)h!Y}1x&S11>2meYBGC?m-+$&{=j^+04FT37v@a1Q&eP`q`^p}E< z^KfdR!y5@0-oO5*%vCFvNk3X_z83m4Q{+6;@$NxI#Rdn8gU9N;91;hv3JbW+K}$xN z$#%8585X8rRnG;DTt>g)l(SV?eEDR%+KZes&!#ZjTxr8=8ur4ywUlr7_O@?}U^)K8qw{rIzLg&$YN&<2VB zh$ZYs@V`kx?xC{}#GnZ6>I!*0_-}V(%u{a!NC8ZjA|$ZFzLpQo^aT`q+z!qW1e-Se z=;7G)TYaNo{rU=@DN~z#WU<^j-$MrBdl7Sg$OG_9kj@GBngzuIB1JqW6E$vBr}51T zOGJU>hDeYwg257>gmf}vNi?utWI!TxsZ2Ct;0v%F3IP1$`T|=;m!KRPgoB6BxX(RY zKX5!8>z{k+faU7@6=Uw$voU;^XH~Ww03AGy7xN*CW9t1MQ1rU8gX{XUJg%XbOR_}s zSx9=E#3+JP!w!HGddU3)Zr-IHWLX38`~5fSNGA%1vI8n;UE+uF_QOOxy2d>a=qg4t zu@*R04ANGg!jPAvx?cmPCZ)7usBw4>Uo(hJsDuMC&L(o*_N{UKMhbuO1g7$9!j?ON z=?mLgC_-w@@Ok_S+p@vwM9!JnX6{{D4ebIzieD$~j`ta$j9l(VpKDf&U+uJgN^eLL zlr)0m9UGO5us2hNyNsM7}Kdw7cf-2->E+f5X`7e^D zrne-B0}1Yo&xYo}W`U!ym#a6|-D(qr%@mc;_?=O zt0X}3zChpCMjVzm;`(&VH-WtX3P_jE7C71>J;W!?GKy*Vb#31EpK88PmR>qIRR3w+ zb}5jFYQyM~sXn}UeT*+ug^f!-UP`C)&&Tu9Y1B9oyGrPu8riV!`SaCI1(peQ<%$~U z`sE$+A={pHAqE<2^qa4P$FQPUZS0iZ^i6qs1}1^W7#kg6>7Z;y-A>4>k4^YJ z)W5vN_sq82x2|83FS2mL!IEE%0f-c)+Y}=U)}}tCwwer3KpA1|Wz>wRs*d$1zWfzZ zOY#d2`D>u77_sVIpnp`#My32@y}tsB)e8ciE&&1UmLKQe1+^sdHp-X0Im5vb($bBC zKJ4dDHnDSALJEu-`XcxH@}ACB+~WAQL|D6&hz=5bNo06dVZ)J9z+eIQfvvw|>70P% z=pDM;oAdm{k-%>yjkEJQWSZD0J?C9c=5dHF)=5E8ghB}i8?cyuh|mB-1FjMfe+Ea| zYhYKJ4P$zv@k%7C<;&vl5U`zMtWDlUzObc+C!S#bjVXfjPU|@NCl?0A!U!dC@6sNoy^$tAcX=XsLw9|MyuN4W< zsyaYirdC_yLvg#QAXkTfTv#2AjQ9x=@47N@cjW@HbSA6r>p{S?9d?8d8H*G_gA2|q zu1BSPMkVV|d>u0|(`SC?Ic?<-E7cNB55k~$#-QEF9?Ee;WHBNwE%jn)g*x|6+yoNC z3aOSG99D!-$YslrU6a3UEc}%tt%NFQT>4xK_z@ppnG9)0#8zRCEyQE?r!8q)t9Do< zxzimFcgQU=-vy~hen#UJ)Z;pps;jGtL%Hf(q>SB0T@@&41idQ{1U;+~O_!a;%2i@PBA8Dw3`T-WASbp=L$tsYTQl3PA~k+y*$X5Gb%y}pBxZ~h1+wE zo*5==lhu}W?=B~DFfFh5pb=PWGsGrSolx#MyqL0#jf=rR5DUxk%V~M+G37|T0Bbu6 zsYe#=cC5ei(_2g=6>0YGL&F_-F0(7)NEN$K??0s^Ur}7s4?cNbwsci|TuJ>?J}cjF z*>13^weoC$k| zGUM#ReLbQaeUmUs4riYqhgf5X?Y<41A2C2DFgMw}h|>hfKNPp`|5Cr+-CJ5}=vRke z{~RU0e1Hn7Z7RLShyk;>+=NhEI~og8d>bp}k|fL|{(ci^A&RlHy!$i~ny-O3?3DK> zg}K0jc43pr&n@^dcoYC%>=v5RrZ5A(Z%@THo!Hha^a<7C}-oLA3i3R?gs(u*hmC@bc9D#QW23mDZ0>BO zKwJ+&%?1Eq;kG+TbuZ-(>3O;6-OTUtvQgsTr2it%d{vWbpmKg@?)Evas&ahLi8gY{ zfTNTg9!)!}(w_jW=S^{rW0EIgQ-v4Y+u|o0EMc!?`1fqiH>U&VJbOXK$vH+YMN{kR z84vGM)c$-kn92zwGuP~(c@d@!m^rCVU*M|N)V+C6t}(M`dmZEgAJ%Ne7%;gN|JXU(^d4 zn|@+#|js}qJ@A(6*dr;2E0CN(N~569#H>I zxxR*LgUX7p3tiwgeJ1Jnr=8v7*;(>b>*32PptjIU%zmBcBy3xG zLf5f8i{n%52?9#>aM^`+$h0N8)>zF9HqrLqE&>_xggadT$HMfFVweY2^2L339MWs> zK}hst?PB=c#N-WNZaHtn;lv>vh&o>v)FYhcZ7sUk%MW9V~Wv zqfDjVzl$xFJ~SxK}y-c1Gd6zFNjZmqE z!tIiPlVGeAN=frjp}5X7sbAe8m3D?f1>A5%K!@o-JWAB+N z*LtWUJ<@rLB@p%riQvI#YG5b&$TbhqgJe;p>6kN>3pf#JAg%|fJbOGNu=D*(xHdDG z(i;&%VnUhi=A$8ltd&%|Toow5tzsg}9cI@VriVxC`J_l@<|(6^px=4k?TSmceWHnX zIZ?rRK1T-t7@yBtA5F?Ekfxh%sdk|3tQltn_T<`rI0s9|*IfMe%rMvruwF{7`Ch;4 z8;{QRfr&mkB24!)sLkRzFnYgiUYdgqkYBD(z}}0|4-%B$Y`UVhFKwR-H^S#J+t~)` zj=o%VEPE*yB}P3=1YV6YW7ie3k6xEXAEZ2|Vw1OVfrjWp#Z-~%wP|2beDKNsAW(j_ zwt_pjRJ8X0<;+t;zvFAqET;X)eLJ>Xn0WT9<6gIQC&opa&UioKuW?PI;;JO;6*agc ztH?o}ddKU-kmLm6iq+N4Ap_3*4`#9$iaN*(Vy?hSfiF-8yaTo#_cWaFqn80ucDmw| zy)p9c?PyWf2}SCOmaf=&{DlkiYHXD^txAfq+d`Lot!_eO{E_YG}HMy@fffhCeOJ- z{h*ZrA(5FAs>2<%z{a`TFpwV zTMj+C)e>9sj^>MjxdN@sUci#`y0=9yIJ98ZPfcxgGB=#78awwmuV{vsJ(7%NqxrR& z`o}QkXF6_S6O|FkkgBd%uu}zOKfB`P$13UPz;17UYrj!gBMh+eVoi6)tI+iR=>5Ur zZBrc%vCg*!e+8xF1x5h&4&YA=;V2tmHa5wB8HU!ml^zki_U%s8G*>unsL}tY>o%d|Z@gKOpgY{1K|HfMom=Fn zMf177NIM=rQ7A`px>M8-X!O93Ak>MK|6IEaNbd<6(MgLJ1=TAOT5tHfKB2zoTYatZ zsM`Vz;0yxvOA#;4E51WVtBO$2tz8eY~J(Ox5Xwk9>$Ee_#c(;A8DXT)1%7WaJ^Q zfo{Puq97y*-rB7Dar`5gg7Js{JdFgkU5vwiTlDltW6kdz=;#Ah;`L*vn$-IA;;V&( zTeSHn0w<7kQ&%qxPiODijKMQf>tfcK1^3WEoZWNXE@&ZTo}3b-mPKVBg2m^w^Weu+ zT_h|)Zp(sxPh;lwa9f!#wj$P@*j>Ftluxgxd}y0enxr=x9o*x;>}ov>PW616xIM!+ zA$GNC(TLMLQLyRaFeiJJW18c{csR*61NHovbCW~<5_(CM;OeuodkgvHc>NPL71GQa zRY!k^uuIY_PE$8$gl{?m6 zttfJeAu_zGujdDrhscR zS@*2kR(KKKOjVvxrXap*yJ^3oCzVcTD=M}KzD!>xn$u5ZM*_@!a3e@i^1`Fd@v}iA z$hmWlqtd1j(`nGfFO=$oZOf67JV?jcbsfpazcpY)Ks_(-Pm&X{WI3%M47oQQFaKi{ zN!?fso&6&bOj=kJtVffV_S6;2!pk(fYBI5YaYk_nBLQs_S2Rx^pT4eqF&dw@jWKR; zo~I*U>?q5H(Uq8rekzgjCw2E3zy_F2nElwV)s17lJ2-7mq(m(>{01`#ypZm@|!UQf$({7qo0h0vfpD!otZAe}$ls={`Tb5O@bJhv1zfQp`?z2HfIC=!fK7 zZqx|O#Ho~hwAblq_L051ceRyf$2Q?t8yMR{MELZL70`T4Fy)bsT_J?V+O&72gY|rTBda+r_an689tJ-C5arEJqG^d~;$^qYdpM?-}8Ij&uVzfz|ML z)RtsF_NazTyP+$s@eAnm#lRF)b;(YKZJ%L*(L2!|3Q4me&)YxraA9-XG9|bSj_M>3 zki!B;AmhnPO2Rx_c~xn6w2+9cvF|+i4V2B*cS?az1|YYvH*A#}bxa0Vx$L}Ac}@tP z!^)1^=b@Y6E2UV@P_rBW?NQ|gj&;=fo@2#UT1oi;)}82HSY zdx7ag(sL-vxiiItrM!547i?D01E2ua)>9Xq8D*zfArM&VCe6qZ{hhF~_5#|r zo{pX^0_RWjWFZ$)SXz7H8QY<6_3dk(Bg3$^_6MnbcEy!{F&YbEVFd+EE)<>&=ogRh z0WrwO3eY|gnX}z#Ao{g000001X)^hR^(0q diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/64/geom_ventoy.ko.xz index cdcdd12e5bc57a51b554589546d5ef70ab646bf5..a5915776a386caa6c2460af00fcfeeee65f36bf2 100644 GIT binary patch literal 7732 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 + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 THE AUTHORS 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FEATURE(geom_ventoy, "GEOM ventoy support"); + +static MALLOC_DEFINE(M_VENTOY, "ventoy_data", "GEOM_VENTOY Data"); + +SYSCTL_DECL(_kern_geom); +static SYSCTL_NODE(_kern_geom, OID_AUTO, ventoy, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, + "GEOM_VENTOY stuff"); +static u_int g_ventoy_debug = 0; +SYSCTL_UINT(_kern_geom_ventoy, OID_AUTO, debug, CTLFLAG_RWTUN, &g_ventoy_debug, 0, + "Debug level"); + +extern int resource_string_value(const char *name, int unit, const char *resname, const char **result); +extern int resource_int_value(const char *name, int unit, const char *resname, int *result); + +static int g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force); +static int g_ventoy_destroy_geom(struct gctl_req *req, struct g_class *mp, + struct g_geom *gp); + +static g_taste_t g_ventoy_taste; +static g_ctl_req_t g_ventoy_config; +static g_dumpconf_t g_ventoy_dumpconf; + +static char g_ventoy_disk_uuid[64]; +static bool g_ventoy_tasted = false; +static off_t g_ventoy_disk_size = 0; +static off_t g_disk_map_start = 0; +static off_t g_disk_map_end = 0; +static int g_ventoy_remount = 0; + +struct g_ventoy_map g_ventoy_map_data __attribute__((aligned (4096))) = +{ + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 }, + { 0, 0, 0, 0 }, + 0, 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { { 0, 0 } }, + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 } +}; + +struct g_class g_ventoy_class = { + .name = G_VENTOY_CLASS_NAME, + .version = G_VERSION, + .ctlreq = g_ventoy_config, + .taste = g_ventoy_taste, + .destroy_geom = g_ventoy_destroy_geom +}; + + +/* + * Greatest Common Divisor. + */ +static u_int +gcd(u_int a, u_int b) +{ + u_int c; + + while (b != 0) { + c = a; + a = b; + b = (c % b); + } + return (a); +} + +/* + * Least Common Multiple. + */ +static u_int +lcm(u_int a, u_int b) +{ + + return ((a * b) / gcd(a, b)); +} + +/* + * Return the number of valid disks. + */ +static u_int +g_ventoy_nvalid(struct g_ventoy_softc *sc) +{ + u_int i, no; + + no = 0; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_consumer != NULL) + no++; + } + + return (no); +} + +static void +g_ventoy_remove_disk(struct g_ventoy_disk *disk) +{ + struct g_consumer *cp; + struct g_ventoy_softc *sc; + + g_topology_assert(); + KASSERT(disk->d_consumer != NULL, ("Non-valid disk in %s.", __func__)); + sc = disk->d_softc; + cp = disk->d_consumer; + + if (!disk->d_removed) { + G_VENTOY_DEBUG(0, "Disk %s removed from %s.", + cp->provider->name, sc->sc_name); + disk->d_removed = 1; + } + + if (sc->sc_provider != NULL) { + G_VENTOY_DEBUG(0, "Device %s deactivated.", + sc->sc_provider->name); + g_wither_provider(sc->sc_provider, ENXIO); + sc->sc_provider = NULL; + } + + if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) + return; + disk->d_consumer = NULL; + g_detach(cp); + g_destroy_consumer(cp); + /* If there are no valid disks anymore, remove device. */ + if (LIST_EMPTY(&sc->sc_geom->consumer)) + g_ventoy_destroy(sc, 1); +} + +static void +g_ventoy_orphan(struct g_consumer *cp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_geom *gp; + + g_topology_assert(); + gp = cp->geom; + sc = gp->softc; + if (sc == NULL) + return; + + disk = cp->private; + if (disk == NULL) /* Possible? */ + return; + g_ventoy_remove_disk(disk); +} + +static int +g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) +{ + struct g_consumer *cp1, *cp2, *tmp; + struct g_ventoy_disk *disk; + struct g_geom *gp; + int error; + + if (dw > 0) /* readonly */ + return (EPERM); + + g_topology_assert(); + gp = pp->geom; + + if (g_ventoy_remount) + { + de = 0; + } + else + { + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + } + + LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { + error = g_access(cp1, dr, dw, de); + if (error != 0) + goto fail; + disk = cp1->private; + if (cp1->acr == 0 && cp1->acw == 0 && cp1->ace == 0 && + disk->d_removed) { + g_ventoy_remove_disk(disk); /* May destroy geom. */ + } + } + return (0); + +fail: + LIST_FOREACH(cp2, &gp->consumer, consumer) { + if (cp1 == cp2) + break; + g_access(cp2, -dr, -dw, -de); + } + return (error); +} + +static void +g_ventoy_candelete(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + int i, val; + + sc = bp->bio_to->geom->softc; + for (i = 0; i < sc->sc_ndisks; i++) { + disk = &sc->sc_disks[i]; + if (!disk->d_removed && disk->d_candelete) + break; + } + val = i < sc->sc_ndisks; + g_handleattr(bp, "GEOM::candelete", &val, sizeof(val)); +} + +static void +g_ventoy_kernel_dump(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct bio *cbp; + struct g_kerneldump *gkd; + u_int i; + + sc = bp->bio_to->geom->softc; + gkd = (struct g_kerneldump *)bp->bio_data; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_start <= gkd->offset && + sc->sc_disks[i].d_end > gkd->offset) + break; + } + if (i == sc->sc_ndisks) { + g_io_deliver(bp, EOPNOTSUPP); + return; + } + disk = &sc->sc_disks[i]; + gkd->offset -= disk->d_start; + if (gkd->length > disk->d_end - disk->d_start - gkd->offset) + gkd->length = disk->d_end - disk->d_start - gkd->offset; + cbp = g_clone_bio(bp); + if (cbp == NULL) { + g_io_deliver(bp, ENOMEM); + return; + } + cbp->bio_done = g_std_done; + g_io_request(cbp, disk->d_consumer); + G_VENTOY_DEBUG(1, "Kernel dump will go to %s.", + disk->d_consumer->provider->name); +} + +static void +g_ventoy_done(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct bio *pbp; + + pbp = bp->bio_parent; + sc = pbp->bio_to->geom->softc; + mtx_lock(&sc->sc_lock); + if (pbp->bio_error == 0) + pbp->bio_error = bp->bio_error; + pbp->bio_completed += bp->bio_completed; + pbp->bio_inbed++; + if (pbp->bio_children == pbp->bio_inbed) { + mtx_unlock(&sc->sc_lock); + g_io_deliver(pbp, pbp->bio_error); + } else + mtx_unlock(&sc->sc_lock); + g_destroy_bio(bp); +} + +static void +g_ventoy_flush(struct g_ventoy_softc *sc, struct bio *bp) +{ + struct bio_queue_head queue; + struct g_consumer *cp; + struct bio *cbp; + u_int no; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + cbp = g_clone_bio(bp); + if (cbp == NULL) { + while ((cbp = bioq_takefirst(&queue)) != NULL) + g_destroy_bio(cbp); + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + cbp->bio_done = g_ventoy_done; + cbp->bio_caller1 = sc->sc_disks[no].d_consumer; + cbp->bio_to = sc->sc_disks[no].d_consumer->provider; + } + while ((cbp = bioq_takefirst(&queue)) != NULL) { + G_VENTOY_LOGREQ(cbp, "Sending request."); + cp = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, cp); + } +} + +static void +g_ventoy_start(struct bio *bp) +{ + struct bio_queue_head queue; + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_provider *pp; + off_t offset, end, length, off, len; + struct bio *cbp; + char *addr; + u_int no; + + pp = bp->bio_to; + sc = pp->geom->softc; + /* + * If sc == NULL, provider's error should be set and g_ventoy_start() + * should not be called at all. + */ + KASSERT(sc != NULL, + ("Provider's error should be set (error=%d)(device=%s).", + bp->bio_to->error, bp->bio_to->name)); + + G_VENTOY_LOGREQ(bp, "Request received."); + + switch (bp->bio_cmd) { + case BIO_READ: + case BIO_WRITE: + case BIO_DELETE: + break; + case BIO_SPEEDUP: + case BIO_FLUSH: + g_ventoy_flush(sc, bp); + return; + case BIO_GETATTR: + if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { + g_ventoy_kernel_dump(bp); + return; + } else if (strcmp("GEOM::candelete", bp->bio_attribute) == 0) { + g_ventoy_candelete(bp); + return; + } + /* To which provider it should be delivered? */ + /* FALLTHROUGH */ + default: + g_io_deliver(bp, EOPNOTSUPP); + return; + } + + offset = bp->bio_offset; + length = bp->bio_length; + if ((bp->bio_flags & BIO_UNMAPPED) != 0) + addr = NULL; + else + addr = bp->bio_data; + end = offset + length; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + if (disk->d_end <= offset) + continue; + if (disk->d_start >= end) + break; + + off = offset - disk->d_start; + len = MIN(length, disk->d_end - offset); + length -= len; + offset += len; + + cbp = g_clone_bio(bp); + if (cbp == NULL) { + while ((cbp = bioq_takefirst(&queue)) != NULL) + g_destroy_bio(cbp); + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + /* + * Fill in the component buf structure. + */ + if (len == bp->bio_length) + cbp->bio_done = g_std_done; + else + cbp->bio_done = g_ventoy_done; + cbp->bio_offset = off + disk->d_map_start; + cbp->bio_length = len; + if ((bp->bio_flags & BIO_UNMAPPED) != 0) { + cbp->bio_ma_offset += (uintptr_t)addr; + cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE; + cbp->bio_ma_offset %= PAGE_SIZE; + cbp->bio_ma_n = round_page(cbp->bio_ma_offset + + cbp->bio_length) / PAGE_SIZE; + } else + cbp->bio_data = addr; + addr += len; + cbp->bio_to = disk->d_consumer->provider; + cbp->bio_caller1 = disk; + + if (length == 0) + break; + } + KASSERT(length == 0, + ("Length is still greater than 0 (class=%s, name=%s).", + bp->bio_to->geom->class->name, bp->bio_to->geom->name)); + while ((cbp = bioq_takefirst(&queue)) != NULL) { + G_VENTOY_LOGREQ(cbp, "Sending request."); + disk = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, disk->d_consumer); + } +} + +static void +g_ventoy_check_and_run(struct g_ventoy_softc *sc) +{ + struct g_ventoy_disk *disk; + struct g_provider *dp, *pp; + u_int no, sectorsize = 0; + off_t start; + int error; + + g_topology_assert(); + if (g_ventoy_nvalid(sc) != sc->sc_ndisks) + return; + + pp = g_new_providerf(sc->sc_geom, "ventoy/%s", sc->sc_name); + pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE | + G_PF_ACCEPT_UNMAPPED; + start = 0; + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + dp = disk->d_consumer->provider; + disk->d_start = start; + disk->d_end = disk->d_start + (disk->d_map_end - disk->d_map_start); + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) + disk->d_end -= dp->sectorsize; + start = disk->d_end; + error = g_access(disk->d_consumer, 1, 0, 0); + if (error == 0) { + error = g_getattr("GEOM::candelete", disk->d_consumer, + &disk->d_candelete); + if (error != 0) + disk->d_candelete = 0; + (void)g_access(disk->d_consumer, -1, 0, 0); + } else + G_VENTOY_DEBUG(1, "Failed to access disk %s, error %d.", + dp->name, error); + if (no == 0) + sectorsize = dp->sectorsize; + else + sectorsize = lcm(sectorsize, dp->sectorsize); + + /* A provider underneath us doesn't support unmapped */ + if ((dp->flags & G_PF_ACCEPT_UNMAPPED) == 0) { + G_VENTOY_DEBUG(1, "Cancelling unmapped " + "because of %s.", dp->name); + pp->flags &= ~G_PF_ACCEPT_UNMAPPED; + } + } + pp->sectorsize = sectorsize; + /* We have sc->sc_disks[sc->sc_ndisks - 1].d_end in 'start'. */ + pp->mediasize = start; + pp->stripesize = sc->sc_disks[0].d_consumer->provider->stripesize; + pp->stripeoffset = sc->sc_disks[0].d_consumer->provider->stripeoffset; + sc->sc_provider = pp; + g_error_provider(pp, 0); + + G_VENTOY_DEBUG(0, "Device %s activated.", sc->sc_provider->name); +} + +static int +g_ventoy_read_metadata(struct g_consumer *cp, struct g_ventoy_metadata *md) +{ + struct g_provider *pp; + u_char *buf; + int error; + + g_topology_assert(); + + error = g_access(cp, 1, 0, 0); + if (error != 0) + return (error); + pp = cp->provider; + g_topology_unlock(); + buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, + &error); + g_topology_lock(); + g_access(cp, -1, 0, 0); + if (buf == NULL) + return (error); + + /* Decode metadata. */ + ventoy_metadata_decode(buf, md); + g_free(buf); + + return (0); +} + +/* + * Add disk to given device. + */ +static int +g_ventoy_add_disk(struct g_ventoy_softc *sc, struct g_provider *pp, u_int no) +{ + struct g_ventoy_disk *disk; + struct g_consumer *cp, *fcp; + struct g_geom *gp; + int error; + + g_topology_assert(); + /* Metadata corrupted? */ + if (no >= sc->sc_ndisks) + return (EINVAL); + + disk = &sc->sc_disks[no]; + /* Check if disk is not already attached. */ + if (disk->d_consumer != NULL) + return (EEXIST); + + gp = sc->sc_geom; + fcp = LIST_FIRST(&gp->consumer); + + cp = g_new_consumer(gp); + cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; + error = g_attach(cp, pp); + if (error != 0) { + g_destroy_consumer(cp); + return (error); + } + + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) { + error = g_access(cp, fcp->acr, fcp->acw, fcp->ace); + if (error != 0) { + g_detach(cp); + g_destroy_consumer(cp); + return (error); + } + } + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) { + struct g_ventoy_metadata md; + + /* Re-read metadata. */ + error = g_ventoy_read_metadata(cp, &md); + if (error != 0) + goto fail; + + if (strcmp(md.md_magic, G_VENTOY_MAGIC) != 0 || + strcmp(md.md_name, sc->sc_name) != 0 || + md.md_id != sc->sc_id) { + G_VENTOY_DEBUG(0, "Metadata on %s changed.", pp->name); + goto fail; + } + } + + cp->private = disk; + disk->d_consumer = cp; + disk->d_softc = sc; + disk->d_start = 0; /* not yet */ + disk->d_end = 0; /* not yet */ + disk->d_removed = 0; + + disk->d_map_start = g_disk_map_start; + disk->d_map_end = g_disk_map_end; + + G_VENTOY_DEBUG(0, "Disk %s attached to %s.", pp->name, sc->sc_name); + + g_ventoy_check_and_run(sc); + + return (0); +fail: + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) + g_access(cp, -fcp->acr, -fcp->acw, -fcp->ace); + g_detach(cp); + g_destroy_consumer(cp); + return (error); +} + +static struct g_geom * +g_ventoy_create(struct g_class *mp, const struct g_ventoy_metadata *md, + u_int type) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + u_int no; + + G_VENTOY_DEBUG(1, "Creating device %s (id=%u).", md->md_name, + md->md_id); + + /* One disks is minimum. */ + if (md->md_all < 1) + return (NULL); + + /* Check for duplicate unit */ + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc != NULL && strcmp(sc->sc_name, md->md_name) == 0) { + G_VENTOY_DEBUG(0, "Device %s already configured.", + gp->name); + return (NULL); + } + } + gp = g_new_geomf(mp, "%s", md->md_name); + sc = malloc(sizeof(*sc), M_VENTOY, M_WAITOK | M_ZERO); + gp->start = g_ventoy_start; + gp->spoiled = g_ventoy_orphan; + gp->orphan = g_ventoy_orphan; + gp->access = g_ventoy_access; + gp->dumpconf = g_ventoy_dumpconf; + + sc->sc_id = md->md_id; + sc->sc_ndisks = md->md_all; + sc->sc_disks = malloc(sizeof(struct g_ventoy_disk) * sc->sc_ndisks, + M_VENTOY, M_WAITOK | M_ZERO); + for (no = 0; no < sc->sc_ndisks; no++) + sc->sc_disks[no].d_consumer = NULL; + sc->sc_type = type; + mtx_init(&sc->sc_lock, "gventoy lock", NULL, MTX_DEF); + + gp->softc = sc; + sc->sc_geom = gp; + sc->sc_provider = NULL; + + G_VENTOY_DEBUG(0, "Device %s created (id=%u).", sc->sc_name, sc->sc_id); + + return (gp); +} + +static int +g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force) +{ + struct g_provider *pp; + struct g_consumer *cp, *cp1; + struct g_geom *gp; + + g_topology_assert(); + + if (sc == NULL) + return (ENXIO); + + pp = sc->sc_provider; + if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) { + if (force) { + G_VENTOY_DEBUG(0, "Device %s is still open, so it " + "can't be definitely removed.", pp->name); + } else { + G_VENTOY_DEBUG(1, + "Device %s is still open (r%dw%de%d).", pp->name, + pp->acr, pp->acw, pp->ace); + return (EBUSY); + } + } + + gp = sc->sc_geom; + LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp1) { + g_ventoy_remove_disk(cp->private); + if (cp1 == NULL) + return (0); /* Recursion happened. */ + } + if (!LIST_EMPTY(&gp->consumer)) + return (EINPROGRESS); + + gp->softc = NULL; + KASSERT(sc->sc_provider == NULL, ("Provider still exists? (device=%s)", + gp->name)); + free(sc->sc_disks, M_VENTOY); + mtx_destroy(&sc->sc_lock); + free(sc, M_VENTOY); + + G_VENTOY_DEBUG(0, "Device %s destroyed.", gp->name); + g_wither_geom(gp, ENXIO); + return (0); +} + +static int +g_ventoy_destroy_geom(struct gctl_req *req __unused, + struct g_class *mp __unused, struct g_geom *gp) +{ + struct g_ventoy_softc *sc; + + sc = gp->softc; + return (g_ventoy_destroy(sc, 0)); +} + +static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) +{ + int i; + int vlnk = 0; + bool ret = true; + uint8_t *buf; + char uuid[64]; + const char *value; + struct g_consumer *cp; + struct g_geom *gp; + uint8_t mbrdata[] = { + 0xEB, 0x63, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44, 0x00, 0x52, 0x64, 0x00, 0x20, 0x45, 0x72, 0x0D, + }; + + if (g_ventoy_disk_size == 0) + { + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) + { + G_DEBUG("ventoy map data is valid. [OK]\n"); + + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", g_ventoy_map_data.diskuuid[i]); + } + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", uuid); + g_ventoy_disk_size = g_ventoy_map_data.disksize; + + G_DEBUG("ventoy.disksize: %llu\n", (unsigned long long)g_ventoy_disk_size); + G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid); + } + else + { + G_DEBUG("ventoy map data is invalid, get from resource\n"); + + if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + { + G_DEBUG("ventoy.disksize: %s\n", value); + g_ventoy_disk_size = strtouq(value, NULL, 0); + } + + if (resource_string_value("ventoy", 0, "diskuuid", &value) == 0) + { + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", value); + G_DEBUG("ventoy.diskuuid: <%s>\n", value); + } + } + } + + if (g_ventoy_disk_size != pp->mediasize) + { + return false; + } + + if (strncmp(pp->name, "cd", 2) == 0 || strchr(pp->name, '/')) + { + return false; + } + + /* read UUID from disk */ + gp = g_new_geomf(mp, "ventoy:taste"); + gp->start = NULL; + gp->access = g_ventoy_access; + gp->orphan = g_ventoy_orphan; + cp = g_new_consumer(gp); + g_attach(cp, pp); + + g_access(cp, 1, 0, 0); + g_topology_unlock(); + buf = g_read_data(cp, 0, pp->sectorsize, NULL); + g_topology_lock(); + g_access(cp, -1, 0, 0); + + g_detach(cp); + g_destroy_consumer(cp); + g_destroy_geom(gp); + gp = NULL; + + if (!buf) + { + return false; + } + + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", buf[0x180 + i]); + } + + if (strncmp(g_ventoy_disk_uuid, uuid, 32)) + { + ret = false; + } + + if (resource_int_value("ventoy", 0, "vlnk", &vlnk) || (vlnk != 1)) + { + if (memcmp(mbrdata, buf, 0x30) || memcmp(mbrdata + 0x30, buf + 0x190, 16)) + { + ret = false; + } + } + + g_free(buf); + + if (ret) + { + G_DEBUG("ventoy disk check OK\n"); + } + + return ret; +} + +static struct g_geom * +g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) +{ + int i; + int error; + int disknum; + int remount = 0; + char *endpos; + const char *value; + const char *alias = NULL; + struct g_geom *gp; + struct g_ventoy_metadata md; + struct g_ventoy_softc *sc; + + if (g_ventoy_tasted) + { + return NULL; + } + + G_DEBUG("%s(%s, %s)\n", __func__, mp->name, pp->name); + g_topology_assert(); + + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + + if (!g_vtoy_check_disk(mp, pp)) + { + return NULL; + } + + g_ventoy_tasted = true; + + G_DEBUG("###### ventoy disk <%s> ######\n", pp->name); + + /* hint.ventoy.0.remount=1 */ + if (resource_int_value("ventoy", 0, "remount", &remount) == 0 && remount == 1) + { + g_ventoy_remount = 1; + G_DEBUG("###### ventoy remount enabled ######\n"); + } + + /* hint.ventoy.0.alias=xxx */ + if (resource_string_value("ventoy", 0, "alias", &alias) == 0) + { + G_DEBUG("###### ventoy alias <%s> ######\n", alias); + } + else + { + alias = NULL; + } + + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) + { + disknum = (int)g_ventoy_map_data.segnum; + G_DEBUG("segnum from map data is:<%d>\n", disknum); + } + else + { + resource_int_value("ventoy", 0, "segnum", &disknum); + G_DEBUG("segnum from resource is:<%d>\n", disknum); + } + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + strlcpy(md.md_name, "IMAGE", sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = (uint16_t)disknum; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + G_VENTOY_DEBUG(0, "Cannot create device %s.", + md.md_name); + return (NULL); + } + sc = gp->softc; + + for (i = 0; i < disknum; i ++) + { + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) + { + G_DEBUG("[map] ventoy segment%d: 0x%llx@0x%llx\n", i, + (long long)g_ventoy_map_data.seglist[i].seg_start_bytes, + (long long)g_ventoy_map_data.seglist[i].seg_end_bytes); + + g_disk_map_start = (off_t)g_ventoy_map_data.seglist[i].seg_start_bytes; + g_disk_map_end = (off_t)g_ventoy_map_data.seglist[i].seg_end_bytes; + } + else + { + if (resource_string_value("ventoy", i, "seg", &value) == 0) + { + g_disk_map_start = strtouq(value, &endpos, 0); + g_disk_map_end = strtouq(endpos + 1, NULL, 0); + } + else + { + printf("Failed to parse ventoy seg %d\n", i); + continue; + } + G_DEBUG("[resource] ventoy segment%d: %s\n", i, value); + } + + G_VENTOY_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name); + error = g_ventoy_add_disk(sc, pp, i); + if (error != 0) { + G_VENTOY_DEBUG(0, + "Cannot add disk %s to %s (error=%d).", pp->name, + gp->name, error); + g_ventoy_destroy(sc, 1); + return (NULL); + } + + g_disk_map_start = 0; + g_disk_map_end = 0; + } + + if (alias && sc && sc->sc_provider) + { + g_provider_add_alias(sc->sc_provider, "%s", alias); + } + + return (gp); +} + +static void +g_ventoy_ctl_create(struct gctl_req *req, struct g_class *mp) +{ + u_int attached, no; + struct g_ventoy_metadata md; + struct g_provider *pp; + struct g_ventoy_softc *sc; + struct g_geom *gp; + struct sbuf *sb; + const char *name; + char param[16]; + int *nargs; + + g_topology_assert(); + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs < 2) { + gctl_error(req, "Too few arguments."); + return; + } + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + name = gctl_get_asciiparam(req, "arg0"); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", 0); + return; + } + strlcpy(md.md_name, name, sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = *nargs - 1; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + /* Check all providers are valid */ + for (no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + pp = gctl_get_provider(req, param); + if (pp == NULL) + return; + } + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + gctl_error(req, "Can't configure %s.", md.md_name); + return; + } + + sc = gp->softc; + sb = sbuf_new_auto(); + sbuf_printf(sb, "Can't attach disk(s) to %s:", gp->name); + for (attached = 0, no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + pp = gctl_get_provider(req, param); + if (pp == NULL) { + name = gctl_get_asciiparam(req, param); + MPASS(name != NULL); + sbuf_printf(sb, " %s", name); + continue; + } + if (g_ventoy_add_disk(sc, pp, no - 1) != 0) { + G_VENTOY_DEBUG(1, "Disk %u (%s) not attached to %s.", + no, pp->name, gp->name); + sbuf_printf(sb, " %s", pp->name); + continue; + } + attached++; + } + sbuf_finish(sb); + if (md.md_all != attached) { + g_ventoy_destroy(gp->softc, 1); + gctl_error(req, "%s", sbuf_data(sb)); + } + sbuf_delete(sb); +} + +static struct g_ventoy_softc * +g_ventoy_find_device(struct g_class *mp, const char *name) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + + if (strncmp(name, _PATH_DEV, strlen(_PATH_DEV)) == 0) + name += strlen(_PATH_DEV); + + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc == NULL) + continue; + if (strcmp(sc->sc_name, name) == 0) + return (sc); + } + return (NULL); +} + +static void +g_ventoy_ctl_destroy(struct gctl_req *req, struct g_class *mp) +{ + struct g_ventoy_softc *sc; + int *force, *nargs, error; + const char *name; + char param[16]; + u_int i; + + g_topology_assert(); + + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs <= 0) { + gctl_error(req, "Missing device(s)."); + return; + } + force = gctl_get_paraml(req, "force", sizeof(*force)); + if (force == NULL) { + gctl_error(req, "No '%s' argument.", "force"); + return; + } + + for (i = 0; i < (u_int)*nargs; i++) { + snprintf(param, sizeof(param), "arg%u", i); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", i); + return; + } + sc = g_ventoy_find_device(mp, name); + if (sc == NULL) { + gctl_error(req, "No such device: %s.", name); + return; + } + error = g_ventoy_destroy(sc, *force); + if (error != 0) { + gctl_error(req, "Cannot destroy device %s (error=%d).", + sc->sc_name, error); + return; + } + } +} + +static void +g_ventoy_config(struct gctl_req *req, struct g_class *mp, const char *verb) +{ + uint32_t *version; + + return; + + g_topology_assert(); + + version = gctl_get_paraml(req, "version", sizeof(*version)); + if (version == NULL) { + gctl_error(req, "No '%s' argument.", "version"); + return; + } + if (*version != G_VENTOY_VERSION) { + gctl_error(req, "Userland and kernel parts are out of sync."); + return; + } + + if (strcmp(verb, "create") == 0) { + g_ventoy_ctl_create(req, mp); + return; + } else if (strcmp(verb, "destroy") == 0 || + strcmp(verb, "stop") == 0) { + g_ventoy_ctl_destroy(req, mp); + return; + } + gctl_error(req, "Unknown verb."); +} + +static void +g_ventoy_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, + struct g_consumer *cp, struct g_provider *pp) +{ + struct g_ventoy_softc *sc; + + g_topology_assert(); + sc = gp->softc; + if (sc == NULL) + return; + if (pp != NULL) { + /* Nothing here. */ + } else if (cp != NULL) { + struct g_ventoy_disk *disk; + + disk = cp->private; + if (disk == NULL) + return; + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_end); + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_start); + } else { + sbuf_printf(sb, "%s%u\n", indent, (u_int)sc->sc_id); + sbuf_printf(sb, "%s", indent); + switch (sc->sc_type) { + case G_VENTOY_TYPE_AUTOMATIC: + sbuf_cat(sb, "AUTOMATIC"); + break; + case G_VENTOY_TYPE_MANUAL: + sbuf_cat(sb, "MANUAL"); + break; + default: + sbuf_cat(sb, "UNKNOWN"); + break; + } + sbuf_cat(sb, "\n"); + sbuf_printf(sb, "%sTotal=%u, Online=%u\n", + indent, sc->sc_ndisks, g_ventoy_nvalid(sc)); + sbuf_printf(sb, "%s", indent); + if (sc->sc_provider != NULL && sc->sc_provider->error == 0) + sbuf_cat(sb, "UP"); + else + sbuf_cat(sb, "DOWN"); + sbuf_cat(sb, "\n"); + } +} + +DECLARE_GEOM_CLASS(g_ventoy_class, g_ventoy); +//MODULE_VERSION(geom_ventoy, 0); diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.h b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.h new file mode 100644 index 00000000000..abe565bdb9f --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.h @@ -0,0 +1,144 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 THE AUTHORS 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. + * + * $FreeBSD$ + */ + +#ifndef _G_VENTOY_H_ +#define _G_VENTOY_H_ + +#include + +#define G_VENTOY_CLASS_NAME "VENTOY" + +#define G_VENTOY_MAGIC "GEOM::VENTOY" +/* + * Version history: + * 1 - Initial version number. + * 2 - Added 'stop' command to gconcat(8). + * 3 - Added md_provider field to metadata and '-h' option to gconcat(8). + * 4 - Added md_provsize field to metadata. + */ +#define G_VENTOY_VERSION 4 + +#ifdef _KERNEL +#define G_VENTOY_TYPE_MANUAL 0 +#define G_VENTOY_TYPE_AUTOMATIC 1 + +#define G_DEBUG(...) if (bootverbose) printf(__VA_ARGS__) +#define G_VENTOY_DEBUG(lvl, ...) if (g_ventoy_debug) printf(__VA_ARGS__) +#define G_VENTOY_LOGREQ(bp, ...) if (g_ventoy_debug) printf(__VA_ARGS__) + +struct g_ventoy_disk { + struct g_consumer *d_consumer; + struct g_ventoy_softc *d_softc; + off_t d_start; + off_t d_end; + off_t d_map_start; + off_t d_map_end; + int d_candelete; + int d_removed; +}; + +struct g_ventoy_softc { + u_int sc_type; /* provider type */ + struct g_geom *sc_geom; + struct g_provider *sc_provider; + uint32_t sc_id; /* concat unique ID */ + + struct g_ventoy_disk *sc_disks; + uint16_t sc_ndisks; + struct mtx sc_lock; +}; +#define sc_name sc_geom->name + + +#pragma pack(1) +#define VENTOY_UNIX_SEG_MAGIC0 0x11223344 +#define VENTOY_UNIX_SEG_MAGIC1 0x55667788 +#define VENTOY_UNIX_SEG_MAGIC2 0x99aabbcc +#define VENTOY_UNIX_SEG_MAGIC3 0xddeeff00 +#define VENTOY_UNIX_MAX_SEGNUM 40960 +struct g_ventoy_seg { + uint64_t seg_start_bytes; + uint64_t seg_end_bytes; +}; + +struct g_ventoy_map{ + uint32_t magic1[4]; + uint32_t magic2[4]; + uint64_t segnum; + uint64_t disksize; + uint8_t diskuuid[16]; + struct g_ventoy_seg seglist[VENTOY_UNIX_MAX_SEGNUM]; + uint32_t magic3[4]; +}; +#pragma pack() + +#define VENTOY_MAP_VALID(magic2) \ + (magic2[0] == VENTOY_UNIX_SEG_MAGIC0 && magic2[1] == VENTOY_UNIX_SEG_MAGIC1 && magic2[2] == VENTOY_UNIX_SEG_MAGIC2 && magic2[3] == VENTOY_UNIX_SEG_MAGIC3) + +#endif /* _KERNEL */ + +struct g_ventoy_metadata { + char md_magic[16]; /* Magic value. */ + uint32_t md_version; /* Version number. */ + char md_name[16]; /* Concat name. */ + uint32_t md_id; /* Unique ID. */ + uint16_t md_no; /* Disk number. */ + uint16_t md_all; /* Number of all disks. */ + char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ +}; +static __inline void +ventoy_metadata_encode(const struct g_ventoy_metadata *md, u_char *data) +{ + + bcopy(md->md_magic, data, sizeof(md->md_magic)); + le32enc(data + 16, md->md_version); + bcopy(md->md_name, data + 20, sizeof(md->md_name)); + le32enc(data + 36, md->md_id); + le16enc(data + 40, md->md_no); + le16enc(data + 42, md->md_all); + bcopy(md->md_provider, data + 44, sizeof(md->md_provider)); + le64enc(data + 60, md->md_provsize); +} +static __inline void +ventoy_metadata_decode(const u_char *data, struct g_ventoy_metadata *md) +{ + + bcopy(data, md->md_magic, sizeof(md->md_magic)); + md->md_version = le32dec(data + 16); + bcopy(data + 20, md->md_name, sizeof(md->md_name)); + md->md_id = le32dec(data + 36); + md->md_no = le16dec(data + 40); + md->md_all = le16dec(data + 42); + bcopy(data + 44, md->md_provider, sizeof(md->md_provider)); + md->md_provsize = le64dec(data + 60); +} +#endif /* _G_VENTOY_H_ */ diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/modules/geom/geom_ventoy/Makefile b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/modules/geom/geom_ventoy/Makefile new file mode 100644 index 00000000000..165f1bdf4cb --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/modules/geom/geom_ventoy/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/geom/ventoy + +KMOD= geom_ventoy +SRCS= g_ventoy.c + +.include