Merge pull request #240 from truenas/NAS-129592-master
NAS-129592 / None / [truenas/zfs-2.3-release] Sync with the upstream master
This commit is contained in:
commit
1b72c70b71
18
.mailmap
18
.mailmap
|
@ -30,6 +30,7 @@ Andreas Dilger <adilger@dilger.ca>
|
|||
Andrew Walker <awalker@ixsystems.com>
|
||||
Benedikt Neuffer <github@itfriend.de>
|
||||
Chengfei Zhu <chengfeix.zhu@intel.com>
|
||||
ChenHao Lu <18302010006@fudan.edu.cn>
|
||||
Chris Lindee <chris.lindee+github@gmail.com>
|
||||
Colm Buckley <colm@tuatha.org>
|
||||
Crag Wang <crag0715@gmail.com>
|
||||
|
@ -43,6 +44,7 @@ Glenn Washburn <development@efficientek.com>
|
|||
Gordan Bobic <gordan.bobic@gmail.com>
|
||||
Gregory Bartholomew <gregory.lee.bartholomew@gmail.com>
|
||||
hedong zhang <h_d_zhang@163.com>
|
||||
Ilkka Sovanto <github@ilkka.kapsi.fi>
|
||||
InsanePrawn <Insane.Prawny@gmail.com>
|
||||
Jason Cohen <jwittlincohen@gmail.com>
|
||||
Jason Harmening <jason.harmening@gmail.com>
|
||||
|
@ -57,6 +59,7 @@ KernelOfTruth <kerneloftruth@gmail.com>
|
|||
Liu Hua <liu.hua130@zte.com.cn>
|
||||
Liu Qing <winglq@gmail.com>
|
||||
loli10K <ezomori.nozomu@gmail.com>
|
||||
Mart Frauenlob <allkind@fastest.cc>
|
||||
Matthias Blankertz <matthias@blankertz.org>
|
||||
Michael Gmelin <grembo@FreeBSD.org>
|
||||
Olivier Mazouffre <olivier.mazouffre@ims-bordeaux.fr>
|
||||
|
@ -73,6 +76,9 @@ WHR <msl0000023508@gmail.com>
|
|||
Yanping Gao <yanping.gao@xtaotech.com>
|
||||
Youzhong Yang <youzhong@gmail.com>
|
||||
|
||||
# Signed-off-by: overriding Author:
|
||||
Yuxin Wang <yuxinwang9999@gmail.com> <Bi11gates9999@gmail.com>
|
||||
|
||||
# Commits from strange places, long ago
|
||||
Brian Behlendorf <behlendorf1@llnl.gov> <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>
|
||||
Brian Behlendorf <behlendorf1@llnl.gov> <behlendo@fedora-17-amd64.(none)>
|
||||
|
@ -102,12 +108,15 @@ Brandon Thetford <brandon@dodecatec.com> <dodexahedron@users.noreply.github.com>
|
|||
buzzingwires <buzzingwires@outlook.com> <131118055+buzzingwires@users.noreply.github.com>
|
||||
Cedric Maunoury <cedric.maunoury@gmail.com> <38213715+cedricmaunoury@users.noreply.github.com>
|
||||
Charles Suh <charles.suh@gmail.com> <charlessuh@users.noreply.github.com>
|
||||
Chris Peredun <chris.peredun@ixsystems.com> <126915832+chrisperedun@users.noreply.github.com>
|
||||
Dacian Reece-Stremtan <dacianstremtan@gmail.com> <35844628+dacianstremtan@users.noreply.github.com>
|
||||
Damian Szuberski <szuberskidamian@gmail.com> <30863496+szubersk@users.noreply.github.com>
|
||||
Daniel Hiepler <d-git@coderdu.de> <32984777+heeplr@users.noreply.github.com>
|
||||
Daniel Kobras <d.kobras@science-computing.de> <sckobras@users.noreply.github.com>
|
||||
Daniel Reichelt <hacking@nachtgeist.net> <nachtgeist@users.noreply.github.com>
|
||||
David Quigley <david.quigley@intel.com> <dpquigl@users.noreply.github.com>
|
||||
Dennis R. Friedrichsen <dennis.r.friedrichsen@gmail.com> <31087738+dennisfriedrichsen@users.noreply.github.com>
|
||||
Dex Wood <slash2314@gmail.com> <slash2314@users.noreply.github.com>
|
||||
DHE <git@dehacked.net> <DeHackEd@users.noreply.github.com>
|
||||
Dmitri John Ledkov <dimitri.ledkov@canonical.com> <19779+xnox@users.noreply.github.com>
|
||||
Dries Michiels <driesm.michiels@gmail.com> <32487486+driesmp@users.noreply.github.com>
|
||||
|
@ -128,6 +137,7 @@ Harry Mallon <hjmallon@gmail.com> <1816667+hjmallon@users.noreply.github.com>
|
|||
Hiếu Lê <leorize+oss@disroot.org> <alaviss@users.noreply.github.com>
|
||||
Jake Howard <git@theorangeone.net> <RealOrangeOne@users.noreply.github.com>
|
||||
James Cowgill <james.cowgill@mips.com> <jcowgill@users.noreply.github.com>
|
||||
Jaron Kent-Dobias <jaron@kent-dobias.com> <kentdobias@users.noreply.github.com>
|
||||
Jason King <jason.king@joyent.com> <jasonbking@users.noreply.github.com>
|
||||
Jeff Dike <jdike@akamai.com> <52420226+jdike@users.noreply.github.com>
|
||||
Jitendra Patidar <jitendra.patidar@nutanix.com> <53164267+jsai20@users.noreply.github.com>
|
||||
|
@ -137,7 +147,9 @@ John L. Hammond <john.hammond@intel.com> <35266395+jhammond-intel@users.noreply.
|
|||
John-Mark Gurney <jmg@funkthat.com> <jmgurney@users.noreply.github.com>
|
||||
John Ramsden <johnramsden@riseup.net> <johnramsden@users.noreply.github.com>
|
||||
Jonathon Fernyhough <jonathon@m2x.dev> <559369+jonathonf@users.noreply.github.com>
|
||||
Jose Luis Duran <jlduran@gmail.com> <jlduran@users.noreply.github.com>
|
||||
Justin Hibbits <chmeeedalf@gmail.com> <chmeeedalf@users.noreply.github.com>
|
||||
Kevin Greene <kevin.greene@delphix.com> <104801862+kxgreene@users.noreply.github.com>
|
||||
Kevin Jin <lostking2008@hotmail.com> <33590050+jxdking@users.noreply.github.com>
|
||||
Kevin P. Fleming <kevin@km6g.us> <kpfleming@users.noreply.github.com>
|
||||
Krzysztof Piecuch <piecuch@kpiecuch.pl> <3964215+pikrzysztof@users.noreply.github.com>
|
||||
|
@ -148,9 +160,11 @@ Lorenz Hüdepohl <dev@stellardeath.org> <lhuedepohl@users.noreply.github.com>
|
|||
Luís Henriques <henrix@camandro.org> <73643340+lumigch@users.noreply.github.com>
|
||||
Marcin Skarbek <git@skarbek.name> <mskarbek@users.noreply.github.com>
|
||||
Matt Fiddaman <github@m.fiddaman.uk> <81489167+matt-fidd@users.noreply.github.com>
|
||||
Maxim Filimonov <che@bein.link> <part1zano@users.noreply.github.com>
|
||||
Max Zettlmeißl <max@zettlmeissl.de> <6818198+maxz@users.noreply.github.com>
|
||||
Michael Niewöhner <foss@mniewoehner.de> <c0d3z3r0@users.noreply.github.com>
|
||||
Michael Zhivich <mzhivich@akamai.com> <33133421+mzhivich@users.noreply.github.com>
|
||||
MigeljanImeri <ImeriMigel@gmail.com> <78048439+MigeljanImeri@users.noreply.github.com>
|
||||
Mo Zhou <cdluminate@gmail.com> <5723047+cdluminate@users.noreply.github.com>
|
||||
Nick Mattis <nickm970@gmail.com> <nmattis@users.noreply.github.com>
|
||||
omni <omni+vagant@hack.org> <79493359+omnivagant@users.noreply.github.com>
|
||||
|
@ -164,6 +178,7 @@ Ping Huang <huangping@smartx.com> <101400146+hpingfs@users.noreply.github.com>
|
|||
Piotr P. Stefaniak <pstef@freebsd.org> <pstef@users.noreply.github.com>
|
||||
Richard Allen <belperite@gmail.com> <33836503+belperite@users.noreply.github.com>
|
||||
Rich Ercolani <rincebrain@gmail.com> <214141+rincebrain@users.noreply.github.com>
|
||||
Rick Macklem <rmacklem@uoguelph.ca> <64620010+rmacklem@users.noreply.github.com>
|
||||
Rob Wing <rob.wing@klarasystems.com> <98866084+rob-wing@users.noreply.github.com>
|
||||
Roman Strashkin <roman.strashkin@nexenta.com> <Ramzec@users.noreply.github.com>
|
||||
Ryan Hirasaki <ryanhirasaki@gmail.com> <4690732+RyanHir@users.noreply.github.com>
|
||||
|
@ -174,6 +189,8 @@ Scott Colby <scott@scolby.com> <scolby33@users.noreply.github.com>
|
|||
Sean Eric Fagan <kithrup@mac.com> <kithrup@users.noreply.github.com>
|
||||
Spencer Kinny <spencerkinny1995@gmail.com> <30333052+Spencer-Kinny@users.noreply.github.com>
|
||||
Srikanth N S <srikanth.nagasubbaraoseetharaman@hpe.com> <75025422+nssrikanth@users.noreply.github.com>
|
||||
Stefan Lendl <s.lendl@proxmox.com> <1321542+stfl@users.noreply.github.com>
|
||||
Thomas Bertschinger <bertschinger@lanl.gov> <101425190+bertschinger@users.noreply.github.com>
|
||||
Thomas Geppert <geppi@digitx.de> <geppi@users.noreply.github.com>
|
||||
Tim Crawford <tcrawford@datto.com> <crawfxrd@users.noreply.github.com>
|
||||
Tom Matthews <tom@axiom-partners.com> <tomtastic@users.noreply.github.com>
|
||||
|
@ -181,6 +198,7 @@ Tony Perkins <tperkins@datto.com> <62951051+tony-zfs@users.noreply.github.com>
|
|||
Torsten Wörtwein <twoertwein@gmail.com> <twoertwein@users.noreply.github.com>
|
||||
Tulsi Jain <tulsi.jain@delphix.com> <TulsiJain@users.noreply.github.com>
|
||||
Václav Skála <skala@vshosting.cz> <33496485+vaclavskala@users.noreply.github.com>
|
||||
Vaibhav Bhanawat <vaibhav.bhanawat@delphix.com> <88050553+vaibhav-delphix@users.noreply.github.com>
|
||||
Violet Purcell <vimproved@inventati.org> <66446404+vimproved@users.noreply.github.com>
|
||||
Vipin Kumar Verma <vipin.verma@hpe.com> <75025470+vermavipinkumar@users.noreply.github.com>
|
||||
Wolfgang Bumiller <w.bumiller@proxmox.com> <Blub@users.noreply.github.com>
|
||||
|
|
35
AUTHORS
35
AUTHORS
|
@ -88,9 +88,11 @@ CONTRIBUTORS:
|
|||
Bassu <bassu@phi9.com>
|
||||
Ben Allen <bsallen@alcf.anl.gov>
|
||||
Ben Cordero <bencord0@condi.me>
|
||||
Benda Xu <orv@debian.org>
|
||||
Benedikt Neuffer <github@itfriend.de>
|
||||
Benjamin Albrecht <git@albrecht.io>
|
||||
Benjamin Gentil <benjgentil.pro@gmail.com>
|
||||
Benjamin Sherman <benjamin@holyarmy.org>
|
||||
Ben McGough <bmcgough@fredhutch.org>
|
||||
Ben Rubson <ben.rubson@gmail.com>
|
||||
Ben Wolsieffer <benwolsieffer@gmail.com>
|
||||
|
@ -111,6 +113,7 @@ CONTRIBUTORS:
|
|||
bzzz77 <bzzz.tomas@gmail.com>
|
||||
cable2999 <cable2999@users.noreply.github.com>
|
||||
Caleb James DeLisle <calebdelisle@lavabit.com>
|
||||
Cameron Harr <harr1@llnl.gov>
|
||||
Cao Xuewen <cao.xuewen@zte.com.cn>
|
||||
Carlo Landmeter <clandmeter@gmail.com>
|
||||
Carlos Alberto Lopez Perez <clopez@igalia.com>
|
||||
|
@ -120,12 +123,15 @@ CONTRIBUTORS:
|
|||
Chen Can <chen.can2@zte.com.cn>
|
||||
Chengfei Zhu <chengfeix.zhu@intel.com>
|
||||
Chen Haiquan <oc@yunify.com>
|
||||
ChenHao Lu <18302010006@fudan.edu.cn>
|
||||
Chip Parker <aparker@enthought.com>
|
||||
Chris Burroughs <chris.burroughs@gmail.com>
|
||||
Chris Davidson <christopher.davidson@gmail.com>
|
||||
Chris Dunlap <cdunlap@llnl.gov>
|
||||
Chris Dunlop <chris@onthe.net.au>
|
||||
Chris Lindee <chris.lindee+github@gmail.com>
|
||||
Chris McDonough <chrism@plope.com>
|
||||
Chris Peredun <chris.peredun@ixsystems.com>
|
||||
Chris Siden <chris.siden@delphix.com>
|
||||
Chris Siebenmann <cks.github@cs.toronto.edu>
|
||||
Christer Ekholm <che@chrekh.se>
|
||||
|
@ -144,6 +150,7 @@ CONTRIBUTORS:
|
|||
Clint Armstrong <clint@clintarmstrong.net>
|
||||
Coleman Kane <ckane@colemankane.org>
|
||||
Colin Ian King <colin.king@canonical.com>
|
||||
Colin Percival <cperciva@tarsnap.com>
|
||||
Colm Buckley <colm@tuatha.org>
|
||||
Crag Wang <crag0715@gmail.com>
|
||||
Craig Loomis <cloomis@astro.princeton.edu>
|
||||
|
@ -156,6 +163,7 @@ CONTRIBUTORS:
|
|||
Damiano Albani <damiano.albani@gmail.com>
|
||||
Damian Szuberski <szuberskidamian@gmail.com>
|
||||
Damian Wojsław <damian@wojslaw.pl>
|
||||
Daniel Berlin <dberlin@dberlin.org>
|
||||
Daniel Hiepler <d-git@coderdu.de>
|
||||
Daniel Hoffman <dj.hoffman@delphix.com>
|
||||
Daniel Kobras <d.kobras@science-computing.de>
|
||||
|
@ -176,8 +184,10 @@ CONTRIBUTORS:
|
|||
David Quigley <david.quigley@intel.com>
|
||||
Debabrata Banerjee <dbanerje@akamai.com>
|
||||
D. Ebdrup <debdrup@freebsd.org>
|
||||
Dennis R. Friedrichsen <dennis.r.friedrichsen@gmail.com>
|
||||
Denys Rtveliashvili <denys@rtveliashvili.name>
|
||||
Derek Dai <daiderek@gmail.com>
|
||||
Dex Wood <slash2314@gmail.com>
|
||||
DHE <git@dehacked.net>
|
||||
Didier Roche <didrocks@ubuntu.com>
|
||||
Dimitri John Ledkov <xnox@ubuntu.com>
|
||||
|
@ -235,9 +245,11 @@ CONTRIBUTORS:
|
|||
Gionatan Danti <g.danti@assyoma.it>
|
||||
Giuseppe Di Natale <guss80@gmail.com>
|
||||
Glenn Washburn <development@efficientek.com>
|
||||
gofaster <felix.gofaster@gmail.com>
|
||||
Gordan Bobic <gordan@redsleeve.org>
|
||||
Gordon Bergling <gbergling@googlemail.com>
|
||||
Gordon Ross <gwr@nexenta.com>
|
||||
Gordon Tetlow <gordon@freebsd.org>
|
||||
Graham Christensen <graham@grahamc.com>
|
||||
Graham Perrin <grahamperrin@gmail.com>
|
||||
Gregor Kopka <gregor@kopka.net>
|
||||
|
@ -265,6 +277,7 @@ CONTRIBUTORS:
|
|||
Igor Kozhukhov <ikozhukhov@gmail.com>
|
||||
Igor Lvovsky <ilvovsky@gmail.com>
|
||||
ilbsmart <wgqimut@gmail.com>
|
||||
Ilkka Sovanto <github@ilkka.kapsi.fi>
|
||||
illiliti <illiliti@protonmail.com>
|
||||
ilovezfs <ilovezfs@icloud.com>
|
||||
InsanePrawn <Insane.Prawny@gmail.com>
|
||||
|
@ -280,9 +293,11 @@ CONTRIBUTORS:
|
|||
Jan Engelhardt <jengelh@inai.de>
|
||||
Jan Kryl <jan.kryl@nexenta.com>
|
||||
Jan Sanislo <oystr@cs.washington.edu>
|
||||
Jaron Kent-Dobias <jaron@kent-dobias.com>
|
||||
Jason Cohen <jwittlincohen@gmail.com>
|
||||
Jason Harmening <jason.harmening@gmail.com>
|
||||
Jason King <jason.brian.king@gmail.com>
|
||||
Jason Lee <jasonlee@lanl.gov>
|
||||
Jason Zaman <jasonzaman@gmail.com>
|
||||
Javen Wu <wu.javen@gmail.com>
|
||||
Jean-Baptiste Lallement <jean-baptiste@ubuntu.com>
|
||||
|
@ -313,6 +328,7 @@ CONTRIBUTORS:
|
|||
Jonathon Fernyhough <jonathon@m2x.dev>
|
||||
Jorgen Lundman <lundman@lundman.net>
|
||||
Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
|
||||
Jose Luis Duran <jlduran@gmail.com>
|
||||
Josh Soref <jsoref@users.noreply.github.com>
|
||||
Joshua M. Clulow <josh@sysmgr.org>
|
||||
José Luis Salvador Rufo <salvador.joseluis@gmail.com>
|
||||
|
@ -336,8 +352,10 @@ CONTRIBUTORS:
|
|||
Kash Pande <kash@tripleback.net>
|
||||
Kay Pedersen <christianpe96@gmail.com>
|
||||
Keith M Wesolowski <wesolows@foobazco.org>
|
||||
Kent Ross <k@mad.cash>
|
||||
KernelOfTruth <kerneloftruth@gmail.com>
|
||||
Kevin Bowling <kevin.bowling@kev009.com>
|
||||
Kevin Greene <kevin.greene@delphix.com>
|
||||
Kevin Jin <lostking2008@hotmail.com>
|
||||
Kevin P. Fleming <kevin@km6g.us>
|
||||
Kevin Tanguy <kevin.tanguy@ovh.net>
|
||||
|
@ -389,6 +407,7 @@ CONTRIBUTORS:
|
|||
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
|
||||
marku89 <mar42@kola.li>
|
||||
Mark Wright <markwright@internode.on.net>
|
||||
Mart Frauenlob <allkind@fastest.cc>
|
||||
Martin Matuska <mm@FreeBSD.org>
|
||||
Martin Rüegg <martin.rueegg@metaworx.ch>
|
||||
Massimo Maggi <me@massimo-maggi.eu>
|
||||
|
@ -405,6 +424,7 @@ CONTRIBUTORS:
|
|||
Matus Kral <matuskral@me.com>
|
||||
Mauricio Faria de Oliveira <mfo@canonical.com>
|
||||
Max Grossman <max.grossman@delphix.com>
|
||||
Maxim Filimonov <che@bein.link>
|
||||
Maximilian Mehnert <maximilian.mehnert@gmx.de>
|
||||
Max Zettlmeißl <max@zettlmeissl.de>
|
||||
Md Islam <mdnahian@outlook.com>
|
||||
|
@ -417,6 +437,7 @@ CONTRIBUTORS:
|
|||
Michael Niewöhner <foss@mniewoehner.de>
|
||||
Michael Zhivich <mzhivich@akamai.com>
|
||||
Michal Vasilek <michal@vasilek.cz>
|
||||
MigeljanImeri <ImeriMigel@gmail.com>
|
||||
Mike Gerdts <mike.gerdts@joyent.com>
|
||||
Mike Harsch <mike@harschsystems.com>
|
||||
Mike Leddy <mike.leddy@gmail.com>
|
||||
|
@ -448,6 +469,7 @@ CONTRIBUTORS:
|
|||
Olaf Faaland <faaland1@llnl.gov>
|
||||
Oleg Drokin <green@linuxhacker.ru>
|
||||
Oleg Stepura <oleg@stepura.com>
|
||||
Olivier Certner <olce.freebsd@certner.fr>
|
||||
Olivier Mazouffre <olivier.mazouffre@ims-bordeaux.fr>
|
||||
omni <omni+vagant@hack.org>
|
||||
Orivej Desh <orivej@gmx.fr>
|
||||
|
@ -479,6 +501,7 @@ CONTRIBUTORS:
|
|||
Prasad Joshi <prasadjoshi124@gmail.com>
|
||||
privb0x23 <privb0x23@users.noreply.github.com>
|
||||
P.SCH <p88@yahoo.com>
|
||||
Quartz <yyhran@163.com>
|
||||
Quentin Zdanis <zdanisq@gmail.com>
|
||||
Rafael Kitover <rkitover@gmail.com>
|
||||
RageLtMan <sempervictus@users.noreply.github.com>
|
||||
|
@ -491,11 +514,15 @@ CONTRIBUTORS:
|
|||
Riccardo Schirone <rschirone91@gmail.com>
|
||||
Richard Allen <belperite@gmail.com>
|
||||
Richard Elling <Richard.Elling@RichardElling.com>
|
||||
Richard Kojedzinszky <richard@kojedz.in>
|
||||
Richard Laager <rlaager@wiktel.com>
|
||||
Richard Lowe <richlowe@richlowe.net>
|
||||
Richard Sharpe <rsharpe@samba.org>
|
||||
Richard Yao <ryao@gentoo.org>
|
||||
Rich Ercolani <rincebrain@gmail.com>
|
||||
Rick Macklem <rmacklem@uoguelph.ca>
|
||||
rilysh <nightquick@proton.me>
|
||||
Robert Evans <evansr@google.com>
|
||||
Robert Novak <sailnfool@gmail.com>
|
||||
Roberto Ricci <ricci@disroot.org>
|
||||
Rob Norris <robn@despairlabs.com>
|
||||
|
@ -509,7 +536,9 @@ CONTRIBUTORS:
|
|||
Ryan Lahfa <masterancpp@gmail.com>
|
||||
Ryan Libby <rlibby@FreeBSD.org>
|
||||
Ryan Moeller <freqlabs@FreeBSD.org>
|
||||
Sam Atkinson <samatk@amazon.com>
|
||||
Sam Hathaway <github.com@munkynet.org>
|
||||
Sam James <sam@gentoo.org>
|
||||
Sam Lunt <samuel.j.lunt@gmail.com>
|
||||
Samuel VERSCHELDE <stormi-github@ylix.fr>
|
||||
Samuel Wycliffe <samuelwycliffe@gmail.com>
|
||||
|
@ -530,6 +559,8 @@ CONTRIBUTORS:
|
|||
Shaan Nobee <sniper111@gmail.com>
|
||||
Shampavman <sham.pavman@nexenta.com>
|
||||
Shaun Tancheff <shaun@aeonazure.com>
|
||||
Shawn Bayern <sbayern@law.fsu.edu>
|
||||
Shengqi Chen <harry-chen@outlook.com>
|
||||
Shen Yan <shenyanxxxy@qq.com>
|
||||
Simon Guest <simon.guest@tesujimath.org>
|
||||
Simon Klinkert <simon.klinkert@gmail.com>
|
||||
|
@ -537,6 +568,7 @@ CONTRIBUTORS:
|
|||
Spencer Kinny <spencerkinny1995@gmail.com>
|
||||
Srikanth N S <srikanth.nagasubbaraoseetharaman@hpe.com>
|
||||
Stanislav Seletskiy <s.seletskiy@gmail.com>
|
||||
Stefan Lendl <s.lendl@proxmox.com>
|
||||
Steffen Müthing <steffen.muething@iwr.uni-heidelberg.de>
|
||||
Stephen Blinick <stephen.blinick@delphix.com>
|
||||
sterlingjensen <sterlingjensen@users.noreply.github.com>
|
||||
|
@ -557,6 +589,7 @@ CONTRIBUTORS:
|
|||
Teodor Spæren <teodor_spaeren@riseup.net>
|
||||
TerraTech <TerraTech@users.noreply.github.com>
|
||||
Thijs Cramer <thijs.cramer@gmail.com>
|
||||
Thomas Bertschinger <bertschinger@lanl.gov>
|
||||
Thomas Geppert <geppi@digitx.de>
|
||||
Thomas Lamprecht <guggentom@hotmail.de>
|
||||
Till Maas <opensource@till.name>
|
||||
|
@ -586,6 +619,7 @@ CONTRIBUTORS:
|
|||
Turbo Fredriksson <turbo@bayour.com>
|
||||
Tyler J. Stachecki <stachecki.tyler@gmail.com>
|
||||
Umer Saleem <usaleem@ixsystems.com>
|
||||
Vaibhav Bhanawat <vaibhav.bhanawat@delphix.com>
|
||||
Valmiky Arquissandas <kayvlim@gmail.com>
|
||||
Val Packett <val@packett.cool>
|
||||
Vince van Oosten <techhazard@codeforyouand.me>
|
||||
|
@ -614,6 +648,7 @@ CONTRIBUTORS:
|
|||
yuina822 <ayuichi@club.kyutech.ac.jp>
|
||||
YunQiang Su <syq@debian.org>
|
||||
Yuri Pankov <yuri.pankov@gmail.com>
|
||||
Yuxin Wang <yuxinwang9999@gmail.com>
|
||||
Yuxuan Shui <yshuiv7@gmail.com>
|
||||
Zachary Bedell <zac@thebedells.org>
|
||||
Zach Dykstra <dykstra.zachary@gmail.com>
|
||||
|
|
2
META
2
META
|
@ -6,5 +6,5 @@ Release: 1
|
|||
Release-Tags: relext
|
||||
License: CDDL
|
||||
Author: OpenZFS
|
||||
Linux-Maximum: 6.7
|
||||
Linux-Maximum: 6.8
|
||||
Linux-Minimum: 3.10
|
||||
|
|
|
@ -157,6 +157,16 @@ cols = {
|
|||
"free": [5, 1024, "ARC free memory"],
|
||||
"avail": [5, 1024, "ARC available memory"],
|
||||
"waste": [5, 1024, "Wasted memory due to round up to pagesize"],
|
||||
"ztotal": [6, 1000, "zfetch total prefetcher calls per second"],
|
||||
"zhits": [5, 1000, "zfetch stream hits per second"],
|
||||
"zahead": [6, 1000, "zfetch hits ahead of streams per second"],
|
||||
"zpast": [5, 1000, "zfetch hits behind streams per second"],
|
||||
"zmisses": [7, 1000, "zfetch stream misses per second"],
|
||||
"zmax": [4, 1000, "zfetch limit reached per second"],
|
||||
"zfuture": [7, 1000, "zfetch stream future per second"],
|
||||
"zstride": [7, 1000, "zfetch stream strides per second"],
|
||||
"zissued": [7, 1000, "zfetch prefetches issued per second"],
|
||||
"zactive": [7, 1000, "zfetch prefetches active per second"],
|
||||
}
|
||||
|
||||
v = {}
|
||||
|
@ -164,6 +174,8 @@ hdr = ["time", "read", "ddread", "ddh%", "dmread", "dmh%", "pread", "ph%",
|
|||
"size", "c", "avail"]
|
||||
xhdr = ["time", "mfu", "mru", "mfug", "mrug", "unc", "eskip", "mtxmis",
|
||||
"dread", "pread", "read"]
|
||||
zhdr = ["time", "ztotal", "zhits", "zahead", "zpast", "zmisses", "zmax",
|
||||
"zfuture", "zstride", "zissued", "zactive"]
|
||||
sint = 1 # Default interval is 1 second
|
||||
count = 1 # Default count is 1
|
||||
hdr_intr = 20 # Print header every 20 lines of output
|
||||
|
@ -188,6 +200,8 @@ if sys.platform.startswith('freebsd'):
|
|||
|
||||
k = [ctl for ctl in sysctl.filter('kstat.zfs.misc.arcstats')
|
||||
if ctl.type != sysctl.CTLTYPE_NODE]
|
||||
k += [ctl for ctl in sysctl.filter('kstat.zfs.misc.zfetchstats')
|
||||
if ctl.type != sysctl.CTLTYPE_NODE]
|
||||
|
||||
if not k:
|
||||
sys.exit(1)
|
||||
|
@ -199,19 +213,28 @@ if sys.platform.startswith('freebsd'):
|
|||
continue
|
||||
|
||||
name, value = s.name, s.value
|
||||
# Trims 'kstat.zfs.misc.arcstats' from the name
|
||||
kstat[name[24:]] = int(value)
|
||||
|
||||
if "arcstats" in name:
|
||||
# Trims 'kstat.zfs.misc.arcstats' from the name
|
||||
kstat[name[24:]] = int(value)
|
||||
else:
|
||||
kstat["zfetch_" + name[27:]] = int(value)
|
||||
|
||||
elif sys.platform.startswith('linux'):
|
||||
def kstat_update():
|
||||
global kstat
|
||||
|
||||
k = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')]
|
||||
k1 = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')]
|
||||
|
||||
if not k:
|
||||
k2 = ["zfetch_" + line.strip() for line in
|
||||
open('/proc/spl/kstat/zfs/zfetchstats')]
|
||||
|
||||
if k1 is None or k2 is None:
|
||||
sys.exit(1)
|
||||
|
||||
del k[0:2]
|
||||
del k1[0:2]
|
||||
del k2[0:2]
|
||||
k = k1 + k2
|
||||
kstat = {}
|
||||
|
||||
for s in k:
|
||||
|
@ -239,6 +262,7 @@ def usage():
|
|||
sys.stderr.write("\t -v : List all possible field headers and definitions"
|
||||
"\n")
|
||||
sys.stderr.write("\t -x : Print extended stats\n")
|
||||
sys.stderr.write("\t -z : Print zfetch stats\n")
|
||||
sys.stderr.write("\t -f : Specify specific fields to print (see -v)\n")
|
||||
sys.stderr.write("\t -o : Redirect output to the specified file\n")
|
||||
sys.stderr.write("\t -s : Override default field separator with custom "
|
||||
|
@ -357,6 +381,7 @@ def init():
|
|||
global count
|
||||
global hdr
|
||||
global xhdr
|
||||
global zhdr
|
||||
global opfile
|
||||
global sep
|
||||
global out
|
||||
|
@ -368,15 +393,17 @@ def init():
|
|||
xflag = False
|
||||
hflag = False
|
||||
vflag = False
|
||||
zflag = False
|
||||
i = 1
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(
|
||||
sys.argv[1:],
|
||||
"axo:hvs:f:p",
|
||||
"axzo:hvs:f:p",
|
||||
[
|
||||
"all",
|
||||
"extended",
|
||||
"zfetch",
|
||||
"outfile",
|
||||
"help",
|
||||
"verbose",
|
||||
|
@ -410,13 +437,15 @@ def init():
|
|||
i += 1
|
||||
if opt in ('-p', '--parsable'):
|
||||
pretty_print = False
|
||||
if opt in ('-z', '--zfetch'):
|
||||
zflag = True
|
||||
i += 1
|
||||
|
||||
argv = sys.argv[i:]
|
||||
sint = int(argv[0]) if argv else sint
|
||||
count = int(argv[1]) if len(argv) > 1 else (0 if len(argv) > 0 else 1)
|
||||
|
||||
if hflag or (xflag and desired_cols):
|
||||
if hflag or (xflag and zflag) or ((zflag or xflag) and desired_cols):
|
||||
usage()
|
||||
|
||||
if vflag:
|
||||
|
@ -425,6 +454,9 @@ def init():
|
|||
if xflag:
|
||||
hdr = xhdr
|
||||
|
||||
if zflag:
|
||||
hdr = zhdr
|
||||
|
||||
update_hdr_intr()
|
||||
|
||||
# check if L2ARC exists
|
||||
|
@ -569,6 +601,17 @@ def calculate():
|
|||
v["el2mru"] = d["evict_l2_eligible_mru"] // sint
|
||||
v["el2inel"] = d["evict_l2_ineligible"] // sint
|
||||
v["mtxmis"] = d["mutex_miss"] // sint
|
||||
v["ztotal"] = (d["zfetch_hits"] + d["zfetch_future"] + d["zfetch_stride"] +
|
||||
d["zfetch_past"] + d["zfetch_misses"]) // sint
|
||||
v["zhits"] = d["zfetch_hits"] // sint
|
||||
v["zahead"] = (d["zfetch_future"] + d["zfetch_stride"]) // sint
|
||||
v["zpast"] = d["zfetch_past"] // sint
|
||||
v["zmisses"] = d["zfetch_misses"] // sint
|
||||
v["zmax"] = d["zfetch_max_streams"] // sint
|
||||
v["zfuture"] = d["zfetch_future"] // sint
|
||||
v["zstride"] = d["zfetch_stride"] // sint
|
||||
v["zissued"] = d["zfetch_io_issued"] // sint
|
||||
v["zactive"] = d["zfetch_io_active"] // sint
|
||||
|
||||
if l2exist:
|
||||
v["l2hits"] = d["l2_hits"] // sint
|
||||
|
|
196
cmd/zdb/zdb.c
196
cmd/zdb/zdb.c
|
@ -85,9 +85,11 @@
|
|||
#include <sys/brt_impl.h>
|
||||
#include <zfs_comutil.h>
|
||||
#include <sys/zstd/zstd.h>
|
||||
#include <sys/backtrace.h>
|
||||
|
||||
#include <libnvpair.h>
|
||||
#include <libzutil.h>
|
||||
#include <libzfs_core.h>
|
||||
|
||||
#include <libzdb.h>
|
||||
|
||||
|
@ -120,6 +122,9 @@ static int flagbits[256];
|
|||
static uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */
|
||||
static int leaked_objects = 0;
|
||||
static range_tree_t *mos_refd_objs;
|
||||
static spa_t *spa;
|
||||
static objset_t *os;
|
||||
static boolean_t kernel_init_done;
|
||||
|
||||
static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *,
|
||||
boolean_t);
|
||||
|
@ -131,6 +136,7 @@ static int dump_bpobj_cb(void *arg, const blkptr_t *bp, boolean_t free,
|
|||
|
||||
|
||||
static void zdb_print_blkptr(const blkptr_t *bp, int flags);
|
||||
static void zdb_exit(int reason);
|
||||
|
||||
typedef struct sublivelist_verify_block_refcnt {
|
||||
/* block pointer entry in livelist being verified */
|
||||
|
@ -818,17 +824,40 @@ usage(void)
|
|||
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
|
||||
"to make only that option verbose\n");
|
||||
(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_debug_buffer(void)
|
||||
{
|
||||
if (dump_opt['G']) {
|
||||
(void) printf("\n");
|
||||
(void) fflush(stdout);
|
||||
zfs_dbgmsg_print("zdb");
|
||||
}
|
||||
ssize_t ret __attribute__((unused));
|
||||
|
||||
if (!dump_opt['G'])
|
||||
return;
|
||||
/*
|
||||
* We use write() instead of printf() so that this function
|
||||
* is safe to call from a signal handler.
|
||||
*/
|
||||
ret = write(STDERR_FILENO, "\n", 1);
|
||||
zfs_dbgmsg_print(STDERR_FILENO, "zdb");
|
||||
}
|
||||
|
||||
static void sig_handler(int signo)
|
||||
{
|
||||
struct sigaction action;
|
||||
|
||||
libspl_backtrace(STDERR_FILENO);
|
||||
dump_debug_buffer();
|
||||
|
||||
/*
|
||||
* Restore default action and re-raise signal so SIGSEGV and
|
||||
* SIGABRT can trigger a core dump.
|
||||
*/
|
||||
action.sa_handler = SIG_DFL;
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_flags = 0;
|
||||
(void) sigaction(signo, &action, NULL);
|
||||
raise(signo);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -849,7 +878,7 @@ fatal(const char *fmt, ...)
|
|||
|
||||
dump_debug_buffer();
|
||||
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2276,7 +2305,7 @@ snprintf_zstd_header(spa_t *spa, char *blkbuf, size_t buflen,
|
|||
buf = malloc(SPA_MAXBLOCKSIZE);
|
||||
if (buf == NULL) {
|
||||
(void) fprintf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
decode_embedded_bp_compressed(bp, buf);
|
||||
memcpy(&zstd_hdr, buf, sizeof (zstd_hdr));
|
||||
|
@ -3231,6 +3260,23 @@ fuid_table_destroy(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
zdb_exit(int reason)
|
||||
{
|
||||
if (os != NULL) {
|
||||
close_objset(os, FTAG);
|
||||
} else if (spa != NULL) {
|
||||
spa_close(spa, FTAG);
|
||||
}
|
||||
|
||||
fuid_table_destroy();
|
||||
|
||||
if (kernel_init_done)
|
||||
kernel_fini();
|
||||
|
||||
exit(reason);
|
||||
}
|
||||
|
||||
/*
|
||||
* print uid or gid information.
|
||||
* For normal POSIX id just the id is printed in decimal format.
|
||||
|
@ -4161,32 +4207,32 @@ dump_cachefile(const char *cachefile)
|
|||
if ((fd = open64(cachefile, O_RDONLY)) < 0) {
|
||||
(void) printf("cannot open '%s': %s\n", cachefile,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
|
||||
if (fstat64(fd, &statbuf) != 0) {
|
||||
(void) printf("failed to stat '%s': %s\n", cachefile,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
|
||||
if ((buf = malloc(statbuf.st_size)) == NULL) {
|
||||
(void) fprintf(stderr, "failed to allocate %llu bytes\n",
|
||||
(u_longlong_t)statbuf.st_size);
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
|
||||
if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
|
||||
(void) fprintf(stderr, "failed to read %llu bytes\n",
|
||||
(u_longlong_t)statbuf.st_size);
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
|
||||
if (nvlist_unpack(buf, statbuf.st_size, &config, 0) != 0) {
|
||||
(void) fprintf(stderr, "failed to unpack nvlist\n");
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
@ -5102,14 +5148,14 @@ dump_label(const char *dev)
|
|||
|
||||
if ((fd = open64(path, O_RDONLY)) < 0) {
|
||||
(void) printf("cannot open '%s': %s\n", path, strerror(errno));
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
|
||||
if (fstat64_blk(fd, &statbuf) != 0) {
|
||||
(void) printf("failed to stat '%s': %s\n", path,
|
||||
strerror(errno));
|
||||
(void) close(fd);
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
|
||||
if (S_ISBLK(statbuf.st_mode) && zfs_dev_flush(fd) != 0)
|
||||
|
@ -5122,7 +5168,7 @@ dump_label(const char *dev)
|
|||
sizeof (cksum_record_t), offsetof(cksum_record_t, link));
|
||||
|
||||
psize = statbuf.st_size;
|
||||
psize = P2ALIGN(psize, (uint64_t)sizeof (vdev_label_t));
|
||||
psize = P2ALIGN_TYPED(psize, sizeof (vdev_label_t), uint64_t);
|
||||
ashift = SPA_MINBLOCKSHIFT;
|
||||
|
||||
/*
|
||||
|
@ -8221,7 +8267,7 @@ dump_zpool(spa_t *spa)
|
|||
|
||||
if (rc != 0) {
|
||||
dump_debug_buffer();
|
||||
exit(rc);
|
||||
zdb_exit(rc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8825,18 +8871,18 @@ zdb_embedded_block(char *thing)
|
|||
words + 12, words + 13, words + 14, words + 15);
|
||||
if (err != 16) {
|
||||
(void) fprintf(stderr, "invalid input format\n");
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE);
|
||||
buf = malloc(SPA_MAXBLOCKSIZE);
|
||||
if (buf == NULL) {
|
||||
(void) fprintf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp));
|
||||
if (err != 0) {
|
||||
(void) fprintf(stderr, "decode failed: %u\n", err);
|
||||
exit(1);
|
||||
zdb_exit(1);
|
||||
}
|
||||
zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0);
|
||||
free(buf);
|
||||
|
@ -8863,8 +8909,6 @@ int
|
|||
main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
spa_t *spa = NULL;
|
||||
objset_t *os = NULL;
|
||||
int dump_all = 1;
|
||||
int verbose = 0;
|
||||
int error = 0;
|
||||
|
@ -8880,9 +8924,30 @@ main(int argc, char **argv)
|
|||
char *spa_config_path_env, *objset_str;
|
||||
boolean_t target_is_spa = B_TRUE, dataset_lookup = B_FALSE;
|
||||
nvlist_t *cfg = NULL;
|
||||
struct sigaction action;
|
||||
boolean_t force_import = B_FALSE;
|
||||
boolean_t config_path_console = B_FALSE;
|
||||
char pbuf[MAXPATHLEN];
|
||||
|
||||
dprintf_setup(&argc, argv);
|
||||
|
||||
/*
|
||||
* Set up signal handlers, so if we crash due to bad on-disk data we
|
||||
* can get more info. Unlike ztest, we don't bail out if we can't set
|
||||
* up signal handlers, because zdb is very useful without them.
|
||||
*/
|
||||
action.sa_handler = sig_handler;
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_flags = 0;
|
||||
if (sigaction(SIGSEGV, &action, NULL) < 0) {
|
||||
(void) fprintf(stderr, "zdb: cannot catch SIGSEGV: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
if (sigaction(SIGABRT, &action, NULL) < 0) {
|
||||
(void) fprintf(stderr, "zdb: cannot catch SIGABRT: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is an environment variable SPA_CONFIG_PATH it overrides
|
||||
* default spa_config_path setting. If -U flag is specified it will
|
||||
|
@ -9033,6 +9098,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
break;
|
||||
case 'U':
|
||||
config_path_console = B_TRUE;
|
||||
spa_config_path = optarg;
|
||||
if (spa_config_path[0] != '/') {
|
||||
(void) fprintf(stderr,
|
||||
|
@ -9092,8 +9158,6 @@ main(int argc, char **argv)
|
|||
*/
|
||||
spa_mode_readable_spacemaps = B_TRUE;
|
||||
|
||||
kernel_init(SPA_MODE_READ);
|
||||
|
||||
if (dump_all)
|
||||
verbose = MAX(verbose, 1);
|
||||
|
||||
|
@ -9112,23 +9176,74 @@ main(int argc, char **argv)
|
|||
if (argc < 2 && dump_opt['R'])
|
||||
usage();
|
||||
|
||||
target = argv[0];
|
||||
|
||||
/*
|
||||
* Automate cachefile
|
||||
*/
|
||||
if (!spa_config_path_env && !config_path_console && target &&
|
||||
libzfs_core_init() == 0) {
|
||||
char *pname = strdup(target);
|
||||
const char *value;
|
||||
nvlist_t *pnvl = NULL;
|
||||
nvlist_t *vnvl;
|
||||
|
||||
if (strpbrk(pname, "/@") != NULL)
|
||||
*strpbrk(pname, "/@") = '\0';
|
||||
|
||||
if (pname && lzc_get_props(pname, &pnvl) == 0) {
|
||||
if (nvlist_lookup_nvlist(pnvl, "cachefile",
|
||||
&vnvl) == 0) {
|
||||
value = fnvlist_lookup_string(vnvl,
|
||||
ZPROP_VALUE);
|
||||
} else {
|
||||
value = "-";
|
||||
}
|
||||
strlcpy(pbuf, value, sizeof (pbuf));
|
||||
if (pbuf[0] != '\0') {
|
||||
if (pbuf[0] == '/') {
|
||||
if (access(pbuf, F_OK) == 0)
|
||||
spa_config_path = pbuf;
|
||||
else
|
||||
force_import = B_TRUE;
|
||||
} else if ((strcmp(pbuf, "-") == 0 &&
|
||||
access(ZPOOL_CACHE, F_OK) != 0) ||
|
||||
strcmp(pbuf, "none") == 0) {
|
||||
force_import = B_TRUE;
|
||||
}
|
||||
}
|
||||
nvlist_free(vnvl);
|
||||
}
|
||||
|
||||
free(pname);
|
||||
nvlist_free(pnvl);
|
||||
libzfs_core_fini();
|
||||
}
|
||||
|
||||
kernel_init(SPA_MODE_READ);
|
||||
kernel_init_done = B_TRUE;
|
||||
|
||||
if (dump_opt['E']) {
|
||||
if (argc != 1)
|
||||
usage();
|
||||
zdb_embedded_block(argv[0]);
|
||||
return (0);
|
||||
error = 0;
|
||||
goto fini;
|
||||
}
|
||||
|
||||
if (argc < 1) {
|
||||
if (!dump_opt['e'] && dump_opt['C']) {
|
||||
dump_cachefile(spa_config_path);
|
||||
return (0);
|
||||
error = 0;
|
||||
goto fini;
|
||||
}
|
||||
usage();
|
||||
}
|
||||
|
||||
if (dump_opt['l'])
|
||||
return (dump_label(argv[0]));
|
||||
if (dump_opt['l']) {
|
||||
error = dump_label(argv[0]);
|
||||
goto fini;
|
||||
}
|
||||
|
||||
if (dump_opt['X'] || dump_opt['F'])
|
||||
rewind = ZPOOL_DO_REWIND |
|
||||
|
@ -9144,7 +9259,6 @@ main(int argc, char **argv)
|
|||
fatal("internal error: %s", strerror(ENOMEM));
|
||||
|
||||
error = 0;
|
||||
target = argv[0];
|
||||
|
||||
if (strpbrk(target, "/@") != NULL) {
|
||||
size_t targetlen;
|
||||
|
@ -9183,15 +9297,24 @@ main(int argc, char **argv)
|
|||
} else if (objset_str && !zdb_numeric(objset_str + 1) &&
|
||||
dump_opt['N']) {
|
||||
printf("Supply a numeric objset ID with -N\n");
|
||||
exit(1);
|
||||
error = 1;
|
||||
goto fini;
|
||||
}
|
||||
} else {
|
||||
target_pool = target;
|
||||
}
|
||||
|
||||
if (dump_opt['e']) {
|
||||
if (dump_opt['e'] || force_import) {
|
||||
importargs_t args = { 0 };
|
||||
|
||||
/*
|
||||
* If path is not provided, search in /dev
|
||||
*/
|
||||
if (searchdirs == NULL) {
|
||||
searchdirs = umem_alloc(sizeof (char *), UMEM_NOFAIL);
|
||||
searchdirs[nsearch++] = (char *)ZFS_DEVDIR;
|
||||
}
|
||||
|
||||
args.paths = nsearch;
|
||||
args.path = searchdirs;
|
||||
args.can_be_active = B_TRUE;
|
||||
|
@ -9240,7 +9363,8 @@ main(int argc, char **argv)
|
|||
if (argc != 2)
|
||||
usage();
|
||||
dump_opt['v'] = verbose + 3;
|
||||
return (dump_path(argv[0], argv[1], NULL));
|
||||
error = dump_path(argv[0], argv[1], NULL);
|
||||
goto fini;
|
||||
}
|
||||
|
||||
if (dump_opt['r']) {
|
||||
|
@ -9328,7 +9452,7 @@ main(int argc, char **argv)
|
|||
fatal("can't dump '%s': %s", target,
|
||||
strerror(error));
|
||||
}
|
||||
return (error);
|
||||
goto fini;
|
||||
} else {
|
||||
target_pool = strdup(target);
|
||||
if (strpbrk(target, "/@") != NULL)
|
||||
|
@ -9458,9 +9582,10 @@ retry_lookup:
|
|||
free(checkpoint_target);
|
||||
}
|
||||
|
||||
fini:
|
||||
if (os != NULL) {
|
||||
close_objset(os, FTAG);
|
||||
} else {
|
||||
} else if (spa != NULL) {
|
||||
spa_close(spa, FTAG);
|
||||
}
|
||||
|
||||
|
@ -9468,7 +9593,8 @@ retry_lookup:
|
|||
|
||||
dump_debug_buffer();
|
||||
|
||||
kernel_fini();
|
||||
if (kernel_init_done)
|
||||
kernel_fini();
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
|
|
@ -703,7 +703,7 @@ zfs_enable_ds(void *arg)
|
|||
{
|
||||
unavailpool_t *pool = (unavailpool_t *)arg;
|
||||
|
||||
(void) zpool_enable_datasets(pool->uap_zhp, NULL, 0);
|
||||
(void) zpool_enable_datasets(pool->uap_zhp, NULL, 0, 512);
|
||||
zpool_close(pool->uap_zhp);
|
||||
free(pool);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ dist_zedexec_SCRIPTS = \
|
|||
%D%/all-debug.sh \
|
||||
%D%/all-syslog.sh \
|
||||
%D%/data-notify.sh \
|
||||
%D%/deadman-slot_off.sh \
|
||||
%D%/generic-notify.sh \
|
||||
%D%/pool_import-led.sh \
|
||||
%D%/resilver_finish-notify.sh \
|
||||
|
@ -29,6 +30,7 @@ SUBSTFILES += $(nodist_zedexec_SCRIPTS)
|
|||
zedconfdefaults = \
|
||||
all-syslog.sh \
|
||||
data-notify.sh \
|
||||
deadman-slot_off.sh \
|
||||
history_event-zfs-list-cacher.sh \
|
||||
pool_import-led.sh \
|
||||
resilver_finish-notify.sh \
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
#!/bin/sh
|
||||
# shellcheck disable=SC3014,SC2154,SC2086,SC2034
|
||||
#
|
||||
# Turn off disk's enclosure slot if an I/O is hung triggering the deadman.
|
||||
#
|
||||
# It's possible for outstanding I/O to a misbehaving SCSI disk to neither
|
||||
# promptly complete or return an error. This can occur due to retry and
|
||||
# recovery actions taken by the SCSI layer, driver, or disk. When it occurs
|
||||
# the pool will be unresponsive even though there may be sufficient redundancy
|
||||
# configured to proceeded without this single disk.
|
||||
#
|
||||
# When a hung I/O is detected by the kmods it will be posted as a deadman
|
||||
# event. By default an I/O is considered to be hung after 5 minutes. This
|
||||
# value can be changed with the zfs_deadman_ziotime_ms module parameter.
|
||||
# If ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN is set the disk's enclosure
|
||||
# slot will be powered off causing the outstanding I/O to fail. The ZED
|
||||
# will then handle this like a normal disk failure and FAULT the vdev.
|
||||
#
|
||||
# We assume the user will be responsible for turning the slot back on
|
||||
# after replacing the disk.
|
||||
#
|
||||
# Note that this script requires that your enclosure be supported by the
|
||||
# Linux SCSI Enclosure services (SES) driver. The script will do nothing
|
||||
# if you have no enclosure, or if your enclosure isn't supported.
|
||||
#
|
||||
# Exit codes:
|
||||
# 0: slot successfully powered off
|
||||
# 1: enclosure not available
|
||||
# 2: ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN disabled
|
||||
# 3: System not configured to wait on deadman
|
||||
# 4: The enclosure sysfs path passed from ZFS does not exist
|
||||
# 5: Enclosure slot didn't actually turn off after we told it to
|
||||
|
||||
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
||||
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
||||
|
||||
if [ ! -d /sys/class/enclosure ] ; then
|
||||
# No JBOD enclosure or NVMe slots
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN}" != "1" ] ; then
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ "$ZEVENT_POOL_FAILMODE" != "wait" ] ; then
|
||||
exit 3
|
||||
fi
|
||||
|
||||
if [ ! -f "$ZEVENT_VDEV_ENC_SYSFS_PATH/power_status" ] ; then
|
||||
exit 4
|
||||
fi
|
||||
|
||||
# Turn off the slot and wait for sysfs to report that the slot is off.
|
||||
# It can take ~400ms on some enclosures and multiple retries may be needed.
|
||||
for i in $(seq 1 20) ; do
|
||||
echo "off" | tee "$ZEVENT_VDEV_ENC_SYSFS_PATH/power_status"
|
||||
|
||||
for j in $(seq 1 5) ; do
|
||||
if [ "$(cat $ZEVENT_VDEV_ENC_SYSFS_PATH/power_status)" == "off" ] ; then
|
||||
break 2
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
done
|
||||
|
||||
if [ "$(cat $ZEVENT_VDEV_ENC_SYSFS_PATH/power_status)" != "off" ] ; then
|
||||
exit 5
|
||||
fi
|
||||
|
||||
zed_log_msg "powered down slot $ZEVENT_VDEV_ENC_SYSFS_PATH for $ZEVENT_VDEV_PATH"
|
|
@ -148,6 +148,13 @@ ZED_SYSLOG_SUBCLASS_EXCLUDE="history_event"
|
|||
# supports slot power control via sysfs.
|
||||
#ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT=1
|
||||
|
||||
##
|
||||
# Power off the drive's slot in the enclosure if there is a hung I/O which
|
||||
# exceeds the deadman timeout. This can help prevent a single misbehaving
|
||||
# drive from rendering a redundant pool unavailable. This assumes your drive
|
||||
# enclosure fully supports slot power control via sysfs.
|
||||
#ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN=1
|
||||
|
||||
##
|
||||
# Ntfy topic
|
||||
# This defines which topic will receive the ntfy notification.
|
||||
|
|
|
@ -2146,15 +2146,25 @@ found2:;
|
|||
|
||||
for (char *tok; (tok = strsep(&optarg, ",")); ) {
|
||||
static const char *const type_opts[] = {
|
||||
"filesystem", "volume",
|
||||
"snapshot", "snap",
|
||||
"filesystem",
|
||||
"fs",
|
||||
"volume",
|
||||
"vol",
|
||||
"snapshot",
|
||||
"snap",
|
||||
"bookmark",
|
||||
"all" };
|
||||
"all"
|
||||
};
|
||||
static const int type_types[] = {
|
||||
ZFS_TYPE_FILESYSTEM, ZFS_TYPE_VOLUME,
|
||||
ZFS_TYPE_SNAPSHOT, ZFS_TYPE_SNAPSHOT,
|
||||
ZFS_TYPE_FILESYSTEM,
|
||||
ZFS_TYPE_FILESYSTEM,
|
||||
ZFS_TYPE_VOLUME,
|
||||
ZFS_TYPE_VOLUME,
|
||||
ZFS_TYPE_SNAPSHOT,
|
||||
ZFS_TYPE_SNAPSHOT,
|
||||
ZFS_TYPE_BOOKMARK,
|
||||
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK };
|
||||
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(type_opts); ++i)
|
||||
if (strcmp(tok, type_opts[i]) == 0) {
|
||||
|
@ -7182,6 +7192,8 @@ share_mount(int op, int argc, char **argv)
|
|||
int c, ret = 0;
|
||||
char *options = NULL;
|
||||
int flags = 0;
|
||||
const uint_t mount_nthr = 512;
|
||||
uint_t nthr;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, op == OP_MOUNT ? ":aRlvo:Of" : "al"))
|
||||
|
@ -7300,9 +7312,9 @@ share_mount(int op, int argc, char **argv)
|
|||
* be serialized so that we can prompt the user for their keys
|
||||
* in a consistent manner.
|
||||
*/
|
||||
nthr = op == OP_MOUNT && !(flags & MS_CRYPT) ? mount_nthr : 1;
|
||||
zfs_foreach_mountpoint(g_zfs, cb.cb_handles, cb.cb_used,
|
||||
share_mount_one_cb, &share_mount_state,
|
||||
op == OP_MOUNT && !(flags & MS_CRYPT));
|
||||
share_mount_one_cb, &share_mount_state, nthr);
|
||||
zfs_commit_shares(NULL);
|
||||
|
||||
ret = share_mount_state.sm_status;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2017, Intel Corporation.
|
||||
* Copyright (c) 2024, Klara Inc.
|
||||
* Copyright (c) 2023-2024, Klara Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -221,6 +221,7 @@ static const struct errstr errstrtable[] = {
|
|||
{ ENXIO, "nxio" },
|
||||
{ ECHILD, "dtl" },
|
||||
{ EILSEQ, "corrupt" },
|
||||
{ ENOSYS, "noop" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
|
@ -265,12 +266,12 @@ usage(void)
|
|||
"\t\tspa_vdev_exit() will trigger a panic.\n"
|
||||
"\n"
|
||||
"\tzinject -d device [-e errno] [-L <nvlist|uber|pad1|pad2>] [-F]\n"
|
||||
"\t\t[-T <read|write|free|claim|ioctl|all>] [-f frequency] pool\n\n"
|
||||
"\t\t[-T <read|write|free|claim|flush|all>] [-f frequency] pool\n\n"
|
||||
"\t\tInject a fault into a particular device or the device's\n"
|
||||
"\t\tlabel. Label injection can either be 'nvlist', 'uber',\n "
|
||||
"\t\t'pad1', or 'pad2'.\n"
|
||||
"\t\t'errno' can be 'nxio' (the default), 'io', 'dtl', or\n"
|
||||
"\t\t'corrupt' (bit flip).\n"
|
||||
"\t\t'errno' can be 'nxio' (the default), 'io', 'dtl',\n"
|
||||
"\t\t'corrupt' (bit flip), or 'noop' (successfully do nothing).\n"
|
||||
"\t\t'frequency' is a value between 0.0001 and 100.0 that limits\n"
|
||||
"\t\tdevice error injection to a percentage of the IOs.\n"
|
||||
"\n"
|
||||
|
@ -309,6 +310,11 @@ usage(void)
|
|||
"\t\tcreate 3 lanes on the device; one lane with a latency\n"
|
||||
"\t\tof 10 ms and two lanes with a 25 ms latency.\n"
|
||||
"\n"
|
||||
"\tzinject -P import|export -s <seconds> pool\n"
|
||||
"\t\tAdd an artificial delay to a future pool import or export,\n"
|
||||
"\t\tsuch that the operation takes a minimum of supplied seconds\n"
|
||||
"\t\tto complete.\n"
|
||||
"\n"
|
||||
"\tzinject -I [-s <seconds> | -g <txgs>] pool\n"
|
||||
"\t\tCause the pool to stop writing blocks yet not\n"
|
||||
"\t\treport errors for a duration. Simulates buggy hardware\n"
|
||||
|
@ -391,8 +397,10 @@ print_data_handler(int id, const char *pool, zinject_record_t *record,
|
|||
{
|
||||
int *count = data;
|
||||
|
||||
if (record->zi_guid != 0 || record->zi_func[0] != '\0')
|
||||
if (record->zi_guid != 0 || record->zi_func[0] != '\0' ||
|
||||
record->zi_duration != 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (*count == 0) {
|
||||
(void) printf("%3s %-15s %-6s %-6s %-8s %3s %-4s "
|
||||
|
@ -425,7 +433,7 @@ print_device_handler(int id, const char *pool, zinject_record_t *record,
|
|||
void *data)
|
||||
{
|
||||
static const char *iotypestr[] = {
|
||||
"null", "read", "write", "free", "claim", "ioctl", "trim", "all",
|
||||
"null", "read", "write", "free", "claim", "flush", "trim", "all",
|
||||
};
|
||||
|
||||
int *count = data;
|
||||
|
@ -506,6 +514,33 @@ print_panic_handler(int id, const char *pool, zinject_record_t *record,
|
|||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
print_pool_delay_handler(int id, const char *pool, zinject_record_t *record,
|
||||
void *data)
|
||||
{
|
||||
int *count = data;
|
||||
|
||||
if (record->zi_cmd != ZINJECT_DELAY_IMPORT &&
|
||||
record->zi_cmd != ZINJECT_DELAY_EXPORT) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (*count == 0) {
|
||||
(void) printf("%3s %-19s %-11s %s\n",
|
||||
"ID", "POOL", "DELAY (sec)", "COMMAND");
|
||||
(void) printf("--- ------------------- -----------"
|
||||
" -------\n");
|
||||
}
|
||||
|
||||
*count += 1;
|
||||
|
||||
(void) printf("%3d %-19s %-11llu %s\n",
|
||||
id, pool, (u_longlong_t)record->zi_duration,
|
||||
record->zi_cmd == ZINJECT_DELAY_IMPORT ? "import": "export");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print all registered error handlers. Returns the number of handlers
|
||||
* registered.
|
||||
|
@ -536,6 +571,13 @@ print_all_handlers(void)
|
|||
count = 0;
|
||||
}
|
||||
|
||||
(void) iter_handlers(print_pool_delay_handler, &count);
|
||||
if (count > 0) {
|
||||
total += count;
|
||||
(void) printf("\n");
|
||||
count = 0;
|
||||
}
|
||||
|
||||
(void) iter_handlers(print_panic_handler, &count);
|
||||
|
||||
return (count + total);
|
||||
|
@ -608,9 +650,27 @@ register_handler(const char *pool, int flags, zinject_record_t *record,
|
|||
zc.zc_guid = flags;
|
||||
|
||||
if (zfs_ioctl(g_zfs, ZFS_IOC_INJECT_FAULT, &zc) != 0) {
|
||||
(void) fprintf(stderr, "failed to add handler: %s\n",
|
||||
errno == EDOM ? "block level exceeds max level of object" :
|
||||
strerror(errno));
|
||||
const char *errmsg = strerror(errno);
|
||||
|
||||
switch (errno) {
|
||||
case EDOM:
|
||||
errmsg = "block level exceeds max level of object";
|
||||
break;
|
||||
case EEXIST:
|
||||
if (record->zi_cmd == ZINJECT_DELAY_IMPORT)
|
||||
errmsg = "pool already imported";
|
||||
if (record->zi_cmd == ZINJECT_DELAY_EXPORT)
|
||||
errmsg = "a handler already exists";
|
||||
break;
|
||||
case ENOENT:
|
||||
/* import delay injector running on older zfs module */
|
||||
if (record->zi_cmd == ZINJECT_DELAY_IMPORT)
|
||||
errmsg = "import delay injector not supported";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
(void) fprintf(stderr, "failed to add handler: %s\n", errmsg);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -635,6 +695,9 @@ register_handler(const char *pool, int flags, zinject_record_t *record,
|
|||
} else if (record->zi_duration < 0) {
|
||||
(void) printf(" txgs: %lld \n",
|
||||
(u_longlong_t)-record->zi_duration);
|
||||
} else if (record->zi_timer > 0) {
|
||||
(void) printf(" timer: %lld ms\n",
|
||||
(u_longlong_t)NSEC2MSEC(record->zi_timer));
|
||||
} else {
|
||||
(void) printf("objset: %llu\n",
|
||||
(u_longlong_t)record->zi_objset);
|
||||
|
@ -833,7 +896,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
|
||||
while ((c = getopt(argc, argv,
|
||||
":aA:b:C:d:D:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:")) != -1) {
|
||||
":aA:b:C:d:D:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:P:")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
flags |= ZINJECT_FLUSH_ARC;
|
||||
|
@ -889,7 +952,7 @@ main(int argc, char **argv)
|
|||
if (error < 0) {
|
||||
(void) fprintf(stderr, "invalid error type "
|
||||
"'%s': must be one of: io decompress "
|
||||
"decrypt nxio dtl corrupt\n",
|
||||
"decrypt nxio dtl corrupt noop\n",
|
||||
optarg);
|
||||
usage();
|
||||
libzfs_fini(g_zfs);
|
||||
|
@ -951,6 +1014,19 @@ main(int argc, char **argv)
|
|||
sizeof (record.zi_func));
|
||||
record.zi_cmd = ZINJECT_PANIC;
|
||||
break;
|
||||
case 'P':
|
||||
if (strcasecmp(optarg, "import") == 0) {
|
||||
record.zi_cmd = ZINJECT_DELAY_IMPORT;
|
||||
} else if (strcasecmp(optarg, "export") == 0) {
|
||||
record.zi_cmd = ZINJECT_DELAY_EXPORT;
|
||||
} else {
|
||||
(void) fprintf(stderr, "invalid command '%s': "
|
||||
"must be 'import' or 'export'\n", optarg);
|
||||
usage();
|
||||
libzfs_fini(g_zfs);
|
||||
return (1);
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
|
@ -978,14 +1054,14 @@ main(int argc, char **argv)
|
|||
io_type = ZIO_TYPE_FREE;
|
||||
} else if (strcasecmp(optarg, "claim") == 0) {
|
||||
io_type = ZIO_TYPE_CLAIM;
|
||||
} else if (strcasecmp(optarg, "ioctl") == 0) {
|
||||
io_type = ZIO_TYPE_IOCTL;
|
||||
} else if (strcasecmp(optarg, "flush") == 0) {
|
||||
io_type = ZIO_TYPE_FLUSH;
|
||||
} else if (strcasecmp(optarg, "all") == 0) {
|
||||
io_type = ZIO_TYPES;
|
||||
} else {
|
||||
(void) fprintf(stderr, "invalid I/O type "
|
||||
"'%s': must be 'read', 'write', 'free', "
|
||||
"'claim', 'ioctl' or 'all'\n", optarg);
|
||||
"'claim', 'flush' or 'all'\n", optarg);
|
||||
usage();
|
||||
libzfs_fini(g_zfs);
|
||||
return (1);
|
||||
|
@ -1032,7 +1108,7 @@ main(int argc, char **argv)
|
|||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (record.zi_duration != 0)
|
||||
if (record.zi_duration != 0 && record.zi_cmd == 0)
|
||||
record.zi_cmd = ZINJECT_IGNORED_WRITES;
|
||||
|
||||
if (cancel != NULL) {
|
||||
|
@ -1178,8 +1254,8 @@ main(int argc, char **argv)
|
|||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
||||
level != 0 || device != NULL || record.zi_freq > 0 ||
|
||||
dvas != 0) {
|
||||
(void) fprintf(stderr, "panic (-p) incompatible with "
|
||||
"other options\n");
|
||||
(void) fprintf(stderr, "%s incompatible with other "
|
||||
"options\n", "import|export delay (-P)");
|
||||
usage();
|
||||
libzfs_fini(g_zfs);
|
||||
return (2);
|
||||
|
@ -1197,6 +1273,28 @@ main(int argc, char **argv)
|
|||
if (argv[1] != NULL)
|
||||
record.zi_type = atoi(argv[1]);
|
||||
dataset[0] = '\0';
|
||||
} else if (record.zi_cmd == ZINJECT_DELAY_IMPORT ||
|
||||
record.zi_cmd == ZINJECT_DELAY_EXPORT) {
|
||||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
||||
level != 0 || device != NULL || record.zi_freq > 0 ||
|
||||
dvas != 0) {
|
||||
(void) fprintf(stderr, "%s incompatible with other "
|
||||
"options\n", "import|export delay (-P)");
|
||||
usage();
|
||||
libzfs_fini(g_zfs);
|
||||
return (2);
|
||||
}
|
||||
|
||||
if (argc != 1 || record.zi_duration <= 0) {
|
||||
(void) fprintf(stderr, "import|export delay (-P) "
|
||||
"injection requires a duration (-s) and a single "
|
||||
"pool name\n");
|
||||
usage();
|
||||
libzfs_fini(g_zfs);
|
||||
return (2);
|
||||
}
|
||||
|
||||
(void) strlcpy(pool, argv[0], sizeof (pool));
|
||||
} else if (record.zi_cmd == ZINJECT_IGNORED_WRITES) {
|
||||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
||||
level != 0 || record.zi_freq > 0 || dvas != 0) {
|
||||
|
|
|
@ -438,7 +438,7 @@ static char *zpool_sysfs_gets(char *path)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
buf = calloc(sizeof (*buf), statbuf.st_size + 1);
|
||||
buf = calloc(statbuf.st_size + 1, sizeof (*buf));
|
||||
if (buf == NULL) {
|
||||
close(fd);
|
||||
return (NULL);
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <thread_pool.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
|
@ -79,6 +80,8 @@
|
|||
|
||||
libzfs_handle_t *g_zfs;
|
||||
|
||||
static int mount_tp_nthr = 512; /* tpool threads for multi-threaded mounting */
|
||||
|
||||
static int zpool_do_create(int, char **);
|
||||
static int zpool_do_destroy(int, char **);
|
||||
|
||||
|
@ -2029,10 +2032,19 @@ zpool_do_destroy(int argc, char **argv)
|
|||
}
|
||||
|
||||
typedef struct export_cbdata {
|
||||
tpool_t *tpool;
|
||||
pthread_mutex_t mnttab_lock;
|
||||
boolean_t force;
|
||||
boolean_t hardforce;
|
||||
int retval;
|
||||
} export_cbdata_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *aea_poolname;
|
||||
export_cbdata_t *aea_cbdata;
|
||||
} async_export_args_t;
|
||||
|
||||
/*
|
||||
* Export one pool
|
||||
*/
|
||||
|
@ -2041,11 +2053,20 @@ zpool_export_one(zpool_handle_t *zhp, void *data)
|
|||
{
|
||||
export_cbdata_t *cb = data;
|
||||
|
||||
if (zpool_disable_datasets(zhp, cb->force) != 0)
|
||||
return (1);
|
||||
/*
|
||||
* zpool_disable_datasets() is not thread-safe for mnttab access.
|
||||
* So we serialize access here for 'zpool export -a' parallel case.
|
||||
*/
|
||||
if (cb->tpool != NULL)
|
||||
pthread_mutex_lock(&cb->mnttab_lock);
|
||||
|
||||
/* The history must be logged as part of the export */
|
||||
log_history = B_FALSE;
|
||||
int retval = zpool_disable_datasets(zhp, cb->force);
|
||||
|
||||
if (cb->tpool != NULL)
|
||||
pthread_mutex_unlock(&cb->mnttab_lock);
|
||||
|
||||
if (retval)
|
||||
return (1);
|
||||
|
||||
if (cb->hardforce) {
|
||||
if (zpool_export_force(zhp, history_str) != 0)
|
||||
|
@ -2057,6 +2078,48 @@ zpool_export_one(zpool_handle_t *zhp, void *data)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Asynchronous export request
|
||||
*/
|
||||
static void
|
||||
zpool_export_task(void *arg)
|
||||
{
|
||||
async_export_args_t *aea = arg;
|
||||
|
||||
zpool_handle_t *zhp = zpool_open(g_zfs, aea->aea_poolname);
|
||||
if (zhp != NULL) {
|
||||
int ret = zpool_export_one(zhp, aea->aea_cbdata);
|
||||
if (ret != 0)
|
||||
aea->aea_cbdata->retval = ret;
|
||||
zpool_close(zhp);
|
||||
} else {
|
||||
aea->aea_cbdata->retval = 1;
|
||||
}
|
||||
|
||||
free(aea->aea_poolname);
|
||||
free(aea);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process an export request in parallel
|
||||
*/
|
||||
static int
|
||||
zpool_export_one_async(zpool_handle_t *zhp, void *data)
|
||||
{
|
||||
tpool_t *tpool = ((export_cbdata_t *)data)->tpool;
|
||||
async_export_args_t *aea = safe_malloc(sizeof (async_export_args_t));
|
||||
|
||||
/* save pool name since zhp will go out of scope */
|
||||
aea->aea_poolname = strdup(zpool_get_name(zhp));
|
||||
aea->aea_cbdata = data;
|
||||
|
||||
/* ship off actual export to another thread */
|
||||
if (tpool_dispatch(tpool, zpool_export_task, (void *)aea) != 0)
|
||||
return (errno); /* unlikely */
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* zpool export [-f] <pool> ...
|
||||
*
|
||||
|
@ -2097,17 +2160,33 @@ zpool_do_export(int argc, char **argv)
|
|||
|
||||
cb.force = force;
|
||||
cb.hardforce = hardforce;
|
||||
cb.tpool = NULL;
|
||||
cb.retval = 0;
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* The history will be logged as part of the export itself */
|
||||
log_history = B_FALSE;
|
||||
|
||||
if (do_all) {
|
||||
if (argc != 0) {
|
||||
(void) fprintf(stderr, gettext("too many arguments\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
return (for_each_pool(argc, argv, B_TRUE, NULL,
|
||||
ZFS_TYPE_POOL, B_FALSE, zpool_export_one, &cb));
|
||||
cb.tpool = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN),
|
||||
0, NULL);
|
||||
pthread_mutex_init(&cb.mnttab_lock, NULL);
|
||||
|
||||
/* Asynchronously call zpool_export_one using thread pool */
|
||||
ret = for_each_pool(argc, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
|
||||
B_FALSE, zpool_export_one_async, &cb);
|
||||
|
||||
tpool_wait(cb.tpool);
|
||||
tpool_destroy(cb.tpool);
|
||||
(void) pthread_mutex_destroy(&cb.mnttab_lock);
|
||||
|
||||
return (ret | cb.retval);
|
||||
}
|
||||
|
||||
/* check arguments */
|
||||
|
@ -2937,6 +3016,7 @@ show_import(nvlist_t *config, boolean_t report_error)
|
|||
const char *health;
|
||||
uint_t vsc;
|
||||
const char *comment;
|
||||
const char *indent;
|
||||
status_cbdata_t cb = { 0 };
|
||||
|
||||
verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
|
||||
|
@ -2961,82 +3041,84 @@ show_import(nvlist_t *config, boolean_t report_error)
|
|||
if (reason != ZPOOL_STATUS_OK && !report_error)
|
||||
return (reason);
|
||||
|
||||
(void) printf(gettext(" pool: %s\n"), name);
|
||||
(void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
|
||||
(void) printf(gettext(" state: %s"), health);
|
||||
if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0) {
|
||||
indent = " ";
|
||||
} else {
|
||||
comment = NULL;
|
||||
indent = "";
|
||||
}
|
||||
|
||||
(void) printf(gettext("%s pool: %s\n"), indent, name);
|
||||
(void) printf(gettext("%s id: %llu\n"), indent, (u_longlong_t)guid);
|
||||
(void) printf(gettext("%s state: %s"), indent, health);
|
||||
if (pool_state == POOL_STATE_DESTROYED)
|
||||
(void) printf(gettext(" (DESTROYED)"));
|
||||
(void) printf("\n");
|
||||
|
||||
if (reason != ZPOOL_STATUS_OK) {
|
||||
(void) printf("%s", indent);
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
}
|
||||
switch (reason) {
|
||||
case ZPOOL_STATUS_MISSING_DEV_R:
|
||||
case ZPOOL_STATUS_MISSING_DEV_NR:
|
||||
case ZPOOL_STATUS_BAD_GUID_SUM:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("One or more devices are "
|
||||
"missing from the system.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_CORRUPT_LABEL_R:
|
||||
case ZPOOL_STATUS_CORRUPT_LABEL_NR:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("One or more devices contains"
|
||||
" corrupted data.\n"));
|
||||
printf_color(ANSI_YELLOW, gettext("One or more devices "
|
||||
"contains corrupted data.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_CORRUPT_DATA:
|
||||
(void) printf(
|
||||
gettext(" status: The pool data is corrupted.\n"));
|
||||
printf_color(ANSI_YELLOW, gettext("The pool data is "
|
||||
"corrupted.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_OFFLINE_DEV:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("One or more devices "
|
||||
"are offlined.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_CORRUPT_POOL:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("The pool metadata is "
|
||||
"corrupted.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_VERSION_OLDER:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("The pool is formatted using "
|
||||
"a legacy on-disk version.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_VERSION_NEWER:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("The pool is formatted using "
|
||||
"an incompatible version.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_FEAT_DISABLED:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("Some supported "
|
||||
"features are not enabled on the pool.\n\t"
|
||||
"(Note that they may be intentionally disabled "
|
||||
"if the\n\t'compatibility' property is set.)\n"));
|
||||
"features are not enabled on the pool.\n"
|
||||
"\t%s(Note that they may be intentionally disabled if the\n"
|
||||
"\t%s'compatibility' property is set.)\n"), indent, indent);
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_COMPATIBILITY_ERR:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("Error reading or parsing "
|
||||
"the file(s) indicated by the 'compatibility'\n"
|
||||
"property.\n"));
|
||||
"\t%sproperty.\n"), indent);
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_INCOMPATIBLE_FEAT:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("One or more features "
|
||||
"are enabled on the pool despite not being\n"
|
||||
"requested by the 'compatibility' property.\n"));
|
||||
"\t%srequested by the 'compatibility' property.\n"),
|
||||
indent);
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_UNSUP_FEAT_READ:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("The pool uses the following "
|
||||
"feature(s) not supported on this system:\n"));
|
||||
color_start(ANSI_YELLOW);
|
||||
|
@ -3045,66 +3127,60 @@ show_import(nvlist_t *config, boolean_t report_error)
|
|||
break;
|
||||
|
||||
case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("The pool can only be "
|
||||
"accessed in read-only mode on this system. It\n\tcannot be"
|
||||
" accessed in read-write mode because it uses the "
|
||||
"following\n\tfeature(s) not supported on this system:\n"));
|
||||
"accessed in read-only mode on this system. It\n"
|
||||
"\t%scannot be accessed in read-write mode because it uses "
|
||||
"the following\n"
|
||||
"\t%sfeature(s) not supported on this system:\n"),
|
||||
indent, indent);
|
||||
color_start(ANSI_YELLOW);
|
||||
zpool_print_unsup_feat(config);
|
||||
color_end();
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_HOSTID_ACTIVE:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("The pool is currently "
|
||||
"imported by another system.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_HOSTID_REQUIRED:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("The pool has the "
|
||||
"multihost property on. It cannot\n\tbe safely imported "
|
||||
"when the system hostid is not set.\n"));
|
||||
"multihost property on. It cannot\n"
|
||||
"\t%sbe safely imported when the system hostid is not "
|
||||
"set.\n"), indent);
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_HOSTID_MISMATCH:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("The pool was last accessed "
|
||||
"by another system.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_FAULTED_DEV_R:
|
||||
case ZPOOL_STATUS_FAULTED_DEV_NR:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("One or more devices are "
|
||||
"faulted.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_BAD_LOG:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("An intent log record cannot "
|
||||
"be read.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_RESILVERING:
|
||||
case ZPOOL_STATUS_REBUILDING:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("One or more devices were "
|
||||
"being resilvered.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_ERRATA:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("Errata #%d detected.\n"),
|
||||
errata);
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_NON_NATIVE_ASHIFT:
|
||||
printf_color(ANSI_BOLD, gettext("status: "));
|
||||
printf_color(ANSI_YELLOW, gettext("One or more devices are "
|
||||
"configured to use a non-native block size.\n"
|
||||
"\tExpect reduced performance.\n"));
|
||||
"\t%sExpect reduced performance.\n"), indent);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -3117,114 +3193,121 @@ show_import(nvlist_t *config, boolean_t report_error)
|
|||
/*
|
||||
* Print out an action according to the overall state of the pool.
|
||||
*/
|
||||
if (vs->vs_state != VDEV_STATE_HEALTHY ||
|
||||
reason != ZPOOL_STATUS_ERRATA || errata != ZPOOL_ERRATA_NONE) {
|
||||
(void) printf("%s", indent);
|
||||
(void) printf(gettext("action: "));
|
||||
}
|
||||
if (vs->vs_state == VDEV_STATE_HEALTHY) {
|
||||
if (reason == ZPOOL_STATUS_VERSION_OLDER ||
|
||||
reason == ZPOOL_STATUS_FEAT_DISABLED) {
|
||||
(void) printf(gettext(" action: The pool can be "
|
||||
"imported using its name or numeric identifier, "
|
||||
"though\n\tsome features will not be available "
|
||||
"without an explicit 'zpool upgrade'.\n"));
|
||||
(void) printf(gettext("The pool can be imported using "
|
||||
"its name or numeric identifier, though\n"
|
||||
"\t%ssome features will not be available without "
|
||||
"an explicit 'zpool upgrade'.\n"), indent);
|
||||
} else if (reason == ZPOOL_STATUS_COMPATIBILITY_ERR) {
|
||||
(void) printf(gettext(" action: The pool can be "
|
||||
"imported using its name or numeric\n\tidentifier, "
|
||||
"though the file(s) indicated by its "
|
||||
"'compatibility'\n\tproperty cannot be parsed at "
|
||||
"this time.\n"));
|
||||
(void) printf(gettext("The pool can be imported using "
|
||||
"its name or numeric\n"
|
||||
"\t%sidentifier, though the file(s) indicated by "
|
||||
"its 'compatibility'\n"
|
||||
"\t%sproperty cannot be parsed at this time.\n"),
|
||||
indent, indent);
|
||||
} else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) {
|
||||
(void) printf(gettext(" action: The pool can be "
|
||||
"imported using its name or numeric "
|
||||
"identifier and\n\tthe '-f' flag.\n"));
|
||||
(void) printf(gettext("The pool can be imported using "
|
||||
"its name or numeric identifier and\n"
|
||||
"\t%sthe '-f' flag.\n"), indent);
|
||||
} else if (reason == ZPOOL_STATUS_ERRATA) {
|
||||
switch (errata) {
|
||||
case ZPOOL_ERRATA_NONE:
|
||||
break;
|
||||
|
||||
case ZPOOL_ERRATA_ZOL_2094_SCRUB:
|
||||
(void) printf(gettext(" action: The pool can "
|
||||
"be imported using its name or numeric "
|
||||
"identifier,\n\thowever there is a compat"
|
||||
"ibility issue which should be corrected"
|
||||
"\n\tby running 'zpool scrub'\n"));
|
||||
(void) printf(gettext("The pool can be "
|
||||
"imported using its name or numeric "
|
||||
"identifier,\n"
|
||||
"\t%showever there is a compatibility "
|
||||
"issue which should be corrected\n"
|
||||
"\t%sby running 'zpool scrub'\n"),
|
||||
indent, indent);
|
||||
break;
|
||||
|
||||
case ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY:
|
||||
(void) printf(gettext(" action: The pool can"
|
||||
"not be imported with this version of ZFS "
|
||||
"due to\n\tan active asynchronous destroy. "
|
||||
"Revert to an earlier version\n\tand "
|
||||
"allow the destroy to complete before "
|
||||
"updating.\n"));
|
||||
(void) printf(gettext("The pool cannot be "
|
||||
"imported with this version of ZFS due to\n"
|
||||
"\t%san active asynchronous destroy. "
|
||||
"Revert to an earlier version\n"
|
||||
"\t%sand allow the destroy to complete "
|
||||
"before updating.\n"), indent, indent);
|
||||
break;
|
||||
|
||||
case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION:
|
||||
(void) printf(gettext(" action: Existing "
|
||||
"encrypted datasets contain an on-disk "
|
||||
"incompatibility, which\n\tneeds to be "
|
||||
"corrected. Backup these datasets to new "
|
||||
"encrypted datasets\n\tand destroy the "
|
||||
"old ones.\n"));
|
||||
(void) printf(gettext("Existing encrypted "
|
||||
"datasets contain an on-disk "
|
||||
"incompatibility, which\n"
|
||||
"\t%sneeds to be corrected. Backup these "
|
||||
"datasets to new encrypted datasets\n"
|
||||
"\t%sand destroy the old ones.\n"),
|
||||
indent, indent);
|
||||
break;
|
||||
|
||||
case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION:
|
||||
(void) printf(gettext(" action: Existing "
|
||||
"encrypted snapshots and bookmarks contain "
|
||||
"an on-disk\n\tincompatibility. This may "
|
||||
"cause on-disk corruption if they are used"
|
||||
"\n\twith 'zfs recv'. To correct the "
|
||||
"issue, enable the bookmark_v2 feature.\n\t"
|
||||
"No additional action is needed if there "
|
||||
"are no encrypted snapshots or\n\t"
|
||||
"bookmarks. If preserving the encrypted "
|
||||
"snapshots and bookmarks is\n\trequired, "
|
||||
"use a non-raw send to backup and restore "
|
||||
"them. Alternately,\n\tthey may be removed"
|
||||
" to resolve the incompatibility.\n"));
|
||||
(void) printf(gettext("Existing encrypted "
|
||||
"snapshots and bookmarks contain an "
|
||||
"on-disk\n"
|
||||
"\t%sincompatibility. This may cause "
|
||||
"on-disk corruption if they are used\n"
|
||||
"\t%swith 'zfs recv'. To correct the "
|
||||
"issue, enable the bookmark_v2 feature.\n"
|
||||
"\t%sNo additional action is needed if "
|
||||
"there are no encrypted snapshots or\n"
|
||||
"\t%sbookmarks. If preserving the "
|
||||
"encrypted snapshots and bookmarks is\n"
|
||||
"\t%srequired, use a non-raw send to "
|
||||
"backup and restore them. Alternately,\n"
|
||||
"\t%sthey may be removed to resolve the "
|
||||
"incompatibility.\n"), indent, indent,
|
||||
indent, indent, indent, indent);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* All errata must contain an action message.
|
||||
*/
|
||||
assert(0);
|
||||
assert(errata == ZPOOL_ERRATA_NONE);
|
||||
}
|
||||
} else {
|
||||
(void) printf(gettext(" action: The pool can be "
|
||||
"imported using its name or numeric "
|
||||
"identifier.\n"));
|
||||
(void) printf(gettext("The pool can be imported using "
|
||||
"its name or numeric identifier.\n"));
|
||||
}
|
||||
} else if (vs->vs_state == VDEV_STATE_DEGRADED) {
|
||||
(void) printf(gettext(" action: The pool can be imported "
|
||||
"despite missing or damaged devices. The\n\tfault "
|
||||
"tolerance of the pool may be compromised if imported.\n"));
|
||||
(void) printf(gettext("The pool can be imported despite "
|
||||
"missing or damaged devices. The\n"
|
||||
"\t%sfault tolerance of the pool may be compromised if "
|
||||
"imported.\n"), indent);
|
||||
} else {
|
||||
switch (reason) {
|
||||
case ZPOOL_STATUS_VERSION_NEWER:
|
||||
(void) printf(gettext(" action: The pool cannot be "
|
||||
"imported. Access the pool on a system running "
|
||||
"newer\n\tsoftware, or recreate the pool from "
|
||||
"backup.\n"));
|
||||
(void) printf(gettext("The pool cannot be imported. "
|
||||
"Access the pool on a system running newer\n"
|
||||
"\t%ssoftware, or recreate the pool from "
|
||||
"backup.\n"), indent);
|
||||
break;
|
||||
case ZPOOL_STATUS_UNSUP_FEAT_READ:
|
||||
printf_color(ANSI_BOLD, gettext("action: "));
|
||||
printf_color(ANSI_YELLOW, gettext("The pool cannot be "
|
||||
"imported. Access the pool on a system that "
|
||||
"supports\n\tthe required feature(s), or recreate "
|
||||
"the pool from backup.\n"));
|
||||
(void) printf(gettext("The pool cannot be imported. "
|
||||
"Access the pool on a system that supports\n"
|
||||
"\t%sthe required feature(s), or recreate the pool "
|
||||
"from backup.\n"), indent);
|
||||
break;
|
||||
case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
|
||||
printf_color(ANSI_BOLD, gettext("action: "));
|
||||
printf_color(ANSI_YELLOW, gettext("The pool cannot be "
|
||||
"imported in read-write mode. Import the pool "
|
||||
"with\n"
|
||||
"\t\"-o readonly=on\", access the pool on a system "
|
||||
"that supports the\n\trequired feature(s), or "
|
||||
"recreate the pool from backup.\n"));
|
||||
(void) printf(gettext("The pool cannot be imported in "
|
||||
"read-write mode. Import the pool with\n"
|
||||
"\t%s'-o readonly=on', access the pool on a system "
|
||||
"that supports the\n"
|
||||
"\t%srequired feature(s), or recreate the pool "
|
||||
"from backup.\n"), indent, indent);
|
||||
break;
|
||||
case ZPOOL_STATUS_MISSING_DEV_R:
|
||||
case ZPOOL_STATUS_MISSING_DEV_NR:
|
||||
case ZPOOL_STATUS_BAD_GUID_SUM:
|
||||
(void) printf(gettext(" action: The pool cannot be "
|
||||
"imported. Attach the missing\n\tdevices and try "
|
||||
"again.\n"));
|
||||
(void) printf(gettext("The pool cannot be imported. "
|
||||
"Attach the missing\n"
|
||||
"\t%sdevices and try again.\n"), indent);
|
||||
break;
|
||||
case ZPOOL_STATUS_HOSTID_ACTIVE:
|
||||
VERIFY0(nvlist_lookup_nvlist(config,
|
||||
|
@ -3238,47 +3321,49 @@ show_import(nvlist_t *config, boolean_t report_error)
|
|||
hostid = fnvlist_lookup_uint64(nvinfo,
|
||||
ZPOOL_CONFIG_MMP_HOSTID);
|
||||
|
||||
(void) printf(gettext(" action: The pool must be "
|
||||
"exported from %s (hostid=%"PRIx64")\n\tbefore it "
|
||||
"can be safely imported.\n"), hostname, hostid);
|
||||
(void) printf(gettext("The pool must be exported from "
|
||||
"%s (hostid=%"PRIx64")\n"
|
||||
"\t%sbefore it can be safely imported.\n"),
|
||||
hostname, hostid, indent);
|
||||
break;
|
||||
case ZPOOL_STATUS_HOSTID_REQUIRED:
|
||||
(void) printf(gettext(" action: Set a unique system "
|
||||
"hostid with the zgenhostid(8) command.\n"));
|
||||
(void) printf(gettext("Set a unique system hostid with "
|
||||
"the zgenhostid(8) command.\n"));
|
||||
break;
|
||||
default:
|
||||
(void) printf(gettext(" action: The pool cannot be "
|
||||
"imported due to damaged devices or data.\n"));
|
||||
(void) printf(gettext("The pool cannot be imported due "
|
||||
"to damaged devices or data.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the comment attached to the pool. */
|
||||
if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
|
||||
if (comment != NULL)
|
||||
(void) printf(gettext("comment: %s\n"), comment);
|
||||
|
||||
/*
|
||||
* If the state is "closed" or "can't open", and the aux state
|
||||
* is "corrupt data":
|
||||
*/
|
||||
if (((vs->vs_state == VDEV_STATE_CLOSED) ||
|
||||
(vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
|
||||
(vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
|
||||
if ((vs->vs_state == VDEV_STATE_CLOSED ||
|
||||
vs->vs_state == VDEV_STATE_CANT_OPEN) &&
|
||||
vs->vs_aux == VDEV_AUX_CORRUPT_DATA) {
|
||||
if (pool_state == POOL_STATE_DESTROYED)
|
||||
(void) printf(gettext("\tThe pool was destroyed, "
|
||||
"but can be imported using the '-Df' flags.\n"));
|
||||
(void) printf(gettext("\t%sThe pool was destroyed, "
|
||||
"but can be imported using the '-Df' flags.\n"),
|
||||
indent);
|
||||
else if (pool_state != POOL_STATE_EXPORTED)
|
||||
(void) printf(gettext("\tThe pool may be active on "
|
||||
"another system, but can be imported using\n\t"
|
||||
"the '-f' flag.\n"));
|
||||
(void) printf(gettext("\t%sThe pool may be active on "
|
||||
"another system, but can be imported using\n"
|
||||
"\t%sthe '-f' flag.\n"), indent, indent);
|
||||
}
|
||||
|
||||
if (msgid != NULL) {
|
||||
(void) printf(gettext(
|
||||
" see: https://openzfs.github.io/openzfs-docs/msg/%s\n"),
|
||||
msgid);
|
||||
(void) printf(gettext("%s see: "
|
||||
"https://openzfs.github.io/openzfs-docs/msg/%s\n"),
|
||||
indent, msgid);
|
||||
}
|
||||
|
||||
(void) printf(gettext(" config:\n\n"));
|
||||
(void) printf(gettext("%sconfig:\n\n"), indent);
|
||||
|
||||
cb.cb_namewidth = max_width(NULL, nvroot, 0, strlen(name),
|
||||
VDEV_NAME_TYPE_ID);
|
||||
|
@ -3292,9 +3377,10 @@ show_import(nvlist_t *config, boolean_t report_error)
|
|||
print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_CLASS_LOGS);
|
||||
|
||||
if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
|
||||
(void) printf(gettext("\n\tAdditional devices are known to "
|
||||
"be part of this pool, though their\n\texact "
|
||||
"configuration cannot be determined.\n"));
|
||||
(void) printf(gettext("\n\t%sAdditional devices are known to "
|
||||
"be part of this pool, though their\n"
|
||||
"\t%sexact configuration cannot be determined.\n"),
|
||||
indent, indent);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -3341,7 +3427,7 @@ zfs_force_import_required(nvlist_t *config)
|
|||
*/
|
||||
static int
|
||||
do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
||||
nvlist_t *props, int flags)
|
||||
nvlist_t *props, int flags, uint_t mntthreads)
|
||||
{
|
||||
int ret = 0;
|
||||
int ms_status = 0;
|
||||
|
@ -3441,13 +3527,13 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
|||
|
||||
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
|
||||
!(flags & ZFS_IMPORT_ONLY)) {
|
||||
ms_status = zpool_enable_datasets(zhp, mntopts, 0);
|
||||
ms_status = zpool_enable_datasets(zhp, mntopts, 0, mntthreads);
|
||||
if (ms_status == EZFS_SHAREFAILED) {
|
||||
(void) fprintf(stderr, gettext("Import was "
|
||||
"successful, but unable to share some datasets"));
|
||||
"successful, but unable to share some datasets\n"));
|
||||
} else if (ms_status == EZFS_MOUNTFAILED) {
|
||||
(void) fprintf(stderr, gettext("Import was "
|
||||
"successful, but unable to mount some datasets"));
|
||||
"successful, but unable to mount some datasets\n"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3455,15 +3541,42 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
|||
return (ret);
|
||||
}
|
||||
|
||||
typedef struct import_parameters {
|
||||
nvlist_t *ip_config;
|
||||
const char *ip_mntopts;
|
||||
nvlist_t *ip_props;
|
||||
int ip_flags;
|
||||
uint_t ip_mntthreads;
|
||||
int *ip_err;
|
||||
} import_parameters_t;
|
||||
|
||||
static void
|
||||
do_import_task(void *arg)
|
||||
{
|
||||
import_parameters_t *ip = arg;
|
||||
*ip->ip_err |= do_import(ip->ip_config, NULL, ip->ip_mntopts,
|
||||
ip->ip_props, ip->ip_flags, ip->ip_mntthreads);
|
||||
free(ip);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
|
||||
char *orig_name, char *new_name,
|
||||
boolean_t do_destroyed, boolean_t pool_specified, boolean_t do_all,
|
||||
importargs_t *import)
|
||||
char *orig_name, char *new_name, importargs_t *import)
|
||||
{
|
||||
nvlist_t *config = NULL;
|
||||
nvlist_t *found_config = NULL;
|
||||
uint64_t pool_state;
|
||||
boolean_t pool_specified = (import->poolname != NULL ||
|
||||
import->guid != 0);
|
||||
uint_t npools = 0;
|
||||
|
||||
|
||||
tpool_t *tp = NULL;
|
||||
if (import->do_all) {
|
||||
tp = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN),
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point we have a list of import candidate configs. Even if
|
||||
|
@ -3474,15 +3587,21 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
|
|||
int err = 0;
|
||||
nvpair_t *elem = NULL;
|
||||
boolean_t first = B_TRUE;
|
||||
if (!pool_specified && import->do_all) {
|
||||
while ((elem = nvlist_next_nvpair(pools, elem)) != NULL)
|
||||
npools++;
|
||||
}
|
||||
while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
|
||||
|
||||
verify(nvpair_value_nvlist(elem, &config) == 0);
|
||||
|
||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
|
||||
&pool_state) == 0);
|
||||
if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
|
||||
if (!import->do_destroyed &&
|
||||
pool_state == POOL_STATE_DESTROYED)
|
||||
continue;
|
||||
if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
|
||||
if (import->do_destroyed &&
|
||||
pool_state != POOL_STATE_DESTROYED)
|
||||
continue;
|
||||
|
||||
verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY,
|
||||
|
@ -3491,12 +3610,22 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
|
|||
if (!pool_specified) {
|
||||
if (first)
|
||||
first = B_FALSE;
|
||||
else if (!do_all)
|
||||
else if (!import->do_all)
|
||||
(void) fputc('\n', stdout);
|
||||
|
||||
if (do_all) {
|
||||
err |= do_import(config, NULL, mntopts,
|
||||
props, flags);
|
||||
if (import->do_all) {
|
||||
import_parameters_t *ip = safe_malloc(
|
||||
sizeof (import_parameters_t));
|
||||
|
||||
ip->ip_config = config;
|
||||
ip->ip_mntopts = mntopts;
|
||||
ip->ip_props = props;
|
||||
ip->ip_flags = flags;
|
||||
ip->ip_mntthreads = mount_tp_nthr / npools;
|
||||
ip->ip_err = &err;
|
||||
|
||||
(void) tpool_dispatch(tp, do_import_task,
|
||||
(void *)ip);
|
||||
} else {
|
||||
/*
|
||||
* If we're importing from cachefile, then
|
||||
|
@ -3544,6 +3673,10 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
|
|||
found_config = config;
|
||||
}
|
||||
}
|
||||
if (import->do_all) {
|
||||
tpool_wait(tp);
|
||||
tpool_destroy(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we were searching for a specific pool, verify that we found a
|
||||
|
@ -3556,7 +3689,7 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
|
|||
err = B_TRUE;
|
||||
} else {
|
||||
err |= do_import(found_config, new_name,
|
||||
mntopts, props, flags);
|
||||
mntopts, props, flags, mount_tp_nthr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3773,7 +3906,6 @@ zpool_do_import(int argc, char **argv)
|
|||
boolean_t xtreme_rewind = B_FALSE;
|
||||
boolean_t do_scan = B_FALSE;
|
||||
boolean_t pool_exists = B_FALSE;
|
||||
boolean_t pool_specified = B_FALSE;
|
||||
uint64_t txg = -1ULL;
|
||||
char *cachefile = NULL;
|
||||
importargs_t idata = { 0 };
|
||||
|
@ -3972,7 +4104,6 @@ zpool_do_import(int argc, char **argv)
|
|||
searchname = argv[0];
|
||||
searchguid = 0;
|
||||
}
|
||||
pool_specified = B_TRUE;
|
||||
|
||||
/*
|
||||
* User specified a name or guid. Ensure it's unique.
|
||||
|
@ -4005,6 +4136,8 @@ zpool_do_import(int argc, char **argv)
|
|||
idata.cachefile = cachefile;
|
||||
idata.scan = do_scan;
|
||||
idata.policy = policy;
|
||||
idata.do_destroyed = do_destroyed;
|
||||
idata.do_all = do_all;
|
||||
|
||||
libpc_handle_t lpch = {
|
||||
.lpc_lib_handle = g_zfs,
|
||||
|
@ -4047,9 +4180,7 @@ zpool_do_import(int argc, char **argv)
|
|||
}
|
||||
|
||||
err = import_pools(pools, props, mntopts, flags,
|
||||
argc >= 1 ? argv[0] : NULL,
|
||||
argc >= 2 ? argv[1] : NULL,
|
||||
do_destroyed, pool_specified, do_all, &idata);
|
||||
argc >= 1 ? argv[0] : NULL, argc >= 2 ? argv[1] : NULL, &idata);
|
||||
|
||||
/*
|
||||
* If we're using the cachefile and we failed to import, then
|
||||
|
@ -4070,9 +4201,8 @@ zpool_do_import(int argc, char **argv)
|
|||
pools = zpool_search_import(&lpch, &idata);
|
||||
|
||||
err = import_pools(pools, props, mntopts, flags,
|
||||
argc >= 1 ? argv[0] : NULL,
|
||||
argc >= 2 ? argv[1] : NULL,
|
||||
do_destroyed, pool_specified, do_all, &idata);
|
||||
argc >= 1 ? argv[0] : NULL, argc >= 2 ? argv[1] : NULL,
|
||||
&idata);
|
||||
}
|
||||
|
||||
error:
|
||||
|
@ -7103,7 +7233,8 @@ zpool_do_split(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) {
|
||||
ms_status = zpool_enable_datasets(zhp, mntopts, 0);
|
||||
ms_status = zpool_enable_datasets(zhp, mntopts, 0,
|
||||
mount_tp_nthr);
|
||||
if (ms_status == EZFS_SHAREFAILED) {
|
||||
(void) fprintf(stderr, gettext("Split was successful, "
|
||||
"datasets are mounted but sharing of some datasets "
|
||||
|
@ -9012,7 +9143,7 @@ status_callback(zpool_handle_t *zhp, void *data)
|
|||
printf_color(ANSI_BOLD, gettext("action: "));
|
||||
printf_color(ANSI_YELLOW, gettext("Make sure the pool's devices"
|
||||
" are connected, then reboot your system and\n\timport the "
|
||||
"pool.\n"));
|
||||
"pool or run 'zpool clear' to resume the pool.\n"));
|
||||
break;
|
||||
|
||||
case ZPOOL_STATUS_IO_FAILURE_WAIT:
|
||||
|
|
|
@ -77,7 +77,7 @@ zstream_do_recompress(int argc, char *argv[])
|
|||
while ((c = getopt(argc, argv, "l:")) != -1) {
|
||||
switch (c) {
|
||||
case 'l':
|
||||
if (sscanf(optarg, "%d", &level) != 0) {
|
||||
if (sscanf(optarg, "%d", &level) != 1) {
|
||||
fprintf(stderr,
|
||||
"failed to parse level '%s'\n",
|
||||
optarg);
|
||||
|
|
|
@ -186,7 +186,7 @@ static void
|
|||
zfs_redup_stream(int infd, int outfd, boolean_t verbose)
|
||||
{
|
||||
int bufsz = SPA_MAXBLOCKSIZE;
|
||||
dmu_replay_record_t thedrr = { 0 };
|
||||
dmu_replay_record_t thedrr;
|
||||
dmu_replay_record_t *drr = &thedrr;
|
||||
redup_table_t rdt;
|
||||
zio_cksum_t stream_cksum;
|
||||
|
@ -194,6 +194,8 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
|
|||
uint64_t num_records = 0;
|
||||
uint64_t num_write_byref_records = 0;
|
||||
|
||||
memset(&thedrr, 0, sizeof (dmu_replay_record_t));
|
||||
|
||||
#ifdef _ILP32
|
||||
uint64_t max_rde_size = SMALLEST_POSSIBLE_MAX_RDT_MB << 20;
|
||||
#else
|
||||
|
|
34
cmd/ztest.c
34
cmd/ztest.c
|
@ -136,9 +136,7 @@
|
|||
#include <libzutil.h>
|
||||
#include <sys/crypto/icp.h>
|
||||
#include <sys/zfs_impl.h>
|
||||
#if (__GLIBC__ && !__UCLIBC__)
|
||||
#include <execinfo.h> /* for backtrace() */
|
||||
#endif
|
||||
#include <sys/backtrace.h>
|
||||
|
||||
static int ztest_fd_data = -1;
|
||||
static int ztest_fd_rand = -1;
|
||||
|
@ -617,22 +615,15 @@ dump_debug_buffer(void)
|
|||
* We use write() instead of printf() so that this function
|
||||
* is safe to call from a signal handler.
|
||||
*/
|
||||
ret = write(STDOUT_FILENO, "\n", 1);
|
||||
zfs_dbgmsg_print("ztest");
|
||||
ret = write(STDERR_FILENO, "\n", 1);
|
||||
zfs_dbgmsg_print(STDERR_FILENO, "ztest");
|
||||
}
|
||||
|
||||
#define BACKTRACE_SZ 100
|
||||
|
||||
static void sig_handler(int signo)
|
||||
{
|
||||
struct sigaction action;
|
||||
#if (__GLIBC__ && !__UCLIBC__) /* backtrace() is a GNU extension */
|
||||
int nptrs;
|
||||
void *buffer[BACKTRACE_SZ];
|
||||
|
||||
nptrs = backtrace(buffer, BACKTRACE_SZ);
|
||||
backtrace_symbols_fd(buffer, nptrs, STDERR_FILENO);
|
||||
#endif
|
||||
libspl_backtrace(STDERR_FILENO);
|
||||
dump_debug_buffer();
|
||||
|
||||
/*
|
||||
|
@ -2529,7 +2520,7 @@ ztest_get_data(void *arg, uint64_t arg2, lr_write_t *lr, char *buf,
|
|||
ASSERT3P(zio, !=, NULL);
|
||||
size = doi.doi_data_block_size;
|
||||
if (ISP2(size)) {
|
||||
offset = P2ALIGN(offset, size);
|
||||
offset = P2ALIGN_TYPED(offset, size, uint64_t);
|
||||
} else {
|
||||
ASSERT3U(offset, <, size);
|
||||
offset = 0;
|
||||
|
@ -3978,7 +3969,8 @@ raidz_scratch_verify(void)
|
|||
raidvd = vdev_lookup_top(spa, vre->vre_vdev_id);
|
||||
offset = RRSS_GET_OFFSET(&spa->spa_uberblock);
|
||||
state = RRSS_GET_STATE(&spa->spa_uberblock);
|
||||
write_size = P2ALIGN(VDEV_BOOT_SIZE, 1 << raidvd->vdev_ashift);
|
||||
write_size = P2ALIGN_TYPED(VDEV_BOOT_SIZE, 1 << raidvd->vdev_ashift,
|
||||
uint64_t);
|
||||
logical_size = write_size * raidvd->vdev_children;
|
||||
|
||||
switch (state) {
|
||||
|
@ -5016,7 +5008,8 @@ ztest_dmu_object_next_chunk(ztest_ds_t *zd, uint64_t id)
|
|||
*/
|
||||
mutex_enter(&os->os_obj_lock);
|
||||
object = ztest_random(os->os_obj_next_chunk);
|
||||
os->os_obj_next_chunk = P2ALIGN(object, dnodes_per_chunk);
|
||||
os->os_obj_next_chunk = P2ALIGN_TYPED(object, dnodes_per_chunk,
|
||||
uint64_t);
|
||||
mutex_exit(&os->os_obj_lock);
|
||||
}
|
||||
|
||||
|
@ -6638,7 +6631,8 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
|
|||
* the end of the disk (vdev_psize) is aligned to
|
||||
* sizeof (vdev_label_t).
|
||||
*/
|
||||
uint64_t psize = P2ALIGN(fsize, sizeof (vdev_label_t));
|
||||
uint64_t psize = P2ALIGN_TYPED(fsize, sizeof (vdev_label_t),
|
||||
uint64_t);
|
||||
if ((leaf & 1) == 1 &&
|
||||
offset + sizeof (bad) > psize - VDEV_LABEL_END_SIZE)
|
||||
continue;
|
||||
|
@ -6962,8 +6956,8 @@ ztest_fletcher_incr(ztest_ds_t *zd, uint64_t id)
|
|||
size_t inc = 64 * ztest_random(size / 67);
|
||||
/* sometimes add few bytes to test non-simd */
|
||||
if (ztest_random(100) < 10)
|
||||
inc += P2ALIGN(ztest_random(64),
|
||||
sizeof (uint32_t));
|
||||
inc += P2ALIGN_TYPED(ztest_random(64),
|
||||
sizeof (uint32_t), uint64_t);
|
||||
|
||||
if (inc > (size - pos))
|
||||
inc = size - pos;
|
||||
|
@ -8045,7 +8039,7 @@ ztest_raidz_expand_run(ztest_shared_t *zs, spa_t *spa)
|
|||
ztest_expand_io_t *thread_args;
|
||||
|
||||
ASSERT3U(ztest_opts.zo_raidz_expand_test, !=, RAIDZ_EXPAND_NONE);
|
||||
ASSERT3U(rzvd->vdev_ops, ==, &vdev_raidz_ops);
|
||||
ASSERT3P(rzvd->vdev_ops, ==, &vdev_raidz_ops);
|
||||
ztest_opts.zo_raidz_expand_test = RAIDZ_EXPAND_STARTED;
|
||||
|
||||
/* Setup a 1 MiB buffer of random data */
|
||||
|
|
|
@ -44,4 +44,4 @@ SUBSTFILES =
|
|||
CLEANFILES += $(SUBSTFILES)
|
||||
dist_noinst_DATA += $(SUBSTFILES:=.in)
|
||||
|
||||
$(call SUBST,%,)
|
||||
$(SUBSTFILES): $(call SUBST,%,)
|
||||
|
|
|
@ -80,10 +80,11 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
|||
[AC_MSG_ERROR("Python $PYTHON_VERSION unknown")]
|
||||
)
|
||||
|
||||
AX_PYTHON_DEVEL([$PYTHON_REQUIRED_VERSION], [
|
||||
AS_IF([test "x$enable_pyzfs" = xyes], [
|
||||
AC_MSG_ERROR("Python $PYTHON_REQUIRED_VERSION development library is not installed")
|
||||
], [test "x$enable_pyzfs" != xno], [
|
||||
AS_IF([test "x$enable_pyzfs" = xyes], [
|
||||
AX_PYTHON_DEVEL([$PYTHON_REQUIRED_VERSION])
|
||||
], [
|
||||
AX_PYTHON_DEVEL([$PYTHON_REQUIRED_VERSION], [true])
|
||||
AS_IF([test "x$ax_python_devel_found" = xno], [
|
||||
enable_pyzfs=no
|
||||
])
|
||||
])
|
||||
|
|
|
@ -4,18 +4,13 @@
|
|||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_PYTHON_DEVEL([version], [action-if-not-found])
|
||||
# AX_PYTHON_DEVEL([version[,optional]])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Note: Defines as a precious variable "PYTHON_VERSION". Don't override it
|
||||
# in your configure.ac.
|
||||
#
|
||||
# Note: this is a slightly modified version of the original AX_PYTHON_DEVEL
|
||||
# macro which accepts an additional [action-if-not-found] argument. This
|
||||
# allow to detect if Python development is available without aborting the
|
||||
# configure phase with an hard error in case it is not.
|
||||
#
|
||||
# This macro checks for Python and tries to get the include path to
|
||||
# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LIBS) output
|
||||
# variables. It also exports $(PYTHON_EXTRA_LIBS) and
|
||||
|
@ -28,6 +23,11 @@
|
|||
# version number. Don't use "PYTHON_VERSION" for this: that environment
|
||||
# variable is declared as precious and thus reserved for the end-user.
|
||||
#
|
||||
# By default this will fail if it does not detect a development version of
|
||||
# python. If you want it to continue, set optional to true, like
|
||||
# AX_PYTHON_DEVEL([], [true]). The ax_python_devel_found variable will be
|
||||
# "no" if it fails.
|
||||
#
|
||||
# This macro should work for all versions of Python >= 2.1.0. As an end
|
||||
# user, you can disable the check for the python version by setting the
|
||||
# PYTHON_NOVERSIONCHECK environment variable to something else than the
|
||||
|
@ -45,7 +45,6 @@
|
|||
# Copyright (c) 2009 Matteo Settenvini <matteo@member.fsf.org>
|
||||
# Copyright (c) 2009 Horst Knorr <hk_classes@knoda.org>
|
||||
# Copyright (c) 2013 Daniel Mullner <muellner@math.stanford.edu>
|
||||
# Copyright (c) 2018 loli10K <ezomori.nozomu@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
|
@ -73,10 +72,18 @@
|
|||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 21
|
||||
#serial 36
|
||||
|
||||
AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
|
||||
AC_DEFUN([AX_PYTHON_DEVEL],[
|
||||
# Get whether it's optional
|
||||
if test -z "$2"; then
|
||||
ax_python_devel_optional=false
|
||||
else
|
||||
ax_python_devel_optional=$2
|
||||
fi
|
||||
ax_python_devel_found=yes
|
||||
|
||||
#
|
||||
# Allow the use of a (user set) custom python version
|
||||
#
|
||||
|
@ -87,23 +94,26 @@ AC_DEFUN([AX_PYTHON_DEVEL],[
|
|||
|
||||
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
|
||||
if test -z "$PYTHON"; then
|
||||
m4_ifvaln([$2],[$2],[
|
||||
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
|
||||
PYTHON_VERSION=""
|
||||
])
|
||||
AC_MSG_WARN([Cannot find python$PYTHON_VERSION in your system path])
|
||||
if ! $ax_python_devel_optional; then
|
||||
AC_MSG_ERROR([Giving up, python development not available])
|
||||
fi
|
||||
ax_python_devel_found=no
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for a version of Python >= 2.1.0
|
||||
#
|
||||
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys; \
|
||||
if test $ax_python_devel_found = yes; then
|
||||
#
|
||||
# Check for a version of Python >= 2.1.0
|
||||
#
|
||||
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys; \
|
||||
ver = sys.version.split ()[[0]]; \
|
||||
print (ver >= '2.1.0')"`
|
||||
if test "$ac_supports_python_ver" != "True"; then
|
||||
if test "$ac_supports_python_ver" != "True"; then
|
||||
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_FAILURE([
|
||||
AC_MSG_WARN([
|
||||
This version of the AC@&t@_PYTHON_DEVEL macro
|
||||
doesn't work properly with versions of Python before
|
||||
2.1.0. You may need to re-run configure, setting the
|
||||
|
@ -112,20 +122,27 @@ PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
|
|||
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
|
||||
to something else than an empty string.
|
||||
])
|
||||
if ! $ax_python_devel_optional; then
|
||||
AC_MSG_FAILURE([Giving up])
|
||||
fi
|
||||
ax_python_devel_found=no
|
||||
PYTHON_VERSION=""
|
||||
else
|
||||
AC_MSG_RESULT([skip at user request])
|
||||
fi
|
||||
else
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# If the macro parameter ``version'' is set, honour it.
|
||||
# A Python shim class, VPy, is used to implement correct version comparisons via
|
||||
# string expressions, since e.g. a naive textual ">= 2.7.3" won't work for
|
||||
# Python 2.7.10 (the ".1" being evaluated as less than ".3").
|
||||
#
|
||||
if test -n "$1"; then
|
||||
if test $ax_python_devel_found = yes; then
|
||||
#
|
||||
# If the macro parameter ``version'' is set, honour it.
|
||||
# A Python shim class, VPy, is used to implement correct version comparisons via
|
||||
# string expressions, since e.g. a naive textual ">= 2.7.3" won't work for
|
||||
# Python 2.7.10 (the ".1" being evaluated as less than ".3").
|
||||
#
|
||||
if test -n "$1"; then
|
||||
AC_MSG_CHECKING([for a version of Python $1])
|
||||
cat << EOF > ax_python_devel_vpy.py
|
||||
class VPy:
|
||||
|
@ -133,7 +150,7 @@ class VPy:
|
|||
return tuple(map(int, s.strip().replace("rc", ".").split(".")))
|
||||
def __init__(self):
|
||||
import sys
|
||||
self.vpy = tuple(sys.version_info)
|
||||
self.vpy = tuple(sys.version_info)[[:3]]
|
||||
def __eq__(self, s):
|
||||
return self.vpy == self.vtup(s)
|
||||
def __ne__(self, s):
|
||||
|
@ -155,25 +172,69 @@ EOF
|
|||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([this package requires Python $1.
|
||||
AC_MSG_WARN([this package requires Python $1.
|
||||
If you have it installed, but it isn't the default Python
|
||||
interpreter in your system path, please pass the PYTHON_VERSION
|
||||
variable to configure. See ``configure --help'' for reference.
|
||||
])
|
||||
if ! $ax_python_devel_optional; then
|
||||
AC_MSG_ERROR([Giving up])
|
||||
fi
|
||||
ax_python_devel_found=no
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for Python include path
|
||||
#
|
||||
#
|
||||
AC_MSG_CHECKING([for Python include path])
|
||||
if test -z "$PYTHON_CPPFLAGS"; then
|
||||
python_path=`$PYTHON -c "import sysconfig; \
|
||||
print (sysconfig.get_path('include'));"`
|
||||
plat_python_path=`$PYTHON -c "import sysconfig; \
|
||||
print (sysconfig.get_path('platinclude'));"`
|
||||
if test $ax_python_devel_found = yes; then
|
||||
#
|
||||
# Check if you have distutils, else fail
|
||||
#
|
||||
AC_MSG_CHECKING([for the sysconfig Python package])
|
||||
ac_sysconfig_result=`$PYTHON -c "import sysconfig" 2>&1`
|
||||
if test $? -eq 0; then
|
||||
AC_MSG_RESULT([yes])
|
||||
IMPORT_SYSCONFIG="import sysconfig"
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
|
||||
AC_MSG_CHECKING([for the distutils Python package])
|
||||
ac_sysconfig_result=`$PYTHON -c "from distutils import sysconfig" 2>&1`
|
||||
if test $? -eq 0; then
|
||||
AC_MSG_RESULT([yes])
|
||||
IMPORT_SYSCONFIG="from distutils import sysconfig"
|
||||
else
|
||||
AC_MSG_WARN([cannot import Python module "distutils".
|
||||
Please check your Python installation. The error was:
|
||||
$ac_sysconfig_result])
|
||||
if ! $ax_python_devel_optional; then
|
||||
AC_MSG_ERROR([Giving up])
|
||||
fi
|
||||
ax_python_devel_found=no
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $ax_python_devel_found = yes; then
|
||||
#
|
||||
# Check for Python include path
|
||||
#
|
||||
AC_MSG_CHECKING([for Python include path])
|
||||
if test -z "$PYTHON_CPPFLAGS"; then
|
||||
if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
|
||||
# sysconfig module has different functions
|
||||
python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
|
||||
print (sysconfig.get_path ('include'));"`
|
||||
plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
|
||||
print (sysconfig.get_path ('platinclude'));"`
|
||||
else
|
||||
# old distutils way
|
||||
python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
|
||||
print (sysconfig.get_python_inc ());"`
|
||||
plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
|
||||
print (sysconfig.get_python_inc (plat_specific=1));"`
|
||||
fi
|
||||
if test -n "${python_path}"; then
|
||||
if test "${plat_python_path}" != "${python_path}"; then
|
||||
python_path="-I$python_path -I$plat_python_path"
|
||||
|
@ -182,15 +243,15 @@ variable to configure. See ``configure --help'' for reference.
|
|||
fi
|
||||
fi
|
||||
PYTHON_CPPFLAGS=$python_path
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_CPPFLAGS])
|
||||
AC_SUBST([PYTHON_CPPFLAGS])
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_CPPFLAGS])
|
||||
AC_SUBST([PYTHON_CPPFLAGS])
|
||||
|
||||
#
|
||||
# Check for Python library path
|
||||
#
|
||||
AC_MSG_CHECKING([for Python library path])
|
||||
if test -z "$PYTHON_LIBS"; then
|
||||
#
|
||||
# Check for Python library path
|
||||
#
|
||||
AC_MSG_CHECKING([for Python library path])
|
||||
if test -z "$PYTHON_LIBS"; then
|
||||
# (makes two attempts to ensure we've got a version number
|
||||
# from the interpreter)
|
||||
ac_python_version=`cat<<EOD | $PYTHON -
|
||||
|
@ -208,7 +269,7 @@ EOD`
|
|||
ac_python_version=$PYTHON_VERSION
|
||||
else
|
||||
ac_python_version=`$PYTHON -c "import sys; \
|
||||
print ('.'.join(sys.version.split('.')[[:2]]))"`
|
||||
print ("%d.%d" % sys.version_info[[:2]])"`
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -220,7 +281,7 @@ EOD`
|
|||
ac_python_libdir=`cat<<EOD | $PYTHON -
|
||||
|
||||
# There should be only one
|
||||
import sysconfig
|
||||
$IMPORT_SYSCONFIG
|
||||
e = sysconfig.get_config_var('LIBDIR')
|
||||
if e is not None:
|
||||
print (e)
|
||||
|
@ -229,7 +290,7 @@ EOD`
|
|||
# Now, for the library:
|
||||
ac_python_library=`cat<<EOD | $PYTHON -
|
||||
|
||||
import sysconfig
|
||||
$IMPORT_SYSCONFIG
|
||||
c = sysconfig.get_config_vars()
|
||||
if 'LDVERSION' in c:
|
||||
print ('python'+c[['LDVERSION']])
|
||||
|
@ -249,88 +310,140 @@ EOD`
|
|||
else
|
||||
# old way: use libpython from python_configdir
|
||||
ac_python_libdir=`$PYTHON -c \
|
||||
"import sysconfig; \
|
||||
"from sysconfig import get_python_lib as f; \
|
||||
import os; \
|
||||
print (os.path.join(sysconfig.get_path('platstdlib'), 'config'));"`
|
||||
print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
|
||||
PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version"
|
||||
fi
|
||||
|
||||
if test -z "PYTHON_LIBS"; then
|
||||
m4_ifvaln([$2],[$2],[
|
||||
AC_MSG_ERROR([
|
||||
AC_MSG_WARN([
|
||||
Cannot determine location of your Python DSO. Please check it was installed with
|
||||
dynamic libraries enabled, or try setting PYTHON_LIBS by hand.
|
||||
])
|
||||
])
|
||||
if ! $ax_python_devel_optional; then
|
||||
AC_MSG_ERROR([Giving up])
|
||||
fi
|
||||
ax_python_devel_found=no
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_LIBS])
|
||||
AC_SUBST([PYTHON_LIBS])
|
||||
|
||||
#
|
||||
# Check for site packages
|
||||
#
|
||||
AC_MSG_CHECKING([for Python site-packages path])
|
||||
if test -z "$PYTHON_SITE_PKG"; then
|
||||
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
|
||||
print (distutils.sysconfig.get_python_lib(0,0));" 2>/dev/null || \
|
||||
$PYTHON -c "import sysconfig; \
|
||||
print (sysconfig.get_path('purelib'));"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_SITE_PKG])
|
||||
AC_SUBST([PYTHON_SITE_PKG])
|
||||
if test $ax_python_devel_found = yes; then
|
||||
AC_MSG_RESULT([$PYTHON_LIBS])
|
||||
AC_SUBST([PYTHON_LIBS])
|
||||
|
||||
#
|
||||
# libraries which must be linked in when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra libraries)
|
||||
if test -z "$PYTHON_EXTRA_LIBS"; then
|
||||
PYTHON_EXTRA_LIBS=`$PYTHON -c "import sysconfig; \
|
||||
#
|
||||
# Check for site packages
|
||||
#
|
||||
AC_MSG_CHECKING([for Python site-packages path])
|
||||
if test -z "$PYTHON_SITE_PKG"; then
|
||||
if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
|
||||
PYTHON_SITE_PKG=`$PYTHON -c "
|
||||
$IMPORT_SYSCONFIG;
|
||||
if hasattr(sysconfig, 'get_default_scheme'):
|
||||
scheme = sysconfig.get_default_scheme()
|
||||
else:
|
||||
scheme = sysconfig._get_default_scheme()
|
||||
if scheme == 'posix_local':
|
||||
# Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/
|
||||
scheme = 'posix_prefix'
|
||||
prefix = '$prefix'
|
||||
if prefix == 'NONE':
|
||||
prefix = '$ac_default_prefix'
|
||||
sitedir = sysconfig.get_path('purelib', scheme, vars={'base': prefix})
|
||||
print(sitedir)"`
|
||||
else
|
||||
# distutils.sysconfig way
|
||||
PYTHON_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
|
||||
print (sysconfig.get_python_lib(0,0));"`
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_SITE_PKG])
|
||||
AC_SUBST([PYTHON_SITE_PKG])
|
||||
|
||||
#
|
||||
# Check for platform-specific site packages
|
||||
#
|
||||
AC_MSG_CHECKING([for Python platform specific site-packages path])
|
||||
if test -z "$PYTHON_PLATFORM_SITE_PKG"; then
|
||||
if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
|
||||
PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c "
|
||||
$IMPORT_SYSCONFIG;
|
||||
if hasattr(sysconfig, 'get_default_scheme'):
|
||||
scheme = sysconfig.get_default_scheme()
|
||||
else:
|
||||
scheme = sysconfig._get_default_scheme()
|
||||
if scheme == 'posix_local':
|
||||
# Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/
|
||||
scheme = 'posix_prefix'
|
||||
prefix = '$prefix'
|
||||
if prefix == 'NONE':
|
||||
prefix = '$ac_default_prefix'
|
||||
sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase': prefix})
|
||||
print(sitedir)"`
|
||||
else
|
||||
# distutils.sysconfig way
|
||||
PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
|
||||
print (sysconfig.get_python_lib(1,0));"`
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_PLATFORM_SITE_PKG])
|
||||
AC_SUBST([PYTHON_PLATFORM_SITE_PKG])
|
||||
|
||||
#
|
||||
# libraries which must be linked in when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra libraries)
|
||||
if test -z "$PYTHON_EXTRA_LIBS"; then
|
||||
PYTHON_EXTRA_LIBS=`$PYTHON -c "$IMPORT_SYSCONFIG; \
|
||||
conf = sysconfig.get_config_var; \
|
||||
print (conf('LIBS') + ' ' + conf('SYSLIBS'))"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
|
||||
AC_SUBST(PYTHON_EXTRA_LIBS)
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
|
||||
AC_SUBST(PYTHON_EXTRA_LIBS)
|
||||
|
||||
#
|
||||
# linking flags needed when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra linking flags)
|
||||
if test -z "$PYTHON_EXTRA_LDFLAGS"; then
|
||||
PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import sysconfig; \
|
||||
#
|
||||
# linking flags needed when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra linking flags)
|
||||
if test -z "$PYTHON_EXTRA_LDFLAGS"; then
|
||||
PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "$IMPORT_SYSCONFIG; \
|
||||
conf = sysconfig.get_config_var; \
|
||||
print (conf('LINKFORSHARED'))"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
|
||||
AC_SUBST(PYTHON_EXTRA_LDFLAGS)
|
||||
# Hack for macos, it sticks this in here.
|
||||
PYTHON_EXTRA_LDFLAGS=`echo $PYTHON_EXTRA_LDFLAGS | sed 's/CoreFoundation.*$/CoreFoundation/'`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
|
||||
AC_SUBST(PYTHON_EXTRA_LDFLAGS)
|
||||
|
||||
#
|
||||
# final check to see if everything compiles alright
|
||||
#
|
||||
AC_MSG_CHECKING([consistency of all components of python development environment])
|
||||
# save current global flags
|
||||
ac_save_LIBS="$LIBS"
|
||||
ac_save_LDFLAGS="$LDFLAGS"
|
||||
ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_EXTRA_LIBS"
|
||||
LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS"
|
||||
CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
|
||||
AC_LANG_PUSH([C])
|
||||
AC_LINK_IFELSE([
|
||||
#
|
||||
# final check to see if everything compiles alright
|
||||
#
|
||||
AC_MSG_CHECKING([consistency of all components of python development environment])
|
||||
# save current global flags
|
||||
ac_save_LIBS="$LIBS"
|
||||
ac_save_LDFLAGS="$LDFLAGS"
|
||||
ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS"
|
||||
LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS"
|
||||
CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
|
||||
AC_LANG_PUSH([C])
|
||||
AC_LINK_IFELSE([
|
||||
AC_LANG_PROGRAM([[#include <Python.h>]],
|
||||
[[Py_Initialize();]])
|
||||
],[pythonexists=yes],[pythonexists=no])
|
||||
AC_LANG_POP([C])
|
||||
# turn back to default flags
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
LDFLAGS="$ac_save_LDFLAGS"
|
||||
AC_LANG_POP([C])
|
||||
# turn back to default flags
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
LDFLAGS="$ac_save_LDFLAGS"
|
||||
|
||||
AC_MSG_RESULT([$pythonexists])
|
||||
AC_MSG_RESULT([$pythonexists])
|
||||
|
||||
if test ! "x$pythonexists" = "xyes"; then
|
||||
m4_ifvaln([$2],[$2],[
|
||||
AC_MSG_FAILURE([
|
||||
if test ! "x$pythonexists" = "xyes"; then
|
||||
AC_MSG_WARN([
|
||||
Could not link test program to Python. Maybe the main Python library has been
|
||||
installed in some non-standard library path. If so, pass it to configure,
|
||||
via the LIBS environment variable.
|
||||
|
@ -340,9 +453,13 @@ EOD`
|
|||
You probably have to install the development version of the Python package
|
||||
for your distribution. The exact name of this package varies among them.
|
||||
============================================================================
|
||||
])
|
||||
PYTHON_VERSION=""
|
||||
])
|
||||
])
|
||||
if ! $ax_python_devel_optional; then
|
||||
AC_MSG_ERROR([Giving up])
|
||||
fi
|
||||
ax_python_devel_found=no
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
|
|
|
@ -90,8 +90,8 @@ AC_DEFUN([ZFS_AC_FIND_SYSTEM_LIBRARY], [
|
|||
AC_DEFINE([HAVE_][$1], [1], [Define if you have [$5]])
|
||||
$7
|
||||
],[dnl ELSE
|
||||
AC_SUBST([$1]_CFLAGS, [])
|
||||
AC_SUBST([$1]_LIBS, [])
|
||||
AC_SUBST([$1]_CFLAGS, [""])
|
||||
AC_SUBST([$1]_LIBS, [""])
|
||||
AC_MSG_WARN([cannot find [$5] via pkg-config or in the standard locations])
|
||||
$8
|
||||
])
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
dnl #
|
||||
dnl # check if kernel provides definitions for given types
|
||||
dnl #
|
||||
|
||||
dnl _ZFS_AC_KERNEL_SRC_TYPE(type)
|
||||
AC_DEFUN([_ZFS_AC_KERNEL_SRC_TYPE], [
|
||||
ZFS_LINUX_TEST_SRC([type_$1], [
|
||||
#include <linux/types.h>
|
||||
],[
|
||||
const $1 __attribute__((unused)) x = ($1) 0;
|
||||
])
|
||||
])
|
||||
|
||||
dnl _ZFS_AC_KERNEL_TYPE(type)
|
||||
AC_DEFUN([_ZFS_AC_KERNEL_TYPE], [
|
||||
AC_MSG_CHECKING([whether kernel defines $1])
|
||||
ZFS_LINUX_TEST_RESULT([type_$1], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_KERNEL_]m4_quote(m4_translit([$1], [a-z], [A-Z])),
|
||||
1, [kernel defines $1])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl ZFS_AC_KERNEL_TYPES([types...])
|
||||
AC_DEFUN([ZFS_AC_KERNEL_TYPES], [
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_TYPES], [
|
||||
m4_foreach_w([type], [$1], [
|
||||
_ZFS_AC_KERNEL_SRC_TYPE(type)
|
||||
])
|
||||
])
|
||||
AC_DEFUN([ZFS_AC_KERNEL_TYPES], [
|
||||
m4_foreach_w([type], [$1], [
|
||||
_ZFS_AC_KERNEL_TYPE(type)
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
ZFS_AC_KERNEL_TYPES([intptr_t])
|
|
@ -37,6 +37,7 @@ dnl # only once the compilation can be done in parallel significantly
|
|||
dnl # speeding up the process.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
||||
ZFS_AC_KERNEL_SRC_TYPES
|
||||
ZFS_AC_KERNEL_SRC_OBJTOOL
|
||||
ZFS_AC_KERNEL_SRC_GLOBAL_PAGE_STATE
|
||||
ZFS_AC_KERNEL_SRC_ACCESS_OK_TYPE
|
||||
|
@ -187,6 +188,7 @@ dnl #
|
|||
dnl # Check results of kernel interface tests.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
||||
ZFS_AC_KERNEL_TYPES
|
||||
ZFS_AC_KERNEL_ACCESS_OK_TYPE
|
||||
ZFS_AC_KERNEL_GLOBAL_PAGE_STATE
|
||||
ZFS_AC_KERNEL_OBJTOOL
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
dnl
|
||||
dnl backtrace(), for userspace assertions. glibc has this directly in libc.
|
||||
dnl FreeBSD and (sometimes) musl have it in a separate -lexecinfo. It's assumed
|
||||
dnl that this will also get the companion function backtrace_symbols().
|
||||
dnl
|
||||
AC_DEFUN([ZFS_AC_CONFIG_USER_BACKTRACE], [
|
||||
AX_SAVE_FLAGS
|
||||
LIBS=""
|
||||
AC_SEARCH_LIBS([backtrace], [execinfo], [
|
||||
AC_DEFINE(HAVE_BACKTRACE, 1, [backtrace() is available])
|
||||
AC_SUBST([BACKTRACE_LIBS], ["$LIBS"])
|
||||
])
|
||||
AX_RESTORE_FLAGS
|
||||
])
|
|
@ -0,0 +1,44 @@
|
|||
dnl
|
||||
dnl Checks for libunwind, which usually does a better job than backtrace() when
|
||||
dnl resolving symbols in the stack backtrace. Newer versions have support for
|
||||
dnl getting info about the object file the function came from, so we look for
|
||||
dnl that too and use it if found.
|
||||
dnl
|
||||
AC_DEFUN([ZFS_AC_CONFIG_USER_LIBUNWIND], [
|
||||
AC_ARG_WITH([libunwind],
|
||||
AS_HELP_STRING([--with-libunwind],
|
||||
[use libunwind for backtraces in userspace assertions]),
|
||||
[],
|
||||
[with_libunwind=auto])
|
||||
|
||||
AS_IF([test "x$with_libunwind" != "xno"], [
|
||||
ZFS_AC_FIND_SYSTEM_LIBRARY(LIBUNWIND, [libunwind], [libunwind.h], [], [unwind], [], [
|
||||
dnl unw_get_elf_filename() is sometimes a macro, other
|
||||
dnl times a proper symbol, so we can't just do a link
|
||||
dnl check; we need to include the header properly.
|
||||
AX_SAVE_FLAGS
|
||||
CFLAGS="$CFLAGS $LIBUNWIND_CFLAGS"
|
||||
LIBS="$LIBS $LIBUNWIND_LIBS"
|
||||
AC_MSG_CHECKING([for unw_get_elf_filename in libunwind])
|
||||
AC_LINK_IFELSE([
|
||||
AC_LANG_PROGRAM([
|
||||
#define UNW_LOCAL_ONLY
|
||||
#include <libunwind.h>
|
||||
], [
|
||||
unw_get_elf_filename(0, 0, 0, 0);
|
||||
])
|
||||
], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_LIBUNWIND_ELF, 1,
|
||||
[libunwind has unw_get_elf_filename])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
AX_RESTORE_FLAGS
|
||||
], [
|
||||
AS_IF([test "x$with_libunwind" = "xyes"], [
|
||||
AC_MSG_FAILURE([--with-libunwind was given, but libunwind is not available, try installing libunwind-devel])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
|
@ -26,12 +26,14 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
|
|||
ZFS_AC_CONFIG_USER_AIO_H
|
||||
ZFS_AC_CONFIG_USER_CLOCK_GETTIME
|
||||
ZFS_AC_CONFIG_USER_PAM
|
||||
ZFS_AC_CONFIG_USER_BACKTRACE
|
||||
ZFS_AC_CONFIG_USER_LIBUNWIND
|
||||
ZFS_AC_CONFIG_USER_RUNSTATEDIR
|
||||
ZFS_AC_CONFIG_USER_MAKEDEV_IN_SYSMACROS
|
||||
ZFS_AC_CONFIG_USER_MAKEDEV_IN_MKDEV
|
||||
ZFS_AC_CONFIG_USER_ZFSEXEC
|
||||
|
||||
AC_CHECK_FUNCS([execvpe issetugid mlockall strlcat strlcpy])
|
||||
AC_CHECK_FUNCS([execvpe issetugid mlockall strlcat strlcpy gettid])
|
||||
|
||||
AC_SUBST(RM)
|
||||
])
|
||||
|
|
|
@ -512,32 +512,33 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
|
|||
[with_vendor=$withval],
|
||||
[with_vendor=check])
|
||||
AS_IF([test "x$with_vendor" = "xcheck"],[
|
||||
if test -f /etc/toss-release ; then
|
||||
VENDOR=toss ;
|
||||
elif test -f /etc/fedora-release ; then
|
||||
VENDOR=fedora ;
|
||||
elif test -f /etc/redhat-release ; then
|
||||
VENDOR=redhat ;
|
||||
elif test -f /etc/gentoo-release ; then
|
||||
VENDOR=gentoo ;
|
||||
if test -f /etc/alpine-release ; then
|
||||
VENDOR=alpine ;
|
||||
elif test -f /etc/arch-release ; then
|
||||
VENDOR=arch ;
|
||||
elif test -f /etc/fedora-release ; then
|
||||
VENDOR=fedora ;
|
||||
elif test -f /bin/freebsd-version ; then
|
||||
VENDOR=freebsd ;
|
||||
elif test -f /etc/gentoo-release ; then
|
||||
VENDOR=gentoo ;
|
||||
elif test -f /etc/lunar.release ; then
|
||||
VENDOR=lunar ;
|
||||
elif test -f /etc/openEuler-release ; then
|
||||
VENDOR=openeuler ;
|
||||
elif test -f /etc/SuSE-release ; then
|
||||
VENDOR=sles ;
|
||||
elif test -f /etc/slackware-version ; then
|
||||
VENDOR=slackware ;
|
||||
elif test -f /etc/lunar.release ; then
|
||||
VENDOR=lunar ;
|
||||
elif test -f /etc/toss-release ; then
|
||||
VENDOR=toss ;
|
||||
elif test -f /etc/lsb-release ; then
|
||||
VENDOR=ubuntu ;
|
||||
# put debian and redhat last as derivatives may have also their file
|
||||
elif test -f /etc/debian_version ; then
|
||||
VENDOR=debian ;
|
||||
elif test -f /etc/alpine-release ; then
|
||||
VENDOR=alpine ;
|
||||
elif test -f /bin/freebsd-version ; then
|
||||
VENDOR=freebsd ;
|
||||
elif test -f /etc/openEuler-release ; then
|
||||
VENDOR=openeuler ;
|
||||
elif test -f /etc/redhat-release ; then
|
||||
VENDOR=redhat ;
|
||||
else
|
||||
VENDOR= ;
|
||||
fi],
|
||||
|
@ -550,20 +551,15 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
|
|||
|
||||
AC_MSG_CHECKING([default package type])
|
||||
case "$VENDOR" in
|
||||
toss) DEFAULT_PACKAGE=rpm ;;
|
||||
redhat) DEFAULT_PACKAGE=rpm ;;
|
||||
fedora) DEFAULT_PACKAGE=rpm ;;
|
||||
gentoo) DEFAULT_PACKAGE=tgz ;;
|
||||
alpine) DEFAULT_PACKAGE=tgz ;;
|
||||
arch) DEFAULT_PACKAGE=tgz ;;
|
||||
sles) DEFAULT_PACKAGE=rpm ;;
|
||||
slackware) DEFAULT_PACKAGE=tgz ;;
|
||||
lunar) DEFAULT_PACKAGE=tgz ;;
|
||||
ubuntu) DEFAULT_PACKAGE=deb ;;
|
||||
debian) DEFAULT_PACKAGE=deb ;;
|
||||
freebsd) DEFAULT_PACKAGE=pkg ;;
|
||||
openeuler) DEFAULT_PACKAGE=rpm ;;
|
||||
*) DEFAULT_PACKAGE=rpm ;;
|
||||
alpine|arch|gentoo|lunar|slackware)
|
||||
DEFAULT_PACKAGE=tgz ;;
|
||||
debian|ubuntu)
|
||||
DEFAULT_PACKAGE=deb ;;
|
||||
freebsd)
|
||||
DEFAULT_PACKAGE=pkg ;;
|
||||
*)
|
||||
# fedora|openeuler|redhat|sles|toss
|
||||
DEFAULT_PACKAGE=rpm ;;
|
||||
esac
|
||||
AC_MSG_RESULT([$DEFAULT_PACKAGE])
|
||||
AC_SUBST(DEFAULT_PACKAGE)
|
||||
|
@ -578,7 +574,7 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
|
|||
|
||||
AC_MSG_CHECKING([default shell])
|
||||
case "$VENDOR" in
|
||||
gentoo|alpine) DEFAULT_INIT_SHELL=/sbin/openrc-run
|
||||
alpine|gentoo) DEFAULT_INIT_SHELL=/sbin/openrc-run
|
||||
IS_SYSV_RC=false ;;
|
||||
*) DEFAULT_INIT_SHELL=/bin/sh
|
||||
IS_SYSV_RC=true ;;
|
||||
|
@ -598,17 +594,19 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
|
|||
|
||||
AC_MSG_CHECKING([default init config directory])
|
||||
case "$VENDOR" in
|
||||
alpine) initconfdir=/etc/conf.d ;;
|
||||
gentoo) initconfdir=/etc/conf.d ;;
|
||||
toss) initconfdir=/etc/sysconfig ;;
|
||||
redhat) initconfdir=/etc/sysconfig ;;
|
||||
fedora) initconfdir=/etc/sysconfig ;;
|
||||
sles) initconfdir=/etc/sysconfig ;;
|
||||
openeuler) initconfdir=/etc/sysconfig ;;
|
||||
ubuntu) initconfdir=/etc/default ;;
|
||||
debian) initconfdir=/etc/default ;;
|
||||
freebsd) initconfdir=$sysconfdir/rc.conf.d;;
|
||||
*) initconfdir=/etc/default ;;
|
||||
alpine|gentoo)
|
||||
initconfdir=/etc/conf.d
|
||||
;;
|
||||
fedora|openeuler|redhat|sles|toss)
|
||||
initconfdir=/etc/sysconfig
|
||||
;;
|
||||
freebsd)
|
||||
initconfdir=$sysconfdir/rc.conf.d
|
||||
;;
|
||||
*)
|
||||
# debian|ubuntu
|
||||
initconfdir=/etc/default
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT([$initconfdir])
|
||||
AC_SUBST(initconfdir)
|
||||
|
@ -625,11 +623,15 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
|
|||
|
||||
AC_MSG_CHECKING([default bash completion directory])
|
||||
case "$VENDOR" in
|
||||
ubuntu) bashcompletiondir=/usr/share/bash-completion/completions ;;
|
||||
debian) bashcompletiondir=/usr/share/bash-completion/completions ;;
|
||||
freebsd) bashcompletiondir=$sysconfdir/bash_completion.d;;
|
||||
gentoo) bashcompletiondir=/usr/share/bash-completion/completions ;;
|
||||
*) bashcompletiondir=/etc/bash_completion.d ;;
|
||||
alpine|debian|gentoo|ubuntu)
|
||||
bashcompletiondir=/usr/share/bash-completion/completions
|
||||
;;
|
||||
freebsd)
|
||||
bashcompletiondir=$sysconfdir/bash_completion.d
|
||||
;;
|
||||
*)
|
||||
bashcompletiondir=/etc/bash_completion.d
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT([$bashcompletiondir])
|
||||
AC_SUBST(bashcompletiondir)
|
||||
|
|
|
@ -155,7 +155,7 @@ __zfs_list_volumes()
|
|||
__zfs_argument_chosen()
|
||||
{
|
||||
local word property
|
||||
for word in $(seq $((COMP_CWORD-1)) -1 2)
|
||||
for word in $(seq $((COMP_CWORD-1)) -1 2 2>/dev/null)
|
||||
do
|
||||
local prev="${COMP_WORDS[$word]}"
|
||||
if [[ ${COMP_WORDS[$word-1]} != -[tos] ]]
|
||||
|
|
|
@ -195,7 +195,7 @@ Depends: dkms (>> 2.1.1.2-5),
|
|||
file,
|
||||
libc6-dev | libc-dev,
|
||||
lsb-release,
|
||||
python3-distutils | libpython3-stdlib (<< 3.6.4),
|
||||
python3 (>> 3.12) | python3-distutils | libpython3-stdlib (<< 3.6.4),
|
||||
${misc:Depends},
|
||||
${perl:Depends}
|
||||
Recommends: openzfs-zfs-zed, openzfs-zfsutils (>= ${source:Version}), ${linux:Recommends}
|
||||
|
|
|
@ -716,7 +716,7 @@ typedef struct get_all_cb {
|
|||
} get_all_cb_t;
|
||||
|
||||
_LIBZFS_H void zfs_foreach_mountpoint(libzfs_handle_t *, zfs_handle_t **,
|
||||
size_t, zfs_iter_f, void *, boolean_t);
|
||||
size_t, zfs_iter_f, void *, uint_t);
|
||||
_LIBZFS_H void libzfs_add_handle(get_all_cb_t *, zfs_handle_t *);
|
||||
|
||||
/*
|
||||
|
@ -1004,7 +1004,8 @@ _LIBZFS_H int zfs_smb_acl_rename(libzfs_handle_t *, char *, char *, char *,
|
|||
* Enable and disable datasets within a pool by mounting/unmounting and
|
||||
* sharing/unsharing them.
|
||||
*/
|
||||
_LIBZFS_H int zpool_enable_datasets(zpool_handle_t *, const char *, int);
|
||||
_LIBZFS_H int zpool_enable_datasets(zpool_handle_t *, const char *, int,
|
||||
uint_t);
|
||||
_LIBZFS_H int zpool_disable_datasets(zpool_handle_t *, boolean_t);
|
||||
_LIBZFS_H void zpool_disable_datasets_os(zpool_handle_t *, boolean_t);
|
||||
_LIBZFS_H void zpool_disable_volume_os(const char *);
|
||||
|
|
|
@ -77,6 +77,7 @@ _LIBZFS_CORE_H int lzc_snaprange_space(const char *, const char *, uint64_t *);
|
|||
_LIBZFS_CORE_H int lzc_hold(nvlist_t *, int, nvlist_t **);
|
||||
_LIBZFS_CORE_H int lzc_release(nvlist_t *, nvlist_t **);
|
||||
_LIBZFS_CORE_H int lzc_get_holds(const char *, nvlist_t **);
|
||||
_LIBZFS_CORE_H int lzc_get_props(const char *, nvlist_t **);
|
||||
|
||||
enum lzc_send_flags {
|
||||
LZC_SEND_FLAG_EMBED_DATA = 1 << 0,
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2018, 2024 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIBZUTIL_H
|
||||
|
@ -79,6 +79,8 @@ typedef struct importargs {
|
|||
boolean_t can_be_active; /* can the pool be active? */
|
||||
boolean_t scan; /* prefer scanning to libblkid cache */
|
||||
nvlist_t *policy; /* load policy (max txg, rewind, etc.) */
|
||||
boolean_t do_destroyed;
|
||||
boolean_t do_all;
|
||||
} importargs_t;
|
||||
|
||||
typedef struct libpc_handle {
|
||||
|
|
|
@ -20,7 +20,6 @@ noinst_HEADERS = \
|
|||
%D%/spl/sys/debug.h \
|
||||
%D%/spl/sys/dirent.h \
|
||||
%D%/spl/sys/disp.h \
|
||||
%D%/spl/sys/dkio.h \
|
||||
%D%/spl/sys/fcntl.h \
|
||||
%D%/spl/sys/file.h \
|
||||
%D%/spl/sys/freebsd_rwlock.h \
|
||||
|
|
|
@ -138,7 +138,8 @@ typedef int enum_t;
|
|||
#define readdir64 readdir
|
||||
#define dirent64 dirent
|
||||
#endif
|
||||
#define P2ALIGN(x, align) ((x) & -(align))
|
||||
// Deprecated. Use P2ALIGN_TYPED instead.
|
||||
// #define P2ALIGN(x, align) ((x) & -(align))
|
||||
#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1)
|
||||
#define P2ROUNDUP(x, align) ((((x) - 1) | ((align) - 1)) + 1)
|
||||
#define P2PHASE(x, align) ((x) & ((align) - 1))
|
||||
|
|
|
@ -56,11 +56,33 @@
|
|||
/*
|
||||
* Common DEBUG functionality.
|
||||
*/
|
||||
#ifdef __FreeBSD__
|
||||
#include <linux/compiler.h>
|
||||
#endif
|
||||
|
||||
#ifndef __printflike
|
||||
#define __printflike(a, b) __printf(a, b)
|
||||
#endif
|
||||
|
||||
#ifndef __maybe_unused
|
||||
#define __maybe_unused __attribute__((unused))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Without this, we see warnings from objtool during normal Linux builds when
|
||||
* the kernel is built with CONFIG_STACK_VALIDATION=y:
|
||||
*
|
||||
* warning: objtool: tsd_create() falls through to next function __list_add()
|
||||
* warning: objtool: .text: unexpected end of section
|
||||
*
|
||||
* Until the toolchain stops doing this, we must only define this attribute on
|
||||
* spl_panic() when doing static analysis.
|
||||
*/
|
||||
#if defined(__COVERITY__) || defined(__clang_analyzer__)
|
||||
__attribute__((__noreturn__))
|
||||
#endif
|
||||
extern void spl_panic(const char *file, const char *func, int line,
|
||||
const char *fmt, ...) __attribute__((__noreturn__));
|
||||
const char *fmt, ...);
|
||||
extern void spl_dumpstack(void);
|
||||
|
||||
static inline int
|
||||
|
@ -73,8 +95,10 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
#ifndef expect
|
||||
#define expect(expr, value) (__builtin_expect((expr), (value)))
|
||||
#endif
|
||||
#ifndef __linux__
|
||||
#define likely(expr) expect((expr) != 0, 1)
|
||||
#define unlikely(expr) expect((expr) != 0, 0)
|
||||
#endif
|
||||
|
||||
#define PANIC(fmt, a...) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
|
||||
|
@ -84,6 +108,12 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
spl_assert("VERIFY(" #cond ") failed\n", \
|
||||
__FILE__, __FUNCTION__, __LINE__))
|
||||
|
||||
#define VERIFYF(cond, str, ...) do { \
|
||||
if (unlikely(!cond)) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY(" #cond ") failed " str "\n", __VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
||||
const boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||
const boolean_t _verify3_right = (boolean_t)(RIGHT); \
|
||||
|
@ -123,7 +153,7 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%p " #OP " %p)\n", \
|
||||
"failed (%px " #OP " %px)\n", \
|
||||
(void *)_verify3_left, \
|
||||
(void *)_verify3_right); \
|
||||
} while (0)
|
||||
|
@ -142,10 +172,98 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
if (unlikely(!(0 == _verify0_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY0P(" #RIGHT ") " \
|
||||
"failed (NULL == %p)\n", \
|
||||
"failed (NULL == %px)\n", \
|
||||
(void *)_verify0_right); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Note that you should not put any operations you want to always happen
|
||||
* in the print section for ASSERTs unless you only want them to run on
|
||||
* debug builds!
|
||||
* e.g. ASSERT3UF(2, <, 3, "%s", foo(x)), foo(x) won't run on non-debug
|
||||
* builds.
|
||||
*/
|
||||
|
||||
#define VERIFY3BF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
const boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||
const boolean_t _verify3_right = (boolean_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%d " #OP " %d) " STR "\n", \
|
||||
(boolean_t)(_verify3_left), \
|
||||
(boolean_t)(_verify3_right), \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3SF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
const int64_t _verify3_left = (int64_t)(LEFT); \
|
||||
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%lld " #OP " %lld) " STR "\n", \
|
||||
(long long)(_verify3_left), \
|
||||
(long long)(_verify3_right), \
|
||||
__VA_ARGS); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3UF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
const uint64_t _verify3_left = (uint64_t)(LEFT); \
|
||||
const uint64_t _verify3_right = (uint64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%llu " #OP " %llu) " STR "\n", \
|
||||
(unsigned long long)(_verify3_left), \
|
||||
(unsigned long long)(_verify3_right), \
|
||||
__VA_ARGS); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3PF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
const uintptr_t _verify3_left = (uintptr_t)(LEFT); \
|
||||
const uintptr_t _verify3_right = (uintptr_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%px " #OP " %px) " STR "\n", \
|
||||
(void *) (_verify3_left), \
|
||||
(void *) (_verify3_right), \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY0PF(RIGHT, STR, ...) do { \
|
||||
const uintptr_t _verify3_left = (uintptr_t)(0); \
|
||||
const uintptr_t _verify3_right = (uintptr_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left == _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY0(0 == " #RIGHT ") " \
|
||||
"failed (0 == %px) " STR "\n", \
|
||||
(long long) (_verify3_right), \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY0F(RIGHT, STR, ...) do { \
|
||||
const int64_t _verify3_left = (int64_t)(0); \
|
||||
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left == _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY0(0 == " #RIGHT ") " \
|
||||
"failed (0 == %lld) " STR "\n", \
|
||||
(long long) (_verify3_right), \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY_IMPLY(A, B) \
|
||||
((void)(likely((!(A)) || (B)) || \
|
||||
spl_assert("(" #A ") implies (" #B ")", \
|
||||
__FILE__, __FUNCTION__, __LINE__)))
|
||||
|
||||
#define VERIFY_EQUIV(A, B) \
|
||||
((void)(likely(!!(A) == !!(B)) || \
|
||||
spl_assert("(" #A ") is equivalent to (" #B ")", \
|
||||
__FILE__, __FUNCTION__, __LINE__)))
|
||||
|
||||
/*
|
||||
* Debugging disabled (--disable-debug)
|
||||
*/
|
||||
|
@ -162,6 +280,13 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
|
||||
#define ASSERT0(x) ((void) sizeof ((uintptr_t)(x)))
|
||||
#define ASSERT0P(x) ((void) sizeof ((uintptr_t)(x)))
|
||||
#define ASSERT3BF(x, y, z, str, ...) ASSERT3B(x, y, z)
|
||||
#define ASSERT3SF(x, y, z, str, ...) ASSERT3S(x, y, z)
|
||||
#define ASSERT3UF(x, y, z, str, ...) ASSERT3U(x, y, z)
|
||||
#define ASSERT3PF(x, y, z, str, ...) ASSERT3P(x, y, z)
|
||||
#define ASSERT0PF(x, str, ...) ASSERT0P(x)
|
||||
#define ASSERT0F(x, str, ...) ASSERT0(x)
|
||||
#define ASSERTF(x, str, ...) ASSERT(x)
|
||||
#define IMPLY(A, B) \
|
||||
((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))
|
||||
#define EQUIV(A, B) \
|
||||
|
@ -178,16 +303,16 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
#define ASSERT3P VERIFY3P
|
||||
#define ASSERT0 VERIFY0
|
||||
#define ASSERT0P VERIFY0P
|
||||
#define ASSERT3BF VERIFY3BF
|
||||
#define ASSERT3SF VERIFY3SF
|
||||
#define ASSERT3UF VERIFY3UF
|
||||
#define ASSERT3PF VERIFY3PF
|
||||
#define ASSERT0PF VERIFY0PF
|
||||
#define ASSERT0F VERIFY0F
|
||||
#define ASSERTF VERIFYF
|
||||
#define ASSERT VERIFY
|
||||
#define IMPLY(A, B) \
|
||||
((void)(likely((!(A)) || (B)) || \
|
||||
spl_assert("(" #A ") implies (" #B ")", \
|
||||
__FILE__, __FUNCTION__, __LINE__)))
|
||||
#define EQUIV(A, B) \
|
||||
((void)(likely(!!(A) == !!(B)) || \
|
||||
spl_assert("(" #A ") is equivalent to (" #B ")", \
|
||||
__FILE__, __FUNCTION__, __LINE__)))
|
||||
|
||||
#define IMPLY VERIFY_IMPLY
|
||||
#define EQUIV VERIFY_EQUIV
|
||||
|
||||
#endif /* NDEBUG */
|
||||
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _OPENSOLARIS_SYS_DKIO_H_
|
||||
#define _OPENSOLARIS_SYS_DKIO_H_
|
||||
|
||||
#define DKIOC (0x04 << 8)
|
||||
#define DKIOCFLUSHWRITECACHE (DKIOC|34) /* flush cache to phys medium */
|
||||
|
||||
#endif /* _OPENSOLARIS_SYS_DKIO_H_ */
|
|
@ -45,11 +45,11 @@
|
|||
#define F_SEEK_HOLE FIOSEEKHOLE
|
||||
|
||||
struct opensolaris_utsname {
|
||||
char *sysname;
|
||||
char *nodename;
|
||||
char *release;
|
||||
char version[32];
|
||||
char *machine;
|
||||
const char *sysname;
|
||||
const char *nodename;
|
||||
const char *release;
|
||||
char version[32];
|
||||
const char *machine;
|
||||
};
|
||||
|
||||
#define task_io_account_read(n)
|
||||
|
|
|
@ -39,20 +39,14 @@
|
|||
#include <sys/signalvar.h>
|
||||
#include <sys/debug.h>
|
||||
|
||||
#define FORREAL 0
|
||||
#define JUSTLOOKING 1
|
||||
|
||||
static __inline int
|
||||
issig(int why)
|
||||
issig(void)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct proc *p;
|
||||
int sig;
|
||||
|
||||
ASSERT(why == FORREAL || why == JUSTLOOKING);
|
||||
if (SIGPENDING(td)) {
|
||||
if (why == JUSTLOOKING)
|
||||
return (1);
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
mtx_lock(&p->p_sigacts->ps_mtx);
|
||||
|
|
|
@ -191,7 +191,8 @@ extern unsigned char bcd_to_byte[256];
|
|||
* eg, P2ALIGN(0x1234, 0x100) == 0x1200 (0x12*align)
|
||||
* eg, P2ALIGN(0x5600, 0x100) == 0x5600 (0x56*align)
|
||||
*/
|
||||
#define P2ALIGN(x, align) ((x) & -(align))
|
||||
// Deprecated. Use P2ALIGN_TYPED instead.
|
||||
// #define P2ALIGN(x, align) ((x) & -(align))
|
||||
|
||||
/*
|
||||
* return x % (mod) align
|
||||
|
|
|
@ -63,7 +63,6 @@ kernel_spl_sys_HEADERS = \
|
|||
%D%/spl/sys/ctype.h \
|
||||
%D%/spl/sys/debug.h \
|
||||
%D%/spl/sys/disp.h \
|
||||
%D%/spl/sys/dkio.h \
|
||||
%D%/spl/sys/errno.h \
|
||||
%D%/spl/sys/fcntl.h \
|
||||
%D%/spl/sys/file.h \
|
||||
|
|
|
@ -94,6 +94,33 @@ blk_queue_set_write_cache(struct request_queue *q, bool wc, bool fua)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect if a device has a write cache. Used to set the intial value for the
|
||||
* vdev nowritecache flag.
|
||||
*
|
||||
* 4.10: QUEUE_FLAG_WC added. Initialised by the driver, but can be changed
|
||||
* later by the operator. If not set, kernel will return flush requests
|
||||
* immediately without doing anything.
|
||||
* 6.6: QUEUE_FLAG_HW_WC added. Initialised by the driver, can't be changed.
|
||||
* Only controls if the operator is allowed to change _WC. Initial version
|
||||
* buggy; aliased to QUEUE_FLAG_FUA, so unuseable.
|
||||
* 6.6.10, 6.7: QUEUE_FLAG_HW_WC fixed.
|
||||
*
|
||||
* Older than 4.10 we just assume write cache, and let the normal flush fail
|
||||
* detection apply.
|
||||
*/
|
||||
static inline boolean_t
|
||||
zfs_bdev_has_write_cache(struct block_device *bdev)
|
||||
{
|
||||
#if defined(QUEUE_FLAG_HW_WC) && QUEUE_FLAG_HW_WC != QUEUE_FLAG_FUA
|
||||
return (test_bit(QUEUE_FLAG_HW_WC, &bdev_get_queue(bdev)->queue_flags));
|
||||
#elif defined(QUEUE_FLAG_WC)
|
||||
return (test_bit(QUEUE_FLAG_WC, &bdev_get_queue(bdev)->queue_flags));
|
||||
#else
|
||||
return (B_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
blk_queue_set_read_ahead(struct request_queue *q, unsigned long ra_pages)
|
||||
{
|
||||
|
@ -563,9 +590,11 @@ static inline boolean_t
|
|||
bdev_discard_supported(struct block_device *bdev)
|
||||
{
|
||||
#if defined(HAVE_BDEV_MAX_DISCARD_SECTORS)
|
||||
return (!!bdev_max_discard_sectors(bdev));
|
||||
return (bdev_max_discard_sectors(bdev) > 0 &&
|
||||
bdev_discard_granularity(bdev) > 0);
|
||||
#elif defined(HAVE_BLK_QUEUE_DISCARD)
|
||||
return (!!blk_queue_discard(bdev_get_queue(bdev)));
|
||||
return (blk_queue_discard(bdev_get_queue(bdev)) > 0 &&
|
||||
bdev_get_queue(bdev)->limits.discard_granularity > 0);
|
||||
#else
|
||||
#error "Unsupported kernel"
|
||||
#endif
|
||||
|
|
|
@ -1,24 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
|
||||
* Copyright (C) 2007 The Regents of the University of California.
|
||||
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
||||
* Written by Brian Behlendorf <behlendorf1@llnl.gov>.
|
||||
* UCRL-CODE-235197
|
||||
* Copyright (c) 2020 iXsystems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of the SPL, Solaris Porting Layer.
|
||||
* 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.
|
||||
*
|
||||
* The SPL is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
* 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.
|
||||
*
|
||||
* The SPL is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with the SPL. If not, see <http://www.gnu.org/licenses/>.
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -47,10 +52,17 @@
|
|||
#ifndef _SPL_DEBUG_H
|
||||
#define _SPL_DEBUG_H
|
||||
|
||||
|
||||
/*
|
||||
* Common DEBUG functionality.
|
||||
*/
|
||||
#ifdef __FreeBSD__
|
||||
#include <linux/compiler.h>
|
||||
#endif
|
||||
|
||||
#ifndef __printflike
|
||||
#define __printflike(a, b) __printf(a, b)
|
||||
#endif
|
||||
|
||||
#ifndef __maybe_unused
|
||||
#define __maybe_unused __attribute__((unused))
|
||||
|
@ -80,6 +92,14 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
return (0);
|
||||
}
|
||||
|
||||
#ifndef expect
|
||||
#define expect(expr, value) (__builtin_expect((expr), (value)))
|
||||
#endif
|
||||
#ifndef __linux__
|
||||
#define likely(expr) expect((expr) != 0, 1)
|
||||
#define unlikely(expr) expect((expr) != 0, 0)
|
||||
#endif
|
||||
|
||||
#define PANIC(fmt, a...) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
|
||||
|
||||
|
@ -88,6 +108,12 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
spl_assert("VERIFY(" #cond ") failed\n", \
|
||||
__FILE__, __FUNCTION__, __LINE__))
|
||||
|
||||
#define VERIFYF(cond, str, ...) do { \
|
||||
if (unlikely(!cond)) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY(" #cond ") failed " str "\n", __VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
||||
const boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||
const boolean_t _verify3_right = (boolean_t)(RIGHT); \
|
||||
|
@ -150,6 +176,84 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
(void *)_verify0_right); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Note that you should not put any operations you want to always happen
|
||||
* in the print section for ASSERTs unless you only want them to run on
|
||||
* debug builds!
|
||||
* e.g. ASSERT3UF(2, <, 3, "%s", foo(x)), foo(x) won't run on non-debug
|
||||
* builds.
|
||||
*/
|
||||
|
||||
#define VERIFY3BF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
const boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||
const boolean_t _verify3_right = (boolean_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%d " #OP " %d) " STR "\n", \
|
||||
(boolean_t)(_verify3_left), \
|
||||
(boolean_t)(_verify3_right), \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3SF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
const int64_t _verify3_left = (int64_t)(LEFT); \
|
||||
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%lld " #OP " %lld) " STR "\n", \
|
||||
(long long)(_verify3_left), \
|
||||
(long long)(_verify3_right), \
|
||||
__VA_ARGS); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3UF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
const uint64_t _verify3_left = (uint64_t)(LEFT); \
|
||||
const uint64_t _verify3_right = (uint64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%llu " #OP " %llu) " STR "\n", \
|
||||
(unsigned long long)(_verify3_left), \
|
||||
(unsigned long long)(_verify3_right), \
|
||||
__VA_ARGS); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3PF(LEFT, OP, RIGHT, STR, ...) do { \
|
||||
const uintptr_t _verify3_left = (uintptr_t)(LEFT); \
|
||||
const uintptr_t _verify3_right = (uintptr_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%px " #OP " %px) " STR "\n", \
|
||||
(void *) (_verify3_left), \
|
||||
(void *) (_verify3_right), \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY0PF(RIGHT, STR, ...) do { \
|
||||
const uintptr_t _verify3_left = (uintptr_t)(0); \
|
||||
const uintptr_t _verify3_right = (uintptr_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left == _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY0(0 == " #RIGHT ") " \
|
||||
"failed (0 == %px) " STR "\n", \
|
||||
(long long) (_verify3_right), \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY0F(RIGHT, STR, ...) do { \
|
||||
const int64_t _verify3_left = (int64_t)(0); \
|
||||
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left == _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY0(0 == " #RIGHT ") " \
|
||||
"failed (0 == %lld) " STR "\n", \
|
||||
(long long) (_verify3_right), \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY_IMPLY(A, B) \
|
||||
((void)(likely((!(A)) || (B)) || \
|
||||
spl_assert("(" #A ") implies (" #B ")", \
|
||||
|
@ -176,6 +280,13 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
|
||||
#define ASSERT0(x) ((void) sizeof ((uintptr_t)(x)))
|
||||
#define ASSERT0P(x) ((void) sizeof ((uintptr_t)(x)))
|
||||
#define ASSERT3BF(x, y, z, str, ...) ASSERT3B(x, y, z)
|
||||
#define ASSERT3SF(x, y, z, str, ...) ASSERT3S(x, y, z)
|
||||
#define ASSERT3UF(x, y, z, str, ...) ASSERT3U(x, y, z)
|
||||
#define ASSERT3PF(x, y, z, str, ...) ASSERT3P(x, y, z)
|
||||
#define ASSERT0PF(x, str, ...) ASSERT0P(x)
|
||||
#define ASSERT0F(x, str, ...) ASSERT0(x)
|
||||
#define ASSERTF(x, str, ...) ASSERT(x)
|
||||
#define IMPLY(A, B) \
|
||||
((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))
|
||||
#define EQUIV(A, B) \
|
||||
|
@ -192,6 +303,13 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
#define ASSERT3P VERIFY3P
|
||||
#define ASSERT0 VERIFY0
|
||||
#define ASSERT0P VERIFY0P
|
||||
#define ASSERT3BF VERIFY3BF
|
||||
#define ASSERT3SF VERIFY3SF
|
||||
#define ASSERT3UF VERIFY3UF
|
||||
#define ASSERT3PF VERIFY3PF
|
||||
#define ASSERT0PF VERIFY0PF
|
||||
#define ASSERT0F VERIFY0F
|
||||
#define ASSERTF VERIFYF
|
||||
#define ASSERT VERIFY
|
||||
#define IMPLY VERIFY_IMPLY
|
||||
#define EQUIV VERIFY_EQUIV
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
|
||||
* Copyright (C) 2007 The Regents of the University of California.
|
||||
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
||||
* Written by Brian Behlendorf <behlendorf1@llnl.gov>.
|
||||
* UCRL-CODE-235197
|
||||
*
|
||||
* This file is part of the SPL, Solaris Porting Layer.
|
||||
*
|
||||
* The SPL is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SPL is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with the SPL. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SPL_DKIO_H
|
||||
#define _SPL_DKIO_H
|
||||
|
||||
#define DFL_SZ(num_exts) \
|
||||
(sizeof (dkioc_free_list_t) + (num_exts - 1) * 16)
|
||||
|
||||
#define DKIOC (0x04 << 8)
|
||||
#define DKIOCFLUSHWRITECACHE (DKIOC|34) /* flush cache to phys medium */
|
||||
|
||||
/*
|
||||
* ioctl to free space (e.g. SCSI UNMAP) off a disk.
|
||||
* Pass a dkioc_free_list_t containing a list of extents to be freed.
|
||||
*/
|
||||
#define DKIOCFREE (DKIOC|50)
|
||||
|
||||
#endif /* _SPL_DKIO_H */
|
|
@ -30,9 +30,6 @@
|
|||
#include <linux/sched/signal.h>
|
||||
#endif
|
||||
|
||||
#define FORREAL 0 /* Usual side-effects */
|
||||
#define JUSTLOOKING 1 /* Don't stop the process */
|
||||
|
||||
extern int issig(int why);
|
||||
extern int issig(void);
|
||||
|
||||
#endif /* SPL_SIGNAL_H */
|
||||
|
|
|
@ -159,7 +159,8 @@ makedev(unsigned int major, unsigned int minor)
|
|||
/*
|
||||
* Compatibility macros/typedefs needed for Solaris -> Linux port
|
||||
*/
|
||||
#define P2ALIGN(x, align) ((x) & -(align))
|
||||
// Deprecated. Use P2ALIGN_TYPED instead.
|
||||
// #define P2ALIGN(x, align) ((x) & -(align))
|
||||
#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1)
|
||||
#define P2ROUNDUP(x, align) ((((x) - 1) | ((align) - 1)) + 1)
|
||||
#define P2PHASE(x, align) ((x) & ((align) - 1))
|
||||
|
|
|
@ -38,7 +38,9 @@ typedef unsigned long ulong_t;
|
|||
typedef unsigned long long u_longlong_t;
|
||||
typedef long long longlong_t;
|
||||
|
||||
#ifndef HAVE_KERNEL_INTPTR_T
|
||||
typedef long intptr_t;
|
||||
#endif
|
||||
typedef unsigned long long rlim64_t;
|
||||
|
||||
typedef struct task_struct kthread_t;
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
/* ZIO macros */
|
||||
#define ZIO_TP_STRUCT_ENTRY \
|
||||
__field(zio_type_t, zio_type) \
|
||||
__field(int, zio_cmd) \
|
||||
__field(zio_priority_t, zio_priority) \
|
||||
__field(uint64_t, zio_size) \
|
||||
__field(uint64_t, zio_orig_size) \
|
||||
|
@ -61,7 +60,6 @@
|
|||
|
||||
#define ZIO_TP_FAST_ASSIGN \
|
||||
__entry->zio_type = zio->io_type; \
|
||||
__entry->zio_cmd = zio->io_cmd; \
|
||||
__entry->zio_priority = zio->io_priority; \
|
||||
__entry->zio_size = zio->io_size; \
|
||||
__entry->zio_orig_size = zio->io_orig_size; \
|
||||
|
@ -90,7 +88,7 @@
|
|||
__entry->zp_dedup_verify = zio->io_prop.zp_dedup_verify;
|
||||
|
||||
#define ZIO_TP_PRINTK_FMT \
|
||||
"zio { type %u cmd %i prio %u size %llu orig_size %llu " \
|
||||
"zio { type %u prio %u size %llu orig_size %llu " \
|
||||
"offset %llu timestamp %llu delta %llu delay %llu " \
|
||||
"flags 0x%llx stage 0x%x pipeline 0x%x orig_flags 0x%llx " \
|
||||
"orig_stage 0x%x orig_pipeline 0x%x reexecute %u " \
|
||||
|
@ -98,7 +96,7 @@
|
|||
"type %u level %u copies %u dedup %u dedup_verify %u nopwrite %u } }"
|
||||
|
||||
#define ZIO_TP_PRINTK_ARGS \
|
||||
__entry->zio_type, __entry->zio_cmd, __entry->zio_priority, \
|
||||
__entry->zio_type, __entry->zio_priority, \
|
||||
__entry->zio_size, __entry->zio_orig_size, __entry->zio_offset, \
|
||||
__entry->zio_timestamp, __entry->zio_delta, __entry->zio_delay, \
|
||||
__entry->zio_flags, __entry->zio_stage, __entry->zio_pipeline, \
|
||||
|
|
|
@ -51,12 +51,6 @@ typedef struct crypto_mechanism {
|
|||
size_t cm_param_len; /* mech. parameter len */
|
||||
} crypto_mechanism_t;
|
||||
|
||||
/* CK_AES_CTR_PARAMS provides parameters to the CKM_AES_CTR mechanism */
|
||||
typedef struct CK_AES_CTR_PARAMS {
|
||||
ulong_t ulCounterBits;
|
||||
uint8_t cb[16];
|
||||
} CK_AES_CTR_PARAMS;
|
||||
|
||||
/* CK_AES_CCM_PARAMS provides parameters to the CKM_AES_CCM mechanism */
|
||||
typedef struct CK_AES_CCM_PARAMS {
|
||||
ulong_t ulMACSize;
|
||||
|
@ -77,13 +71,6 @@ typedef struct CK_AES_GCM_PARAMS {
|
|||
ulong_t ulTagBits;
|
||||
} CK_AES_GCM_PARAMS;
|
||||
|
||||
/* CK_AES_GMAC_PARAMS provides parameters to the CKM_AES_GMAC mechanism */
|
||||
typedef struct CK_AES_GMAC_PARAMS {
|
||||
uchar_t *pIv;
|
||||
uchar_t *pAAD;
|
||||
ulong_t ulAADLen;
|
||||
} CK_AES_GMAC_PARAMS;
|
||||
|
||||
/*
|
||||
* The measurement unit bit flag for a mechanism's minimum or maximum key size.
|
||||
* The unit are mechanism dependent. It can be in bits or in bytes.
|
||||
|
@ -92,23 +79,9 @@ typedef uint32_t crypto_keysize_unit_t;
|
|||
|
||||
|
||||
/* Mechanisms supported out-of-the-box */
|
||||
#define SUN_CKM_SHA256 "CKM_SHA256"
|
||||
#define SUN_CKM_SHA256_HMAC "CKM_SHA256_HMAC"
|
||||
#define SUN_CKM_SHA256_HMAC_GENERAL "CKM_SHA256_HMAC_GENERAL"
|
||||
#define SUN_CKM_SHA384 "CKM_SHA384"
|
||||
#define SUN_CKM_SHA384_HMAC "CKM_SHA384_HMAC"
|
||||
#define SUN_CKM_SHA384_HMAC_GENERAL "CKM_SHA384_HMAC_GENERAL"
|
||||
#define SUN_CKM_SHA512 "CKM_SHA512"
|
||||
#define SUN_CKM_SHA512_HMAC "CKM_SHA512_HMAC"
|
||||
#define SUN_CKM_SHA512_HMAC_GENERAL "CKM_SHA512_HMAC_GENERAL"
|
||||
#define SUN_CKM_SHA512_224 "CKM_SHA512_224"
|
||||
#define SUN_CKM_SHA512_256 "CKM_SHA512_256"
|
||||
#define SUN_CKM_AES_CBC "CKM_AES_CBC"
|
||||
#define SUN_CKM_AES_ECB "CKM_AES_ECB"
|
||||
#define SUN_CKM_AES_CTR "CKM_AES_CTR"
|
||||
#define SUN_CKM_AES_CCM "CKM_AES_CCM"
|
||||
#define SUN_CKM_AES_GCM "CKM_AES_GCM"
|
||||
#define SUN_CKM_AES_GMAC "CKM_AES_GMAC"
|
||||
|
||||
/* Data arguments of cryptographic operations */
|
||||
|
||||
|
|
|
@ -32,9 +32,6 @@ int aes_mod_fini(void);
|
|||
int sha2_mod_init(void);
|
||||
int sha2_mod_fini(void);
|
||||
|
||||
int skein_mod_init(void);
|
||||
int skein_mod_fini(void);
|
||||
|
||||
int icp_init(void);
|
||||
void icp_fini(void);
|
||||
|
||||
|
|
|
@ -173,6 +173,7 @@ typedef struct dsl_scan {
|
|||
dsl_scan_phys_t scn_phys; /* on disk representation of scan */
|
||||
dsl_scan_phys_t scn_phys_cached;
|
||||
avl_tree_t scn_queue; /* queue of datasets to scan */
|
||||
kmutex_t scn_queue_lock; /* serializes scn_queue inserts */
|
||||
uint64_t scn_queues_pending; /* outstanding data to issue */
|
||||
/* members needed for syncing error scrub status to disk */
|
||||
dsl_errorscrub_phys_t errorscrub_phys;
|
||||
|
|
|
@ -1094,11 +1094,17 @@ typedef enum zio_type {
|
|||
ZIO_TYPE_WRITE,
|
||||
ZIO_TYPE_FREE,
|
||||
ZIO_TYPE_CLAIM,
|
||||
ZIO_TYPE_IOCTL,
|
||||
ZIO_TYPE_FLUSH,
|
||||
ZIO_TYPE_TRIM,
|
||||
ZIO_TYPES
|
||||
} zio_type_t;
|
||||
|
||||
/*
|
||||
* Compatibility: _IOCTL was renamed to _FLUSH; keep the old name available to
|
||||
* user programs.
|
||||
*/
|
||||
#define ZIO_TYPE_IOCTL ZIO_TYPE_FLUSH
|
||||
|
||||
/*
|
||||
* Pool statistics. Note: all fields should be 64-bit because this
|
||||
* is passed between kernel and userland as an nvlist uint64 array.
|
||||
|
|
|
@ -82,12 +82,15 @@ int multilist_is_empty(multilist_t *);
|
|||
unsigned int multilist_get_num_sublists(multilist_t *);
|
||||
unsigned int multilist_get_random_index(multilist_t *);
|
||||
|
||||
multilist_sublist_t *multilist_sublist_lock(multilist_t *, unsigned int);
|
||||
void multilist_sublist_lock(multilist_sublist_t *);
|
||||
multilist_sublist_t *multilist_sublist_lock_idx(multilist_t *, unsigned int);
|
||||
multilist_sublist_t *multilist_sublist_lock_obj(multilist_t *, void *);
|
||||
void multilist_sublist_unlock(multilist_sublist_t *);
|
||||
|
||||
void multilist_sublist_insert_head(multilist_sublist_t *, void *);
|
||||
void multilist_sublist_insert_tail(multilist_sublist_t *, void *);
|
||||
void multilist_sublist_insert_after(multilist_sublist_t *, void *, void *);
|
||||
void multilist_sublist_insert_before(multilist_sublist_t *, void *, void *);
|
||||
void multilist_sublist_move_forward(multilist_sublist_t *mls, void *obj);
|
||||
void multilist_sublist_remove(multilist_sublist_t *, void *);
|
||||
int multilist_sublist_is_empty(multilist_sublist_t *);
|
||||
|
|
|
@ -86,30 +86,13 @@ typedef struct {
|
|||
|
||||
/* SHA2 algorithm types */
|
||||
typedef enum sha2_mech_type {
|
||||
SHA256_MECH_INFO_TYPE, /* SUN_CKM_SHA256 */
|
||||
SHA256_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC */
|
||||
SHA256_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC_GENERAL */
|
||||
SHA384_MECH_INFO_TYPE, /* SUN_CKM_SHA384 */
|
||||
SHA384_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC */
|
||||
SHA384_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC_GENERAL */
|
||||
SHA512_MECH_INFO_TYPE, /* SUN_CKM_SHA512 */
|
||||
SHA512_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC */
|
||||
SHA512_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC_GENERAL */
|
||||
SHA512_224_MECH_INFO_TYPE, /* SUN_CKM_SHA512_224 */
|
||||
SHA512_256_MECH_INFO_TYPE /* SUN_CKM_SHA512_256 */
|
||||
} sha2_mech_type_t;
|
||||
|
||||
#define SHA256 0
|
||||
#define SHA256_HMAC 1
|
||||
#define SHA256_HMAC_GEN 2
|
||||
#define SHA384 3
|
||||
#define SHA384_HMAC 4
|
||||
#define SHA384_HMAC_GEN 5
|
||||
#define SHA512 6
|
||||
#define SHA512_HMAC 7
|
||||
#define SHA512_HMAC_GEN 8
|
||||
#define SHA512_224 9
|
||||
#define SHA512_256 10
|
||||
/* Not true KCF mech types; used by direct callers to SHA2Init */
|
||||
SHA256,
|
||||
SHA512,
|
||||
SHA512_256,
|
||||
} sha2_mech_type_t;
|
||||
|
||||
/* SHA2 Init function */
|
||||
extern void SHA2Init(int algotype, SHA2_CTX *ctx);
|
||||
|
|
|
@ -152,25 +152,16 @@ typedef struct skein_param {
|
|||
|
||||
/* Module definitions */
|
||||
#ifdef SKEIN_MODULE_IMPL
|
||||
#define CKM_SKEIN_256 "CKM_SKEIN_256"
|
||||
#define CKM_SKEIN_512 "CKM_SKEIN_512"
|
||||
#define CKM_SKEIN1024 "CKM_SKEIN1024"
|
||||
#define CKM_SKEIN_256_MAC "CKM_SKEIN_256_MAC"
|
||||
#define CKM_SKEIN_512_MAC "CKM_SKEIN_512_MAC"
|
||||
#define CKM_SKEIN1024_MAC "CKM_SKEIN1024_MAC"
|
||||
|
||||
typedef enum skein_mech_type {
|
||||
SKEIN_256_MECH_INFO_TYPE,
|
||||
SKEIN_512_MECH_INFO_TYPE,
|
||||
SKEIN1024_MECH_INFO_TYPE,
|
||||
SKEIN_256_MAC_MECH_INFO_TYPE,
|
||||
SKEIN_512_MAC_MECH_INFO_TYPE,
|
||||
SKEIN1024_MAC_MECH_INFO_TYPE
|
||||
} skein_mech_type_t;
|
||||
|
||||
#define VALID_SKEIN_DIGEST_MECH(__mech) \
|
||||
((int)(__mech) >= SKEIN_256_MECH_INFO_TYPE && \
|
||||
(__mech) <= SKEIN1024_MECH_INFO_TYPE)
|
||||
#define VALID_SKEIN_MAC_MECH(__mech) \
|
||||
((int)(__mech) >= SKEIN_256_MAC_MECH_INFO_TYPE && \
|
||||
(__mech) <= SKEIN1024_MAC_MECH_INFO_TYPE)
|
||||
|
|
|
@ -770,7 +770,7 @@ extern int bpobj_enqueue_free_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx);
|
|||
|
||||
#define SPA_ASYNC_CONFIG_UPDATE 0x01
|
||||
#define SPA_ASYNC_REMOVE 0x02
|
||||
#define SPA_ASYNC_PROBE 0x04
|
||||
#define SPA_ASYNC_FAULT_VDEV 0x04
|
||||
#define SPA_ASYNC_RESILVER_DONE 0x08
|
||||
#define SPA_ASYNC_RESILVER 0x10
|
||||
#define SPA_ASYNC_AUTOEXPAND 0x20
|
||||
|
@ -829,10 +829,14 @@ extern uint_t zfs_sync_pass_deferred_free;
|
|||
/* spa sync taskqueues */
|
||||
taskq_t *spa_sync_tq_create(spa_t *spa, const char *name);
|
||||
void spa_sync_tq_destroy(spa_t *spa);
|
||||
uint_t spa_acq_allocator(spa_t *spa);
|
||||
void spa_rel_allocator(spa_t *spa, uint_t allocator);
|
||||
void spa_select_allocator(zio_t *zio);
|
||||
|
||||
/* spa namespace global mutex */
|
||||
extern kmutex_t spa_namespace_lock;
|
||||
extern avl_tree_t spa_namespace_avl;
|
||||
extern kcondvar_t spa_namespace_cv;
|
||||
|
||||
/*
|
||||
* SPA configuration functions in spa_config.c
|
||||
|
@ -1121,6 +1125,8 @@ extern uint32_t spa_get_hostid(spa_t *spa);
|
|||
extern void spa_activate_allocation_classes(spa_t *, dmu_tx_t *);
|
||||
extern boolean_t spa_livelist_delete_check(spa_t *spa);
|
||||
|
||||
extern boolean_t spa_mmp_remote_host_activity(spa_t *spa);
|
||||
|
||||
extern spa_mode_t spa_mode(spa_t *spa);
|
||||
extern uint64_t zfs_strtonum(const char *str, char **nptr);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2019 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2011, 2024 by Delphix. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
||||
* Copyright 2013 Saso Kiselkov. All rights reserved.
|
||||
|
@ -63,6 +63,12 @@ typedef struct spa_alloc {
|
|||
avl_tree_t spaa_tree;
|
||||
} ____cacheline_aligned spa_alloc_t;
|
||||
|
||||
typedef struct spa_allocs_use {
|
||||
kmutex_t sau_lock;
|
||||
uint_t sau_rotor;
|
||||
boolean_t sau_inuse[];
|
||||
} spa_allocs_use_t;
|
||||
|
||||
typedef struct spa_error_entry {
|
||||
zbookmark_phys_t se_bookmark;
|
||||
char *se_name;
|
||||
|
@ -192,7 +198,7 @@ typedef struct spa_taskqs {
|
|||
/* one for each thread in the spa sync taskq */
|
||||
typedef struct spa_syncthread_info {
|
||||
kthread_t *sti_thread;
|
||||
taskq_t *sti_wr_iss_tq; /* assigned wr_iss taskq */
|
||||
uint_t sti_allocator;
|
||||
} spa_syncthread_info_t;
|
||||
|
||||
typedef enum spa_all_vdev_zap_action {
|
||||
|
@ -237,6 +243,8 @@ struct spa {
|
|||
dsl_pool_t *spa_dsl_pool;
|
||||
boolean_t spa_is_initializing; /* true while opening pool */
|
||||
boolean_t spa_is_exporting; /* true while exporting pool */
|
||||
kthread_t *spa_export_thread; /* valid during pool export */
|
||||
kthread_t *spa_load_thread; /* loading, no namespace lock */
|
||||
metaslab_class_t *spa_normal_class; /* normal data class */
|
||||
metaslab_class_t *spa_log_class; /* intent log data class */
|
||||
metaslab_class_t *spa_embedded_log_class; /* log on normal vdevs */
|
||||
|
@ -269,6 +277,7 @@ struct spa {
|
|||
* allocation performance in write-heavy workloads.
|
||||
*/
|
||||
spa_alloc_t *spa_allocs;
|
||||
spa_allocs_use_t *spa_allocs_use;
|
||||
int spa_alloc_count;
|
||||
int spa_active_allocator; /* selectable allocator */
|
||||
|
||||
|
@ -470,10 +479,8 @@ struct spa {
|
|||
extern char *spa_config_path;
|
||||
extern const char *zfs_deadman_failmode;
|
||||
extern uint_t spa_slop_shift;
|
||||
extern void spa_taskq_dispatch_ent(spa_t *spa, zio_type_t t, zio_taskq_type_t q,
|
||||
task_func_t *func, void *arg, uint_t flags, taskq_ent_t *ent, zio_t *zio);
|
||||
extern void spa_taskq_dispatch_sync(spa_t *, zio_type_t t, zio_taskq_type_t q,
|
||||
task_func_t *func, void *arg, uint_t flags);
|
||||
extern void spa_taskq_dispatch(spa_t *spa, zio_type_t t, zio_taskq_type_t q,
|
||||
task_func_t *func, zio_t *zio, boolean_t cutinline);
|
||||
extern void spa_load_spares(spa_t *spa);
|
||||
extern void spa_load_l2cache(spa_t *spa);
|
||||
extern sysevent_t *spa_event_create(spa_t *spa, vdev_t *vd, nvlist_t *hist_nvl,
|
||||
|
|
|
@ -50,20 +50,20 @@ extern "C" {
|
|||
#define MMP_SEQ_VALID_BIT 0x02
|
||||
#define MMP_FAIL_INT_VALID_BIT 0x04
|
||||
|
||||
#define MMP_VALID(ubp) (ubp->ub_magic == UBERBLOCK_MAGIC && \
|
||||
ubp->ub_mmp_magic == MMP_MAGIC)
|
||||
#define MMP_INTERVAL_VALID(ubp) (MMP_VALID(ubp) && (ubp->ub_mmp_config & \
|
||||
#define MMP_VALID(ubp) ((ubp)->ub_magic == UBERBLOCK_MAGIC && \
|
||||
(ubp)->ub_mmp_magic == MMP_MAGIC)
|
||||
#define MMP_INTERVAL_VALID(ubp) (MMP_VALID(ubp) && ((ubp)->ub_mmp_config & \
|
||||
MMP_INTERVAL_VALID_BIT))
|
||||
#define MMP_SEQ_VALID(ubp) (MMP_VALID(ubp) && (ubp->ub_mmp_config & \
|
||||
#define MMP_SEQ_VALID(ubp) (MMP_VALID(ubp) && ((ubp)->ub_mmp_config & \
|
||||
MMP_SEQ_VALID_BIT))
|
||||
#define MMP_FAIL_INT_VALID(ubp) (MMP_VALID(ubp) && (ubp->ub_mmp_config & \
|
||||
#define MMP_FAIL_INT_VALID(ubp) (MMP_VALID(ubp) && ((ubp)->ub_mmp_config & \
|
||||
MMP_FAIL_INT_VALID_BIT))
|
||||
|
||||
#define MMP_INTERVAL(ubp) ((ubp->ub_mmp_config & 0x00000000FFFFFF00) \
|
||||
#define MMP_INTERVAL(ubp) (((ubp)->ub_mmp_config & 0x00000000FFFFFF00) \
|
||||
>> 8)
|
||||
#define MMP_SEQ(ubp) ((ubp->ub_mmp_config & 0x0000FFFF00000000) \
|
||||
#define MMP_SEQ(ubp) (((ubp)->ub_mmp_config & 0x0000FFFF00000000) \
|
||||
>> 32)
|
||||
#define MMP_FAIL_INT(ubp) ((ubp->ub_mmp_config & 0xFFFF000000000000) \
|
||||
#define MMP_FAIL_INT(ubp) (((ubp)->ub_mmp_config & 0xFFFF000000000000) \
|
||||
>> 48)
|
||||
|
||||
#define MMP_INTERVAL_SET(write) \
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include <sys/nvpair.h>
|
||||
#include <sys/space_map.h>
|
||||
#include <sys/vdev.h>
|
||||
#include <sys/dkio.h>
|
||||
#include <sys/uberblock_impl.h>
|
||||
#include <sys/vdev_indirect_mapping.h>
|
||||
#include <sys/vdev_indirect_births.h>
|
||||
|
@ -274,7 +273,7 @@ struct vdev {
|
|||
txg_list_t vdev_dtl_list; /* per-txg dirty DTL lists */
|
||||
txg_node_t vdev_txg_node; /* per-txg dirty vdev linkage */
|
||||
boolean_t vdev_remove_wanted; /* async remove wanted? */
|
||||
boolean_t vdev_probe_wanted; /* async probe wanted? */
|
||||
boolean_t vdev_fault_wanted; /* async faulted wanted? */
|
||||
list_node_t vdev_config_dirty_node; /* config dirty list */
|
||||
list_node_t vdev_state_dirty_node; /* state dirty list */
|
||||
uint64_t vdev_deflate_ratio; /* deflation ratio (x512) */
|
||||
|
|
|
@ -228,9 +228,9 @@ typedef pthread_t kthread_t;
|
|||
|
||||
#define thread_create_named(name, stk, stksize, func, arg, len, \
|
||||
pp, state, pri) \
|
||||
zk_thread_create(func, arg, stksize, state)
|
||||
zk_thread_create(name, func, arg, stksize, state)
|
||||
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
|
||||
zk_thread_create(func, arg, stksize, state)
|
||||
zk_thread_create(#func, func, arg, stksize, state)
|
||||
#define thread_exit() pthread_exit(NULL)
|
||||
#define thread_join(t) pthread_join((pthread_t)(t), NULL)
|
||||
|
||||
|
@ -246,11 +246,10 @@ extern struct proc p0;
|
|||
|
||||
#define PS_NONE -1
|
||||
|
||||
extern kthread_t *zk_thread_create(void (*func)(void *), void *arg,
|
||||
size_t stksize, int state);
|
||||
extern kthread_t *zk_thread_create(const char *name, void (*func)(void *),
|
||||
void *arg, size_t stksize, int state);
|
||||
|
||||
#define issig(why) (FALSE)
|
||||
#define ISSIG(thr, why) (FALSE)
|
||||
#define issig() (FALSE)
|
||||
|
||||
#define KPREEMPT_SYNC (-1)
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ extern void zfs_dbgmsg_fini(void);
|
|||
|
||||
#ifndef _KERNEL
|
||||
extern int dprintf_find_string(const char *string);
|
||||
extern void zfs_dbgmsg_print(const char *tag);
|
||||
extern void zfs_dbgmsg_print(int fd, const char *tag);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, 2024 by Delphix. All rights reserved.
|
||||
* Copyright 2016 RackTop Systems.
|
||||
* Copyright (c) 2017, Intel Corporation.
|
||||
*/
|
||||
|
@ -454,6 +454,8 @@ typedef enum zinject_type {
|
|||
ZINJECT_PANIC,
|
||||
ZINJECT_DELAY_IO,
|
||||
ZINJECT_DECRYPT_FAULT,
|
||||
ZINJECT_DELAY_IMPORT,
|
||||
ZINJECT_DELAY_EXPORT,
|
||||
} zinject_type_t;
|
||||
|
||||
typedef struct zfs_share {
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2020 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, 2024 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||
* Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||
* Copyright (c) 2019, Allan Jude
|
||||
* Copyright (c) 2019, Klara Inc.
|
||||
* Copyright (c) 2019, 2023, 2024, Klara Inc.
|
||||
* Copyright (c) 2019-2020, Michael Niewöhner
|
||||
*/
|
||||
|
||||
|
@ -451,7 +451,6 @@ struct zio {
|
|||
zio_type_t io_type;
|
||||
enum zio_child io_child_type;
|
||||
enum trim_flag io_trim_flags;
|
||||
int io_cmd;
|
||||
zio_priority_t io_priority;
|
||||
uint8_t io_reexecute;
|
||||
uint8_t io_state[ZIO_WAIT_TYPES];
|
||||
|
@ -529,9 +528,6 @@ struct zio {
|
|||
|
||||
/* Taskq dispatching state */
|
||||
taskq_ent_t io_tqent;
|
||||
|
||||
/* write issue taskq selection, based upon sync thread */
|
||||
taskq_t *io_wr_iss_tq;
|
||||
};
|
||||
|
||||
enum blk_verify_flag {
|
||||
|
@ -579,9 +575,6 @@ extern zio_t *zio_claim(zio_t *pio, spa_t *spa, uint64_t txg,
|
|||
const blkptr_t *bp,
|
||||
zio_done_func_t *done, void *priv, zio_flag_t flags);
|
||||
|
||||
extern zio_t *zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd,
|
||||
zio_done_func_t *done, void *priv, zio_flag_t flags);
|
||||
|
||||
extern zio_t *zio_trim(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
|
||||
zio_done_func_t *done, void *priv, zio_priority_t priority,
|
||||
zio_flag_t flags, enum trim_flag trim_flags);
|
||||
|
@ -690,6 +683,8 @@ extern int zio_handle_device_injections(vdev_t *vd, zio_t *zio, int err1,
|
|||
extern int zio_handle_label_injection(zio_t *zio, int error);
|
||||
extern void zio_handle_ignored_writes(zio_t *zio);
|
||||
extern hrtime_t zio_handle_io_delay(zio_t *zio);
|
||||
extern void zio_handle_import_delay(spa_t *spa, hrtime_t elapsed);
|
||||
extern void zio_handle_export_delay(spa_t *spa, hrtime_t elapsed);
|
||||
|
||||
/*
|
||||
* Checksum ereport functions
|
||||
|
|
|
@ -40,7 +40,7 @@ extern "C" {
|
|||
*
|
||||
* The ZFS I/O pipeline is comprised of various stages which are defined
|
||||
* in the zio_stage enum below. The individual stages are used to construct
|
||||
* these basic I/O operations: Read, Write, Free, Claim, Ioctl and Trim.
|
||||
* these basic I/O operations: Read, Write, Free, Claim, Flush and Trim.
|
||||
*
|
||||
* I/O operations: (XXX - provide detail for each of the operations)
|
||||
*
|
||||
|
@ -48,7 +48,7 @@ extern "C" {
|
|||
* Write:
|
||||
* Free:
|
||||
* Claim:
|
||||
* Ioctl:
|
||||
* Flush:
|
||||
* Trim:
|
||||
*
|
||||
* Although the most common pipeline are used by the basic I/O operations
|
||||
|
@ -122,7 +122,7 @@ extern "C" {
|
|||
* zio pipeline stage definitions
|
||||
*/
|
||||
enum zio_stage {
|
||||
ZIO_STAGE_OPEN = 1 << 0, /* RWFCIT */
|
||||
ZIO_STAGE_OPEN = 1 << 0, /* RWFCXT */
|
||||
|
||||
ZIO_STAGE_READ_BP_INIT = 1 << 1, /* R----- */
|
||||
ZIO_STAGE_WRITE_BP_INIT = 1 << 2, /* -W---- */
|
||||
|
@ -150,15 +150,15 @@ enum zio_stage {
|
|||
ZIO_STAGE_DVA_FREE = 1 << 18, /* --F--- */
|
||||
ZIO_STAGE_DVA_CLAIM = 1 << 19, /* ---C-- */
|
||||
|
||||
ZIO_STAGE_READY = 1 << 20, /* RWFCIT */
|
||||
ZIO_STAGE_READY = 1 << 20, /* RWFCXT */
|
||||
|
||||
ZIO_STAGE_VDEV_IO_START = 1 << 21, /* RW--IT */
|
||||
ZIO_STAGE_VDEV_IO_DONE = 1 << 22, /* RW--IT */
|
||||
ZIO_STAGE_VDEV_IO_ASSESS = 1 << 23, /* RW--IT */
|
||||
ZIO_STAGE_VDEV_IO_START = 1 << 21, /* RW--XT */
|
||||
ZIO_STAGE_VDEV_IO_DONE = 1 << 22, /* RW--XT */
|
||||
ZIO_STAGE_VDEV_IO_ASSESS = 1 << 23, /* RW--XT */
|
||||
|
||||
ZIO_STAGE_CHECKSUM_VERIFY = 1 << 24, /* R----- */
|
||||
|
||||
ZIO_STAGE_DONE = 1 << 25 /* RWFCIT */
|
||||
ZIO_STAGE_DONE = 1 << 25 /* RWFCXT */
|
||||
};
|
||||
|
||||
#define ZIO_ROOT_PIPELINE \
|
||||
|
@ -259,7 +259,7 @@ enum zio_stage {
|
|||
(ZIO_INTERLOCK_STAGES | \
|
||||
ZIO_STAGE_DVA_CLAIM)
|
||||
|
||||
#define ZIO_IOCTL_PIPELINE \
|
||||
#define ZIO_FLUSH_PIPELINE \
|
||||
(ZIO_INTERLOCK_STAGES | \
|
||||
ZIO_VDEV_IO_STAGES)
|
||||
|
||||
|
|
|
@ -1175,8 +1175,8 @@ efi_use_whole_disk(int fd)
|
|||
* (for performance reasons). The alignment should match the
|
||||
* alignment used by the "zpool_label_disk" function.
|
||||
*/
|
||||
limit = P2ALIGN(efi_label->efi_last_lba - nblocks - EFI_MIN_RESV_SIZE,
|
||||
PARTITION_END_ALIGNMENT);
|
||||
limit = P2ALIGN_TYPED(efi_label->efi_last_lba - nblocks -
|
||||
EFI_MIN_RESV_SIZE, PARTITION_END_ALIGNMENT, diskaddr_t);
|
||||
if (data_start + data_size != limit || resv_start != limit)
|
||||
sync_needed = B_TRUE;
|
||||
|
||||
|
|
|
@ -18,13 +18,10 @@ nodist_libicp_la_SOURCES = \
|
|||
module/icp/algs/blake3/blake3_impl.c \
|
||||
module/icp/algs/edonr/edonr.c \
|
||||
module/icp/algs/modes/modes.c \
|
||||
module/icp/algs/modes/cbc.c \
|
||||
module/icp/algs/modes/gcm_generic.c \
|
||||
module/icp/algs/modes/gcm_pclmulqdq.c \
|
||||
module/icp/algs/modes/gcm.c \
|
||||
module/icp/algs/modes/ctr.c \
|
||||
module/icp/algs/modes/ccm.c \
|
||||
module/icp/algs/modes/ecb.c \
|
||||
module/icp/algs/sha2/sha2_generic.c \
|
||||
module/icp/algs/sha2/sha256_impl.c \
|
||||
module/icp/algs/sha2/sha512_impl.c \
|
||||
|
@ -34,7 +31,6 @@ nodist_libicp_la_SOURCES = \
|
|||
module/icp/illumos-crypto.c \
|
||||
module/icp/io/aes.c \
|
||||
module/icp/io/sha2_mod.c \
|
||||
module/icp/io/skein_mod.c \
|
||||
module/icp/core/kcf_sched.c \
|
||||
module/icp/core/kcf_prov_lib.c \
|
||||
module/icp/core/kcf_callprov.c \
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
<elf-symbol name='fnvpair_value_uint64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='fnvpair_value_uint8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_assertf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_backtrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_set_assert_ok' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='nv_alloc_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='nv_alloc_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
@ -1156,6 +1157,11 @@
|
|||
<parameter type-id='80f4b756'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='strchr' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='strcspn' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='80f4b756'/>
|
||||
|
@ -2041,9 +2047,77 @@
|
|||
</function-type>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/assert.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='320' id='36c46961'>
|
||||
<subrange length='40' type-id='7359adad' id='8f80b239'/>
|
||||
</array-type-def>
|
||||
<union-decl name='pthread_mutex_t' size-in-bits='320' naming-typedef-id='7a6844eb' visibility='default' id='70681f9b'>
|
||||
<data-member access='public'>
|
||||
<var-decl name='__data' type-id='4c734837' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public'>
|
||||
<var-decl name='__size' type-id='36c46961' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public'>
|
||||
<var-decl name='__align' type-id='bd54fe1a' visibility='default'/>
|
||||
</data-member>
|
||||
</union-decl>
|
||||
<typedef-decl name='pthread_mutex_t' type-id='70681f9b' id='7a6844eb'/>
|
||||
<class-decl name='__pthread_mutex_s' size-in-bits='320' is-struct='yes' visibility='default' id='4c734837'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='__lock' type-id='95e97e5e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='32'>
|
||||
<var-decl name='__count' type-id='f0981eeb' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='__owner' type-id='95e97e5e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='96'>
|
||||
<var-decl name='__nusers' type-id='f0981eeb' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='__kind' type-id='95e97e5e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='160'>
|
||||
<var-decl name='__spins' type-id='a2185560' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='176'>
|
||||
<var-decl name='__elision' type-id='a2185560' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='__list' type-id='518fb49c' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='__pthread_internal_list' size-in-bits='128' is-struct='yes' visibility='default' id='0e01899c'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='__prev' type-id='4d98cd5a' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='__next' type-id='4d98cd5a' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='__pthread_list_t' type-id='0e01899c' id='518fb49c'/>
|
||||
<typedef-decl name='__pid_t' type-id='95e97e5e' id='3629bad8'/>
|
||||
<pointer-type-def type-id='0e01899c' size-in-bits='64' id='4d98cd5a'/>
|
||||
<pointer-type-def type-id='7a6844eb' size-in-bits='64' id='18c91f9e'/>
|
||||
<function-decl name='libspl_backtrace' mangled-name='libspl_backtrace' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_backtrace'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='pthread_mutex_lock' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='18c91f9e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='pthread_mutex_unlock' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='18c91f9e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='abort' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='getpid' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='3629bad8'/>
|
||||
</function-decl>
|
||||
<function-decl name='__vfprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
|
@ -2051,11 +2125,43 @@
|
|||
<parameter type-id='b7f2d5e6'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='gettid' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='3629bad8'/>
|
||||
</function-decl>
|
||||
<function-decl name='prctl' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter is-variadic='yes'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='libspl_set_assert_ok' mangled-name='libspl_set_assert_ok' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_set_assert_ok'>
|
||||
<parameter type-id='c19b74c3' name='val'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/backtrace.c' language='LANG_C99'>
|
||||
<typedef-decl name='__ssize_t' type-id='bd54fe1a' id='41060289'/>
|
||||
<typedef-decl name='ssize_t' type-id='41060289' id='79a0948f'/>
|
||||
<qualified-type-def type-id='eaa32e2f' const='yes' id='83be723c'/>
|
||||
<pointer-type-def type-id='83be723c' size-in-bits='64' id='7acd98a2'/>
|
||||
<pointer-type-def type-id='eaa32e2f' size-in-bits='64' id='63e171df'/>
|
||||
<function-decl name='backtrace' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='63e171df'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='backtrace_symbols_fd' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='7acd98a2'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='write' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<parameter type-id='b59d7dce'/>
|
||||
<return type-id='79a0948f'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='module/nvpair/fnvpair.c' language='LANG_C99'>
|
||||
<function-decl name='fnvlist_alloc' mangled-name='fnvlist_alloc' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fnvlist_alloc'>
|
||||
<return type-id='5ce45b60'/>
|
||||
|
@ -2536,11 +2642,6 @@
|
|||
<parameter type-id='b59d7dce'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='strchr' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='strlen' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<return type-id='b59d7dce'/>
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
include $(srcdir)/%D%/include/Makefile.am
|
||||
|
||||
libspl_assert_la_CFLAGS = $(AM_CFLAGS) $(LIBRARY_CFLAGS)
|
||||
libspl_assert_la_CFLAGS = $(AM_CFLAGS) $(LIBRARY_CFLAGS) $(LIBUNWIND_CFLAGS)
|
||||
libspl_la_CFLAGS = $(libspl_assert_la_CFLAGS)
|
||||
|
||||
noinst_LTLIBRARIES += libspl_assert.la libspl.la
|
||||
CPPCHECKTARGETS += libspl_assert.la libspl.la
|
||||
|
||||
libspl_assert_la_SOURCES = \
|
||||
%D%/assert.c
|
||||
%D%/assert.c \
|
||||
%D%/backtrace.c
|
||||
|
||||
libspl_la_SOURCES = \
|
||||
%D%/libspl_impl.h \
|
||||
|
@ -43,3 +44,9 @@ libspl_la_LIBADD = \
|
|||
libspl_assert.la
|
||||
|
||||
libspl_la_LIBADD += $(LIBATOMIC_LIBS) $(LIBCLOCK_GETTIME)
|
||||
|
||||
libspl_assert_la_LIBADD = $(BACKTRACE_LIBS) $(LIBUNWIND_LIBS)
|
||||
|
||||
if BUILD_FREEBSD
|
||||
libspl_assert_la_LIBADD += -lpthread
|
||||
endif
|
||||
|
|
|
@ -22,8 +22,48 @@
|
|||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2024, Rob Norris <robn@despairlabs.com>
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/backtrace.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <errno.h>
|
||||
#include <sys/prctl.h>
|
||||
#ifdef HAVE_GETTID
|
||||
#define libspl_gettid() gettid()
|
||||
#else
|
||||
#include <sys/syscall.h>
|
||||
#define libspl_gettid() ((pid_t)syscall(__NR_gettid))
|
||||
#endif
|
||||
#define libspl_getprogname() (program_invocation_short_name)
|
||||
#define libspl_getthreadname(buf, len) \
|
||||
prctl(PR_GET_NAME, (unsigned long)(buf), 0, 0, 0)
|
||||
#elif defined(__FreeBSD__) || defined(__APPLE__)
|
||||
#if !defined(__APPLE__)
|
||||
#include <pthread_np.h>
|
||||
#define libspl_gettid() pthread_getthreadid_np()
|
||||
#endif
|
||||
#define libspl_getprogname() getprogname()
|
||||
#define libspl_getthreadname(buf, len) \
|
||||
pthread_getname_np(pthread_self(), buf, len);
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
static inline uint64_t
|
||||
libspl_gettid(void)
|
||||
{
|
||||
uint64_t tid;
|
||||
|
||||
if (pthread_threadid_np(NULL, &tid) != 0)
|
||||
tid = 0;
|
||||
|
||||
return (tid);
|
||||
}
|
||||
#endif
|
||||
|
||||
static boolean_t libspl_assert_ok = B_FALSE;
|
||||
|
||||
|
@ -33,21 +73,41 @@ libspl_set_assert_ok(boolean_t val)
|
|||
libspl_assert_ok = val;
|
||||
}
|
||||
|
||||
static pthread_mutex_t assert_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* printf version of libspl_assert */
|
||||
void
|
||||
libspl_assertf(const char *file, const char *func, int line,
|
||||
const char *format, ...)
|
||||
{
|
||||
pthread_mutex_lock(&assert_lock);
|
||||
|
||||
va_list args;
|
||||
char tname[64];
|
||||
|
||||
libspl_getthreadname(tname, sizeof (tname));
|
||||
|
||||
fprintf(stderr, "ASSERT at %s:%d:%s()\n", file, line, func);
|
||||
|
||||
va_start(args, format);
|
||||
vfprintf(stderr, format, args);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "ASSERT at %s:%d:%s()", file, line, func);
|
||||
va_end(args);
|
||||
|
||||
fprintf(stderr, "\n"
|
||||
" PID: %-8u COMM: %s\n"
|
||||
#if defined(__APPLE__)
|
||||
" TID: %-8" PRIu64 " NAME: %s\n",
|
||||
#else
|
||||
" TID: %-8u NAME: %s\n",
|
||||
#endif
|
||||
getpid(), libspl_getprogname(),
|
||||
libspl_gettid(), tname);
|
||||
|
||||
libspl_backtrace(STDERR_FILENO);
|
||||
|
||||
#if !__has_feature(attribute_analyzer_noreturn) && !defined(__COVERITY__)
|
||||
if (libspl_assert_ok) {
|
||||
pthread_mutex_unlock(&assert_lock);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2024, Rob Norris <robn@despairlabs.com>
|
||||
* Copyright (c) 2024, Klara Inc.
|
||||
*/
|
||||
|
||||
#include <sys/backtrace.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* libspl_backtrace() must be safe to call from inside a signal hander. This
|
||||
* mostly means it must not allocate, and so we can't use things like printf.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_LIBUNWIND)
|
||||
#define UNW_LOCAL_ONLY
|
||||
#include <libunwind.h>
|
||||
|
||||
static size_t
|
||||
libspl_u64_to_hex_str(uint64_t v, size_t digits, char *buf, size_t buflen)
|
||||
{
|
||||
static const char hexdigits[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
||||
};
|
||||
|
||||
size_t pos = 0;
|
||||
boolean_t want = (digits == 0);
|
||||
for (int i = 15; i >= 0; i--) {
|
||||
const uint64_t d = v >> (i * 4) & 0xf;
|
||||
if (!want && (d != 0 || digits > i))
|
||||
want = B_TRUE;
|
||||
if (want) {
|
||||
buf[pos++] = hexdigits[d];
|
||||
if (pos == buflen)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (pos);
|
||||
}
|
||||
|
||||
void
|
||||
libspl_backtrace(int fd)
|
||||
{
|
||||
ssize_t ret __attribute__((unused));
|
||||
unw_context_t uc;
|
||||
unw_cursor_t cp;
|
||||
unw_word_t loc;
|
||||
char buf[128];
|
||||
size_t n;
|
||||
|
||||
ret = write(fd, "Call trace:\n", 12);
|
||||
unw_getcontext(&uc);
|
||||
unw_init_local(&cp, &uc);
|
||||
while (unw_step(&cp) > 0) {
|
||||
unw_get_reg(&cp, UNW_REG_IP, &loc);
|
||||
ret = write(fd, " [0x", 5);
|
||||
n = libspl_u64_to_hex_str(loc, 10, buf, sizeof (buf));
|
||||
ret = write(fd, buf, n);
|
||||
ret = write(fd, "] ", 2);
|
||||
unw_get_proc_name(&cp, buf, sizeof (buf), &loc);
|
||||
for (n = 0; n < sizeof (buf) && buf[n] != '\0'; n++) {}
|
||||
ret = write(fd, buf, n);
|
||||
ret = write(fd, "+0x", 3);
|
||||
n = libspl_u64_to_hex_str(loc, 2, buf, sizeof (buf));
|
||||
ret = write(fd, buf, n);
|
||||
#ifdef HAVE_LIBUNWIND_ELF
|
||||
ret = write(fd, " (in ", 5);
|
||||
unw_get_elf_filename(&cp, buf, sizeof (buf), &loc);
|
||||
for (n = 0; n < sizeof (buf) && buf[n] != '\0'; n++) {}
|
||||
ret = write(fd, buf, n);
|
||||
ret = write(fd, " +0x", 4);
|
||||
n = libspl_u64_to_hex_str(loc, 2, buf, sizeof (buf));
|
||||
ret = write(fd, buf, n);
|
||||
ret = write(fd, ")", 1);
|
||||
#endif
|
||||
ret = write(fd, "\n", 1);
|
||||
}
|
||||
}
|
||||
#elif defined(HAVE_BACKTRACE)
|
||||
#include <execinfo.h>
|
||||
|
||||
void
|
||||
libspl_backtrace(int fd)
|
||||
{
|
||||
ssize_t ret __attribute__((unused));
|
||||
void *btptrs[64];
|
||||
size_t nptrs = backtrace(btptrs, 64);
|
||||
ret = write(fd, "Call trace:\n", 12);
|
||||
backtrace_symbols_fd(btptrs, nptrs, fd);
|
||||
}
|
||||
#else
|
||||
#include <sys/debug.h>
|
||||
|
||||
void
|
||||
libspl_backtrace(int fd __maybe_unused)
|
||||
{
|
||||
}
|
||||
#endif
|
|
@ -27,6 +27,7 @@ libspl_sys_HEADERS = \
|
|||
%D%/sys/acl.h \
|
||||
%D%/sys/acl_impl.h \
|
||||
%D%/sys/asm_linkage.h \
|
||||
%D%/sys/backtrace.h \
|
||||
%D%/sys/callb.h \
|
||||
%D%/sys/cmn_err.h \
|
||||
%D%/sys/cred.h \
|
||||
|
|
|
@ -70,6 +70,15 @@ libspl_assert(const char *buf, const char *file, const char *func, int line)
|
|||
#define VERIFY(cond) \
|
||||
(void) ((!(cond)) && \
|
||||
libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))
|
||||
|
||||
#define VERIFYF(cond, STR, ...) \
|
||||
do { \
|
||||
if (!(cond)) \
|
||||
libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s " STR, #cond, \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define verify(cond) \
|
||||
(void) ((!(cond)) && \
|
||||
libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))
|
||||
|
@ -132,6 +141,79 @@ do { \
|
|||
(void *)__left); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* This is just here because cstyle gets upset about #LEFT
|
||||
* on a newline.
|
||||
*/
|
||||
|
||||
/* BEGIN CSTYLED */
|
||||
#define VERIFY3BF(LEFT, OP, RIGHT, STR, ...) \
|
||||
do { \
|
||||
const boolean_t __left = (boolean_t)(LEFT); \
|
||||
const boolean_t __right = (boolean_t)(RIGHT); \
|
||||
if (!(__left OP __right)) \
|
||||
libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s %s %s (0x%llx %s 0x%llx) " STR, \
|
||||
#LEFT, #OP, #RIGHT, \
|
||||
(u_longlong_t)__left, #OP, (u_longlong_t)__right, \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3SF(LEFT, OP, RIGHT, STR, ...) \
|
||||
do { \
|
||||
const int64_t __left = (int64_t)(LEFT); \
|
||||
const int64_t __right = (int64_t)(RIGHT); \
|
||||
if (!(__left OP __right)) \
|
||||
libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s %s %s (0x%llx %s 0x%llx) " STR, \
|
||||
#LEFT, #OP, #RIGHT, \
|
||||
(u_longlong_t)__left, #OP, (u_longlong_t)__right, \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3UF(LEFT, OP, RIGHT, STR, ...) \
|
||||
do { \
|
||||
const uint64_t __left = (uint64_t)(LEFT); \
|
||||
const uint64_t __right = (uint64_t)(RIGHT); \
|
||||
if (!(__left OP __right)) \
|
||||
libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s %s %s (0x%llx %s 0x%llx) " STR, \
|
||||
#LEFT, #OP, #RIGHT, \
|
||||
(u_longlong_t)__left, #OP, (u_longlong_t)__right, \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3PF(LEFT, OP, RIGHT, STR, ...) \
|
||||
do { \
|
||||
const uintptr_t __left = (uintptr_t)(LEFT); \
|
||||
const uintptr_t __right = (uintptr_t)(RIGHT); \
|
||||
if (!(__left OP __right)) \
|
||||
libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s %s %s (0x%llx %s 0x%llx) " STR, \
|
||||
#LEFT, #OP, #RIGHT, \
|
||||
(u_longlong_t)__left, #OP, (u_longlong_t)__right, \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
/* END CSTYLED */
|
||||
|
||||
#define VERIFY0F(LEFT, STR, ...) \
|
||||
do { \
|
||||
const uint64_t __left = (uint64_t)(LEFT); \
|
||||
if (!(__left == 0)) \
|
||||
libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s == 0 (0x%llx == 0) " STR, #LEFT, \
|
||||
(u_longlong_t)__left, __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY0PF(LEFT, STR, ...) \
|
||||
do { \
|
||||
const uintptr_t __left = (uintptr_t)(LEFT); \
|
||||
if (!(__left == 0)) \
|
||||
libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s == 0 (%p == 0) " STR, #LEFT, \
|
||||
(u_longlong_t)__left, __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#ifdef assert
|
||||
#undef assert
|
||||
#endif
|
||||
|
@ -147,7 +229,15 @@ do { \
|
|||
((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
|
||||
#define ASSERT0(x) ((void) sizeof ((uintptr_t)(x)))
|
||||
#define ASSERT0P(x) ((void) sizeof ((uintptr_t)(x)))
|
||||
#define ASSERT3BF(x, y, z, str, ...) ASSERT3B(x, y, z)
|
||||
#define ASSERT3SF(x, y, z, str, ...) ASSERT3S(x, y, z)
|
||||
#define ASSERT3UF(x, y, z, str, ...) ASSERT3U(x, y, z)
|
||||
#define ASSERT3PF(x, y, z, str, ...) ASSERT3P(x, y, z)
|
||||
#define ASSERT0P(x) ((void) sizeof ((uintptr_t)(x)))
|
||||
#define ASSERT0PF(x, str, ...) ASSERT0P(x)
|
||||
#define ASSERT0F(x, str, ...) ASSERT0(x)
|
||||
#define ASSERT(x) ((void) sizeof ((uintptr_t)(x)))
|
||||
#define ASSERTF(x, str, ...) ASSERT(x)
|
||||
#define assert(x) ((void) sizeof ((uintptr_t)(x)))
|
||||
#define IMPLY(A, B) \
|
||||
((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))
|
||||
|
@ -160,7 +250,14 @@ do { \
|
|||
#define ASSERT3P VERIFY3P
|
||||
#define ASSERT0 VERIFY0
|
||||
#define ASSERT0P VERIFY0P
|
||||
#define ASSERT3BF VERIFY3BF
|
||||
#define ASSERT3SF VERIFY3SF
|
||||
#define ASSERT3UF VERIFY3UF
|
||||
#define ASSERT3PF VERIFY3PF
|
||||
#define ASSERT0PF VERIFY0PF
|
||||
#define ASSERT0F VERIFY0F
|
||||
#define ASSERT VERIFY
|
||||
#define ASSERTF VERIFYF
|
||||
#define assert VERIFY
|
||||
#define IMPLY(A, B) \
|
||||
((void)(((!(A)) || (B)) || \
|
||||
|
|
|
@ -52,7 +52,8 @@
|
|||
/*
|
||||
* Compatibility macros/typedefs needed for Solaris -> Linux port
|
||||
*/
|
||||
#define P2ALIGN(x, align) ((x) & -(align))
|
||||
// Deprecated. Use P2ALIGN_TYPED instead.
|
||||
// #define P2ALIGN(x, align) ((x) & -(align))
|
||||
#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1)
|
||||
#define P2ROUNDUP(x, align) ((((x) - 1) | ((align) - 1)) + 1)
|
||||
#define P2BOUNDARY(off, len, align) \
|
||||
|
|
|
@ -20,17 +20,13 @@
|
|||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
* Copyright (c) 2024, Rob Norris <robn@despairlabs.com>
|
||||
* Copyright (c) 2024, Klara Inc.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TRAP_H
|
||||
#define _SYS_TRAP_H
|
||||
#ifndef _LIBSPL_SYS_BACKTRACE_H
|
||||
#define _LIBSPL_SYS_BACKTRACE_H
|
||||
|
||||
#if defined(__i386) || defined(__amd64)
|
||||
|
||||
#include <sys/ia32/trap.h> /* XX64 x86/sys/trap.h */
|
||||
void libspl_backtrace(int fd);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_TRAP_H */
|
|
@ -423,6 +423,26 @@ tpool_dispatch(tpool_t *tpool, void (*func)(void *), void *arg)
|
|||
|
||||
pthread_mutex_lock(&tpool->tp_mutex);
|
||||
|
||||
if (!(tpool->tp_flags & TP_SUSPEND)) {
|
||||
if (tpool->tp_idle > 0)
|
||||
(void) pthread_cond_signal(&tpool->tp_workcv);
|
||||
else if (tpool->tp_current >= tpool->tp_maximum) {
|
||||
/* At worker limit. Leave task on queue */
|
||||
} else {
|
||||
if (create_worker(tpool) == 0) {
|
||||
/* Started a new worker thread */
|
||||
tpool->tp_current++;
|
||||
} else if (tpool->tp_current > 0) {
|
||||
/* Leave task on queue */
|
||||
} else {
|
||||
/* Cannot start a single worker! */
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
free(job);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tpool->tp_head == NULL)
|
||||
tpool->tp_head = job;
|
||||
else
|
||||
|
@ -430,14 +450,6 @@ tpool_dispatch(tpool_t *tpool, void (*func)(void *), void *arg)
|
|||
tpool->tp_tail = job;
|
||||
tpool->tp_njobs++;
|
||||
|
||||
if (!(tpool->tp_flags & TP_SUSPEND)) {
|
||||
if (tpool->tp_idle > 0)
|
||||
(void) pthread_cond_signal(&tpool->tp_workcv);
|
||||
else if (tpool->tp_current < tpool->tp_maximum &&
|
||||
create_worker(tpool) == 0)
|
||||
tpool->tp_current++;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -149,6 +149,7 @@
|
|||
<elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='getzoneid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_assertf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_backtrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_set_assert_ok' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='list_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='list_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
@ -242,6 +243,22 @@
|
|||
<elf-symbol name='uu_zalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
</elf-function-symbols>
|
||||
<abi-instr address-size='64' path='lib/libspl/assert.c' language='LANG_C99'>
|
||||
<typedef-decl name='__pid_t' type-id='95e97e5e' id='3629bad8'/>
|
||||
<function-decl name='libspl_backtrace' mangled-name='libspl_backtrace' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_backtrace'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='getpid' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='3629bad8'/>
|
||||
</function-decl>
|
||||
<function-decl name='gettid' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='3629bad8'/>
|
||||
</function-decl>
|
||||
<function-decl name='prctl' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter is-variadic='yes'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='libspl_set_assert_ok' mangled-name='libspl_set_assert_ok' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_set_assert_ok'>
|
||||
<parameter type-id='c19b74c3' name='val'/>
|
||||
<return type-id='48b5725f'/>
|
||||
|
@ -576,6 +593,27 @@
|
|||
</function-decl>
|
||||
<type-decl name='unsigned short int' size-in-bits='16' id='8efea9e5'/>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/backtrace.c' language='LANG_C99'>
|
||||
<qualified-type-def type-id='eaa32e2f' const='yes' id='83be723c'/>
|
||||
<pointer-type-def type-id='83be723c' size-in-bits='64' id='7acd98a2'/>
|
||||
<function-decl name='backtrace' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='63e171df'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='backtrace_symbols_fd' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='7acd98a2'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='write' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<parameter type-id='b59d7dce'/>
|
||||
<return type-id='79a0948f'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/getexecname.c' language='LANG_C99'>
|
||||
<function-decl name='getexecname' mangled-name='getexecname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getexecname'>
|
||||
<return type-id='80f4b756'/>
|
||||
|
@ -596,14 +634,11 @@
|
|||
<var-decl name='prev' type-id='b03eadb4' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='list' size-in-bits='256' is-struct='yes' visibility='default' id='e824dae9'>
|
||||
<class-decl name='list' size-in-bits='192' is-struct='yes' visibility='default' id='e824dae9'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='list_size' type-id='b59d7dce' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='list_offset' type-id='b59d7dce' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='list_head' type-id='b0b5e45e' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
|
@ -800,9 +835,16 @@
|
|||
<type-decl name='unsigned long int' size-in-bits='64' id='7359adad'/>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/getmntany.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='38b51b3c' size-in-bits='832' id='02b72c00'>
|
||||
<subrange length='13' type-id='7359adad' id='487fded1'/>
|
||||
</array-type-def>
|
||||
<array-type-def dimensions='1' type-id='03085adc' size-in-bits='192' id='083f8d58'>
|
||||
<subrange length='3' type-id='7359adad' id='56f209d2'/>
|
||||
</array-type-def>
|
||||
<class-decl name='__locale_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='23de8b96'/>
|
||||
<array-type-def dimensions='1' type-id='80f4b756' size-in-bits='832' id='39e6f84a'>
|
||||
<subrange length='13' type-id='7359adad' id='487fded1'/>
|
||||
</array-type-def>
|
||||
<class-decl name='mnttab' size-in-bits='256' is-struct='yes' visibility='default' id='1b055409'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='mnt_special' type-id='26a90f95' visibility='default'/>
|
||||
|
@ -912,6 +954,25 @@
|
|||
<typedef-decl name='__blksize_t' type-id='bd54fe1a' id='d3f10a7f'/>
|
||||
<typedef-decl name='__blkcnt64_t' type-id='bd54fe1a' id='4e711bf1'/>
|
||||
<typedef-decl name='__syscall_slong_t' type-id='bd54fe1a' id='03085adc'/>
|
||||
<class-decl name='__locale_struct' size-in-bits='1856' is-struct='yes' visibility='default' id='90cc1ce3'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='__locales' type-id='02b72c00' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='832'>
|
||||
<var-decl name='__ctype_b' type-id='31347b7a' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='896'>
|
||||
<var-decl name='__ctype_tolower' type-id='6d60f45d' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='960'>
|
||||
<var-decl name='__ctype_toupper' type-id='6d60f45d' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1024'>
|
||||
<var-decl name='__names' type-id='39e6f84a' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='__locale_t' type-id='f01e1813' id='b7ac9b5f'/>
|
||||
<typedef-decl name='locale_t' type-id='b7ac9b5f' id='973a4f8d'/>
|
||||
<class-decl name='timespec' size-in-bits='128' is-struct='yes' visibility='default' id='a9c79a1f'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='tv_sec' type-id='65eda9c0' visibility='default'/>
|
||||
|
@ -920,12 +981,23 @@
|
|||
<var-decl name='tv_nsec' type-id='03085adc' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<pointer-type-def type-id='23de8b96' size-in-bits='64' id='38b51b3c'/>
|
||||
<pointer-type-def type-id='90cc1ce3' size-in-bits='64' id='f01e1813'/>
|
||||
<qualified-type-def type-id='95e97e5e' const='yes' id='2448a865'/>
|
||||
<pointer-type-def type-id='2448a865' size-in-bits='64' id='6d60f45d'/>
|
||||
<qualified-type-def type-id='8efea9e5' const='yes' id='3beb2af4'/>
|
||||
<pointer-type-def type-id='3beb2af4' size-in-bits='64' id='31347b7a'/>
|
||||
<pointer-type-def type-id='0c544dc0' size-in-bits='64' id='394fc496'/>
|
||||
<pointer-type-def type-id='56fe4a37' size-in-bits='64' id='b6b61d2f'/>
|
||||
<qualified-type-def type-id='b6b61d2f' restrict='yes' id='3cad23cd'/>
|
||||
<pointer-type-def type-id='1b055409' size-in-bits='64' id='9d424d31'/>
|
||||
<pointer-type-def type-id='0bbec9cd' size-in-bits='64' id='62f7a03d'/>
|
||||
<qualified-type-def type-id='62f7a03d' restrict='yes' id='f1cadedf'/>
|
||||
<class-decl name='__locale_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='23de8b96'/>
|
||||
<function-decl name='uselocale' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='973a4f8d'/>
|
||||
<return type-id='973a4f8d'/>
|
||||
</function-decl>
|
||||
<function-decl name='getmntent_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='3cad23cd'/>
|
||||
|
@ -937,8 +1009,9 @@
|
|||
<parameter type-id='822cd80b'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='strerror' visibility='default' binding='global' size-in-bits='64'>
|
||||
<function-decl name='strerror_l' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='973a4f8d'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='__fprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||
|
|
|
@ -505,14 +505,20 @@ uu_list_walk(uu_list_t *lp, uu_walk_fn_t *func, void *private, uint32_t flags)
|
|||
}
|
||||
|
||||
if (lp->ul_debug || robust) {
|
||||
uu_list_walk_t my_walk;
|
||||
uu_list_walk_t *my_walk;
|
||||
void *e;
|
||||
|
||||
list_walk_init(&my_walk, lp, flags);
|
||||
my_walk = uu_zalloc(sizeof (*my_walk));
|
||||
if (my_walk == NULL)
|
||||
return (-1);
|
||||
|
||||
list_walk_init(my_walk, lp, flags);
|
||||
while (status == UU_WALK_NEXT &&
|
||||
(e = uu_list_walk_next(&my_walk)) != NULL)
|
||||
(e = uu_list_walk_next(my_walk)) != NULL)
|
||||
status = (*func)(e, private);
|
||||
list_walk_fini(&my_walk);
|
||||
list_walk_fini(my_walk);
|
||||
|
||||
uu_free(my_walk);
|
||||
} else {
|
||||
if (!reverse) {
|
||||
for (np = lp->ul_null_node.uln_next;
|
||||
|
|
|
@ -191,6 +191,7 @@
|
|||
<elf-symbol name='is_mpath_whole_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libpc_error_description' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_assertf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_backtrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_set_assert_ok' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libzfs_add_handle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libzfs_envvar_is_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
@ -777,6 +778,18 @@
|
|||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/assert.c' language='LANG_C99'>
|
||||
<function-decl name='libspl_backtrace' mangled-name='libspl_backtrace' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_backtrace'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='gettid' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='3629bad8'/>
|
||||
</function-decl>
|
||||
<function-decl name='prctl' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter is-variadic='yes'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='libspl_set_assert_ok' mangled-name='libspl_set_assert_ok' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_set_assert_ok'>
|
||||
<parameter type-id='c19b74c3' name='val'/>
|
||||
<return type-id='48b5725f'/>
|
||||
|
@ -1092,6 +1105,19 @@
|
|||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/backtrace.c' language='LANG_C99'>
|
||||
<function-decl name='backtrace' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='63e171df'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='backtrace_symbols_fd' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='7acd98a2'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/getexecname.c' language='LANG_C99'>
|
||||
<function-decl name='getexecname' mangled-name='getexecname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getexecname'>
|
||||
<return type-id='80f4b756'/>
|
||||
|
@ -5532,13 +5558,14 @@
|
|||
<parameter type-id='b59d7dce' name='num_handles'/>
|
||||
<parameter type-id='d8e49ab9' name='func'/>
|
||||
<parameter type-id='eaa32e2f' name='data'/>
|
||||
<parameter type-id='c19b74c3' name='parallel'/>
|
||||
<parameter type-id='3502e3ff' name='nthr'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_enable_datasets' mangled-name='zpool_enable_datasets' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_enable_datasets'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='80f4b756' name='mntopts'/>
|
||||
<parameter type-id='95e97e5e' name='flags'/>
|
||||
<parameter type-id='3502e3ff' name='nthr'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_disable_datasets' mangled-name='zpool_disable_datasets' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_disable_datasets'>
|
||||
|
@ -6251,6 +6278,11 @@
|
|||
<parameter type-id='8c85230f'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='ctime_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='d6e2847c'/>
|
||||
<parameter type-id='266fe297'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='__realpath_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='266fe297'/>
|
||||
|
@ -6362,7 +6394,7 @@
|
|||
<function-decl name='zpool_add' mangled-name='zpool_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_add'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='5ce45b60' name='nvroot'/>
|
||||
<parameter type-id='c19b74c3' name='ashift_check'/>
|
||||
<parameter type-id='c19b74c3' name='check_ashift'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_export' mangled-name='zpool_export' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_export'>
|
||||
|
@ -8671,7 +8703,7 @@
|
|||
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='256' id='16dc656a'>
|
||||
<subrange length='32' type-id='7359adad' id='ae5bde82'/>
|
||||
</array-type-def>
|
||||
<class-decl name='importargs' size-in-bits='448' is-struct='yes' visibility='default' id='7ac83801'>
|
||||
<class-decl name='importargs' size-in-bits='512' is-struct='yes' visibility='default' id='7ac83801'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='path' type-id='9b23c9ad' visibility='default'/>
|
||||
</data-member>
|
||||
|
@ -8696,6 +8728,12 @@
|
|||
<data-member access='public' layout-offset-in-bits='384'>
|
||||
<var-decl name='policy' type-id='5ce45b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='448'>
|
||||
<var-decl name='do_destroyed' type-id='c19b74c3' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='480'>
|
||||
<var-decl name='do_all' type-id='c19b74c3' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='importargs_t' type-id='7ac83801' id='7a842a6b'/>
|
||||
<class-decl name='libpc_handle' size-in-bits='8448' is-struct='yes' visibility='default' id='7c8737f0'>
|
||||
|
|
|
@ -5565,8 +5565,21 @@ volsize_from_vdevs(zpool_handle_t *zhp, uint64_t nblocks, uint64_t blksize)
|
|||
/*
|
||||
* Scale this size down as a ratio of 128k / tsize.
|
||||
* See theory statement above.
|
||||
*
|
||||
* Bitshift is to avoid the case of nblocks * asize < tsize
|
||||
* producing a size of 0.
|
||||
*/
|
||||
volsize = nblocks * asize * SPA_OLD_MAXBLOCKSIZE / tsize;
|
||||
volsize = (nblocks * asize) / (tsize >> SPA_MINBLOCKSHIFT);
|
||||
/*
|
||||
* If we would blow UINT64_MAX with this next multiplication,
|
||||
* don't.
|
||||
*/
|
||||
if (volsize >
|
||||
(UINT64_MAX / (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT)))
|
||||
volsize = UINT64_MAX;
|
||||
else
|
||||
volsize *= (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);
|
||||
|
||||
if (volsize > ret) {
|
||||
ret = volsize;
|
||||
}
|
||||
|
|
|
@ -83,8 +83,6 @@
|
|||
#include <sys/systeminfo.h>
|
||||
#define MAXISALEN 257 /* based on sysinfo(2) man page */
|
||||
|
||||
static int mount_tp_nthr = 512; /* tpool threads for multi-threaded mounting */
|
||||
|
||||
static void zfs_mount_task(void *);
|
||||
|
||||
static const proto_table_t proto_table[SA_PROTOCOL_COUNT] = {
|
||||
|
@ -1098,7 +1096,10 @@ zfs_dispatch_mount(libzfs_handle_t *hdl, zfs_handle_t **handles,
|
|||
mnt_param->mnt_func = func;
|
||||
mnt_param->mnt_data = data;
|
||||
|
||||
(void) tpool_dispatch(tp, zfs_mount_task, (void*)mnt_param);
|
||||
if (tpool_dispatch(tp, zfs_mount_task, (void*)mnt_param)) {
|
||||
/* Could not dispatch to thread pool; execute directly */
|
||||
zfs_mount_task((void*)mnt_param);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1202,19 +1203,20 @@ out:
|
|||
*
|
||||
* Callbacks are issued in one of two ways:
|
||||
*
|
||||
* 1. Sequentially: If the parallel argument is B_FALSE or the ZFS_SERIAL_MOUNT
|
||||
* 1. Sequentially: If the nthr argument is <= 1 or the ZFS_SERIAL_MOUNT
|
||||
* environment variable is set, then we issue callbacks sequentially.
|
||||
*
|
||||
* 2. In parallel: If the parallel argument is B_TRUE and the ZFS_SERIAL_MOUNT
|
||||
* 2. In parallel: If the nthr argument is > 1 and the ZFS_SERIAL_MOUNT
|
||||
* environment variable is not set, then we use a tpool to dispatch threads
|
||||
* to mount filesystems in parallel. This function dispatches tasks to mount
|
||||
* the filesystems at the top-level mountpoints, and these tasks in turn
|
||||
* are responsible for recursively mounting filesystems in their children
|
||||
* mountpoints.
|
||||
* mountpoints. The value of the nthr argument will be the number of worker
|
||||
* threads for the thread pool.
|
||||
*/
|
||||
void
|
||||
zfs_foreach_mountpoint(libzfs_handle_t *hdl, zfs_handle_t **handles,
|
||||
size_t num_handles, zfs_iter_f func, void *data, boolean_t parallel)
|
||||
size_t num_handles, zfs_iter_f func, void *data, uint_t nthr)
|
||||
{
|
||||
zoneid_t zoneid = getzoneid();
|
||||
|
||||
|
@ -1223,7 +1225,7 @@ zfs_foreach_mountpoint(libzfs_handle_t *hdl, zfs_handle_t **handles,
|
|||
* variable that can be used as a convenience to do a/b comparison
|
||||
* of serial vs. parallel mounting.
|
||||
*/
|
||||
boolean_t serial_mount = !parallel ||
|
||||
boolean_t serial_mount = nthr <= 1 ||
|
||||
(getenv("ZFS_SERIAL_MOUNT") != NULL);
|
||||
|
||||
/*
|
||||
|
@ -1243,7 +1245,7 @@ zfs_foreach_mountpoint(libzfs_handle_t *hdl, zfs_handle_t **handles,
|
|||
* Issue the callback function for each dataset using a parallel
|
||||
* algorithm that uses a thread pool to manage threads.
|
||||
*/
|
||||
tpool_t *tp = tpool_create(1, mount_tp_nthr, 0, NULL);
|
||||
tpool_t *tp = tpool_create(1, nthr, 0, NULL);
|
||||
|
||||
/*
|
||||
* There may be multiple "top level" mountpoints outside of the pool's
|
||||
|
@ -1270,10 +1272,12 @@ zfs_foreach_mountpoint(libzfs_handle_t *hdl, zfs_handle_t **handles,
|
|||
|
||||
/*
|
||||
* Mount and share all datasets within the given pool. This assumes that no
|
||||
* datasets within the pool are currently mounted.
|
||||
* datasets within the pool are currently mounted. nthr will be number of
|
||||
* worker threads to use while mounting datasets.
|
||||
*/
|
||||
int
|
||||
zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
|
||||
zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags,
|
||||
uint_t nthr)
|
||||
{
|
||||
get_all_cb_t cb = { 0 };
|
||||
mount_state_t ms = { 0 };
|
||||
|
@ -1299,7 +1303,7 @@ zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
|
|||
ms.ms_mntopts = mntopts;
|
||||
ms.ms_mntflags = flags;
|
||||
zfs_foreach_mountpoint(zhp->zpool_hdl, cb.cb_handles, cb.cb_used,
|
||||
zfs_mount_one, &ms, B_TRUE);
|
||||
zfs_mount_one, &ms, nthr);
|
||||
if (ms.ms_mntstatus != 0)
|
||||
ret = EZFS_MOUNTFAILED;
|
||||
|
||||
|
@ -1310,7 +1314,7 @@ zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
|
|||
*/
|
||||
ms.ms_mntstatus = 0;
|
||||
zfs_foreach_mountpoint(zhp->zpool_hdl, cb.cb_handles, cb.cb_used,
|
||||
zfs_share_one, &ms, B_FALSE);
|
||||
zfs_share_one, &ms, 1);
|
||||
if (ms.ms_mntstatus != 0)
|
||||
ret = EZFS_SHAREFAILED;
|
||||
else
|
||||
|
|
|
@ -1053,6 +1053,7 @@ send_progress_thread(void *arg)
|
|||
}
|
||||
}
|
||||
pthread_cleanup_pop(B_TRUE);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
|
@ -2169,7 +2170,8 @@ out:
|
|||
static int
|
||||
send_conclusion_record(int fd, zio_cksum_t *zc)
|
||||
{
|
||||
dmu_replay_record_t drr = { 0 };
|
||||
dmu_replay_record_t drr;
|
||||
memset(&drr, 0, sizeof (dmu_replay_record_t));
|
||||
drr.drr_type = DRR_END;
|
||||
if (zc != NULL)
|
||||
drr.drr_u.drr_end.drr_checksum = *zc;
|
||||
|
@ -2271,7 +2273,8 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd,
|
|||
}
|
||||
|
||||
if (!dryrun) {
|
||||
dmu_replay_record_t drr = { 0 };
|
||||
dmu_replay_record_t drr;
|
||||
memset(&drr, 0, sizeof (dmu_replay_record_t));
|
||||
/* write first begin record */
|
||||
drr.drr_type = DRR_BEGIN;
|
||||
drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
|
||||
|
|
|
@ -274,7 +274,8 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name)
|
|||
if (start_block == MAXOFFSET_T)
|
||||
start_block = NEW_START_BLOCK;
|
||||
slice_size -= start_block;
|
||||
slice_size = P2ALIGN(slice_size, PARTITION_END_ALIGNMENT);
|
||||
slice_size = P2ALIGN_TYPED(slice_size, PARTITION_END_ALIGNMENT,
|
||||
uint64_t);
|
||||
|
||||
vtoc->efi_parts[0].p_start = start_block;
|
||||
vtoc->efi_parts[0].p_size = slice_size;
|
||||
|
|
|
@ -132,6 +132,7 @@
|
|||
<elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='getzoneid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_assertf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_backtrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libspl_set_assert_ok' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libzfs_core_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libzfs_core_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
@ -167,6 +168,7 @@
|
|||
<elf-symbol name='lzc_get_bookmarks' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_get_bootenv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_get_holds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_get_props' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_get_vdev_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_hold' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_initialize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
@ -231,10 +233,18 @@
|
|||
<var-decl name='reg_save_area' type-id='eaa32e2f' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='__pid_t' type-id='95e97e5e' id='3629bad8'/>
|
||||
<pointer-type-def type-id='d5027220' size-in-bits='64' id='b7f2d5e6'/>
|
||||
<function-decl name='libspl_backtrace' mangled-name='libspl_backtrace' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_backtrace'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='abort' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='getpid' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='3629bad8'/>
|
||||
</function-decl>
|
||||
<function-decl name='__vfprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
|
@ -242,6 +252,14 @@
|
|||
<parameter type-id='b7f2d5e6'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='gettid' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='3629bad8'/>
|
||||
</function-decl>
|
||||
<function-decl name='prctl' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter is-variadic='yes'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='libspl_set_assert_ok' mangled-name='libspl_set_assert_ok' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_set_assert_ok'>
|
||||
<parameter type-id='c19b74c3' name='val'/>
|
||||
<return type-id='48b5725f'/>
|
||||
|
@ -574,6 +592,27 @@
|
|||
<type-decl name='unsigned long int' size-in-bits='64' id='7359adad'/>
|
||||
<type-decl name='unsigned short int' size-in-bits='16' id='8efea9e5'/>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/backtrace.c' language='LANG_C99'>
|
||||
<qualified-type-def type-id='eaa32e2f' const='yes' id='83be723c'/>
|
||||
<pointer-type-def type-id='83be723c' size-in-bits='64' id='7acd98a2'/>
|
||||
<function-decl name='backtrace' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='63e171df'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='backtrace_symbols_fd' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='7acd98a2'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='write' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<parameter type-id='b59d7dce'/>
|
||||
<return type-id='79a0948f'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/getexecname.c' language='LANG_C99'>
|
||||
<function-decl name='getexecname' mangled-name='getexecname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getexecname'>
|
||||
<return type-id='80f4b756'/>
|
||||
|
@ -594,14 +633,11 @@
|
|||
<var-decl name='prev' type-id='b03eadb4' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='list' size-in-bits='256' is-struct='yes' visibility='default' id='e824dae9'>
|
||||
<class-decl name='list' size-in-bits='192' is-struct='yes' visibility='default' id='e824dae9'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='list_size' type-id='b59d7dce' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='list_offset' type-id='b59d7dce' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='list_head' type-id='b0b5e45e' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
|
@ -770,6 +806,13 @@
|
|||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/getmntany.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='38b51b3c' size-in-bits='832' id='02b72c00'>
|
||||
<subrange length='13' type-id='7359adad' id='487fded1'/>
|
||||
</array-type-def>
|
||||
<class-decl name='__locale_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='23de8b96'/>
|
||||
<array-type-def dimensions='1' type-id='80f4b756' size-in-bits='832' id='39e6f84a'>
|
||||
<subrange length='13' type-id='7359adad' id='487fded1'/>
|
||||
</array-type-def>
|
||||
<class-decl name='mnttab' size-in-bits='256' is-struct='yes' visibility='default' id='1b055409'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='mnt_special' type-id='26a90f95' visibility='default'/>
|
||||
|
@ -873,12 +916,42 @@
|
|||
</class-decl>
|
||||
<typedef-decl name='__ino64_t' type-id='7359adad' id='71288a47'/>
|
||||
<typedef-decl name='__blkcnt64_t' type-id='bd54fe1a' id='4e711bf1'/>
|
||||
<class-decl name='__locale_struct' size-in-bits='1856' is-struct='yes' visibility='default' id='90cc1ce3'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='__locales' type-id='02b72c00' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='832'>
|
||||
<var-decl name='__ctype_b' type-id='31347b7a' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='896'>
|
||||
<var-decl name='__ctype_tolower' type-id='6d60f45d' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='960'>
|
||||
<var-decl name='__ctype_toupper' type-id='6d60f45d' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1024'>
|
||||
<var-decl name='__names' type-id='39e6f84a' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='__locale_t' type-id='f01e1813' id='b7ac9b5f'/>
|
||||
<typedef-decl name='locale_t' type-id='b7ac9b5f' id='973a4f8d'/>
|
||||
<pointer-type-def type-id='23de8b96' size-in-bits='64' id='38b51b3c'/>
|
||||
<pointer-type-def type-id='90cc1ce3' size-in-bits='64' id='f01e1813'/>
|
||||
<qualified-type-def type-id='95e97e5e' const='yes' id='2448a865'/>
|
||||
<pointer-type-def type-id='2448a865' size-in-bits='64' id='6d60f45d'/>
|
||||
<qualified-type-def type-id='8efea9e5' const='yes' id='3beb2af4'/>
|
||||
<pointer-type-def type-id='3beb2af4' size-in-bits='64' id='31347b7a'/>
|
||||
<pointer-type-def type-id='0c544dc0' size-in-bits='64' id='394fc496'/>
|
||||
<pointer-type-def type-id='56fe4a37' size-in-bits='64' id='b6b61d2f'/>
|
||||
<qualified-type-def type-id='b6b61d2f' restrict='yes' id='3cad23cd'/>
|
||||
<pointer-type-def type-id='1b055409' size-in-bits='64' id='9d424d31'/>
|
||||
<pointer-type-def type-id='0bbec9cd' size-in-bits='64' id='62f7a03d'/>
|
||||
<qualified-type-def type-id='62f7a03d' restrict='yes' id='f1cadedf'/>
|
||||
<class-decl name='__locale_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='23de8b96'/>
|
||||
<function-decl name='uselocale' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='973a4f8d'/>
|
||||
<return type-id='973a4f8d'/>
|
||||
</function-decl>
|
||||
<function-decl name='getmntent_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='3cad23cd'/>
|
||||
|
@ -895,8 +968,9 @@
|
|||
<parameter type-id='80f4b756'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='strerror' visibility='default' binding='global' size-in-bits='64'>
|
||||
<function-decl name='strerror_l' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='973a4f8d'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='__fprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||
|
@ -1119,7 +1193,7 @@
|
|||
<enumerator name='LZC_SEND_FLAG_RAW' value='8'/>
|
||||
<enumerator name='LZC_SEND_FLAG_SAVED' value='16'/>
|
||||
</enum-decl>
|
||||
<class-decl name='ddt_key' size-in-bits='320' is-struct='yes' visibility='default' id='e0a4a1cb'>
|
||||
<class-decl name='ddt_key_t' size-in-bits='320' is-struct='yes' naming-typedef-id='67f6d2cf' visibility='default' id='5fae1718'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='ddk_cksum' type-id='39730d0b' visibility='default'/>
|
||||
</data-member>
|
||||
|
@ -1127,7 +1201,7 @@
|
|||
<var-decl name='ddk_prop' type-id='9c313c2d' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='ddt_key_t' type-id='e0a4a1cb' id='67f6d2cf'/>
|
||||
<typedef-decl name='ddt_key_t' type-id='5fae1718' id='67f6d2cf'/>
|
||||
<enum-decl name='dmu_object_type' id='04b3b0b9'>
|
||||
<underlying-type type-id='9cac1fee'/>
|
||||
<enumerator name='DMU_OT_NONE' value='0'/>
|
||||
|
@ -2621,6 +2695,11 @@
|
|||
<parameter type-id='857bb57e' name='holdsp'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='lzc_get_props' mangled-name='lzc_get_props' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzc_get_props'>
|
||||
<parameter type-id='80f4b756' name='poolname'/>
|
||||
<parameter type-id='857bb57e' name='props'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='lzc_send_wrapper' mangled-name='lzc_send_wrapper' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzc_send_wrapper'>
|
||||
<parameter type-id='2e711a2a' name='func'/>
|
||||
<parameter type-id='95e97e5e' name='orig_fd'/>
|
||||
|
|
|
@ -596,6 +596,12 @@ lzc_get_holds(const char *snapname, nvlist_t **holdsp)
|
|||
return (lzc_ioctl(ZFS_IOC_GET_HOLDS, snapname, NULL, holdsp));
|
||||
}
|
||||
|
||||
int
|
||||
lzc_get_props(const char *poolname, nvlist_t **props)
|
||||
{
|
||||
return (lzc_ioctl(ZFS_IOC_POOL_GET_PROPS, poolname, NULL, props));
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
max_pipe_buffer(int infd)
|
||||
{
|
||||
|
|
|
@ -92,7 +92,8 @@ zk_thread_wrapper(void *arg)
|
|||
}
|
||||
|
||||
kthread_t *
|
||||
zk_thread_create(void (*func)(void *), void *arg, size_t stksize, int state)
|
||||
zk_thread_create(const char *name, void (*func)(void *), void *arg,
|
||||
size_t stksize, int state)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
pthread_t tid;
|
||||
|
@ -140,6 +141,8 @@ zk_thread_create(void (*func)(void *), void *arg, size_t stksize, int state)
|
|||
VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw));
|
||||
VERIFY0(pthread_attr_destroy(&attr));
|
||||
|
||||
pthread_setname_np(tid, name);
|
||||
|
||||
return ((void *)(uintptr_t)tid);
|
||||
}
|
||||
|
||||
|
|
|
@ -295,8 +295,8 @@ taskq_create(const char *name, int nthreads, pri_t pri,
|
|||
}
|
||||
|
||||
for (t = 0; t < nthreads; t++)
|
||||
VERIFY((tq->tq_threadlist[t] = thread_create(NULL, 0,
|
||||
taskq_thread, tq, 0, &p0, TS_RUN, pri)) != NULL);
|
||||
VERIFY((tq->tq_threadlist[t] = thread_create_named(tq->tq_name,
|
||||
NULL, 0, taskq_thread, tq, 0, &p0, TS_RUN, pri)) != NULL);
|
||||
|
||||
return (tq);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
.\" own identifying information:
|
||||
.\" Portions Copyright [yyyy] [name of copyright owner]
|
||||
.\"
|
||||
.Dd January 9, 2024
|
||||
.Dd February 14, 2024
|
||||
.Dt ZFS 4
|
||||
.Os
|
||||
.
|
||||
|
@ -525,10 +525,17 @@ most ZPL operations (e.g. write, create) will return
|
|||
.
|
||||
.It Sy spa_num_allocators Ns = Ns Sy 4 Pq int
|
||||
Determines the number of block alloctators to use per spa instance.
|
||||
Capped by the number of actual CPUs in the system.
|
||||
Capped by the number of actual CPUs in the system via
|
||||
.Sy spa_cpus_per_allocator .
|
||||
.Pp
|
||||
Note that setting this value too high could result in performance
|
||||
degredation and/or excess fragmentation.
|
||||
Set value only applies to pools imported/created after that.
|
||||
.
|
||||
.It Sy spa_cpus_per_allocator Ns = Ns Sy 4 Pq int
|
||||
Determines the minimum number of CPUs in a system for block alloctator
|
||||
per spa instance.
|
||||
Set value only applies to pools imported/created after that.
|
||||
.
|
||||
.It Sy spa_upgrade_errlog_limit Ns = Ns Sy 0 Pq uint
|
||||
Limits the number of on-disk error log entries that will be converted to the
|
||||
|
@ -564,9 +571,8 @@ However, this is limited by
|
|||
Maximum micro ZAP size.
|
||||
A micro ZAP is upgraded to a fat ZAP, once it grows beyond the specified size.
|
||||
.
|
||||
.It Sy zfetch_hole_shift Ns = Ns Sy 2 Pq uint
|
||||
Log2 fraction of holes in speculative prefetch stream allowed for it to
|
||||
proceed.
|
||||
.It Sy zap_shrink_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int
|
||||
If set, adjacent empty ZAP blocks will be collapsed, reducing disk space.
|
||||
.
|
||||
.It Sy zfetch_min_distance Ns = Ns Sy 4194304 Ns B Po 4 MiB Pc Pq uint
|
||||
Min bytes to prefetch per stream.
|
||||
|
@ -900,6 +906,13 @@ Historically used for controlling what reporting was available under
|
|||
.Pa /proc/spl/kstat/zfs .
|
||||
No effect.
|
||||
.
|
||||
.It Sy zfs_deadman_checktime_ms Ns = Ns Sy 60000 Ns ms Po 1 min Pc Pq u64
|
||||
Check time in milliseconds.
|
||||
This defines the frequency at which we check for hung I/O requests
|
||||
and potentially invoke the
|
||||
.Sy zfs_deadman_failmode
|
||||
behavior.
|
||||
.
|
||||
.It Sy zfs_deadman_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int
|
||||
When a pool sync operation takes longer than
|
||||
.Sy zfs_deadman_synctime_ms ,
|
||||
|
@ -915,6 +928,10 @@ By default, the deadman is enabled and set to
|
|||
which results in "hung" I/O operations only being logged.
|
||||
The deadman is automatically disabled when a pool gets suspended.
|
||||
.
|
||||
.It Sy zfs_deadman_events_per_second Ns = Ns Sy 1 Ns /s Pq int
|
||||
Rate limit deadman zevents (which report hung I/O operations) to this many per
|
||||
second.
|
||||
.
|
||||
.It Sy zfs_deadman_failmode Ns = Ns Sy wait Pq charp
|
||||
Controls the failure behavior when the deadman detects a "hung" I/O operation.
|
||||
Valid values are:
|
||||
|
@ -932,13 +949,6 @@ This can be used to facilitate automatic fail-over
|
|||
to a properly configured fail-over partner.
|
||||
.El
|
||||
.
|
||||
.It Sy zfs_deadman_checktime_ms Ns = Ns Sy 60000 Ns ms Po 1 min Pc Pq u64
|
||||
Check time in milliseconds.
|
||||
This defines the frequency at which we check for hung I/O requests
|
||||
and potentially invoke the
|
||||
.Sy zfs_deadman_failmode
|
||||
behavior.
|
||||
.
|
||||
.It Sy zfs_deadman_synctime_ms Ns = Ns Sy 600000 Ns ms Po 10 min Pc Pq u64
|
||||
Interval in milliseconds after which the deadman is triggered and also
|
||||
the interval after which a pool sync operation is considered to be "hung".
|
||||
|
@ -996,8 +1006,7 @@ will result in objects waiting when there is not actually contention on the
|
|||
same object.
|
||||
.
|
||||
.It Sy zfs_slow_io_events_per_second Ns = Ns Sy 20 Ns /s Pq int
|
||||
Rate limit delay and deadman zevents (which report slow I/O operations) to this
|
||||
many per
|
||||
Rate limit delay zevents (which report slow I/O operations) to this many per
|
||||
second.
|
||||
.
|
||||
.It Sy zfs_unflushed_max_mem_amt Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq u64
|
||||
|
@ -2327,8 +2336,8 @@ Prioritize requeued I/O.
|
|||
.
|
||||
.It Sy zio_taskq_batch_pct Ns = Ns Sy 80 Ns % Pq uint
|
||||
Percentage of online CPUs which will run a worker thread for I/O.
|
||||
These workers are responsible for I/O work such as compression and
|
||||
checksum calculations.
|
||||
These workers are responsible for I/O work such as compression, encryption,
|
||||
checksum and parity calculations.
|
||||
Fractional number of CPUs will be rounded down.
|
||||
.Pp
|
||||
The default value of
|
||||
|
@ -2336,33 +2345,36 @@ The default value of
|
|||
was chosen to avoid using all CPUs which can result in
|
||||
latency issues and inconsistent application performance,
|
||||
especially when slower compression and/or checksumming is enabled.
|
||||
Set value only applies to pools imported/created after that.
|
||||
.
|
||||
.It Sy zio_taskq_batch_tpq Ns = Ns Sy 0 Pq uint
|
||||
Number of worker threads per taskq.
|
||||
Lower values improve I/O ordering and CPU utilization,
|
||||
while higher reduces lock contention.
|
||||
Higher values improve I/O ordering and CPU utilization,
|
||||
while lower reduce lock contention.
|
||||
Set value only applies to pools imported/created after that.
|
||||
.Pp
|
||||
If
|
||||
.Sy 0 ,
|
||||
generate a system-dependent value close to 6 threads per taskq.
|
||||
Set value only applies to pools imported/created after that.
|
||||
.
|
||||
.It Sy zio_taskq_wr_iss_ncpus Ns = Ns Sy 0 Pq uint
|
||||
Determines the number of CPUs to run write issue taskqs.
|
||||
.Pp
|
||||
When 0 (the default), the value to use is computed internally
|
||||
as the number of actual CPUs in the system divided by the
|
||||
.Sy spa_num_allocators
|
||||
value.
|
||||
.It Sy zio_taskq_write_tpq Ns = Ns Sy 16 Pq uint
|
||||
Determines the minumum number of threads per write issue taskq.
|
||||
Higher values improve CPU utilization on high throughput,
|
||||
while lower reduce taskq locks contention on high IOPS.
|
||||
Set value only applies to pools imported/created after that.
|
||||
.
|
||||
.It Sy zio_taskq_read Ns = Ns Sy fixed,1,8 null scale null Pq charp
|
||||
Set the queue and thread configuration for the IO read queues.
|
||||
This is an advanced debugging parameter.
|
||||
Don't change this unless you understand what it does.
|
||||
Set values only apply to pools imported/created after that.
|
||||
.
|
||||
.It Sy zio_taskq_write Ns = Ns Sy sync fixed,1,5 scale fixed,1,5 Pq charp
|
||||
.It Sy zio_taskq_write Ns = Ns Sy sync null scale null Pq charp
|
||||
Set the queue and thread configuration for the IO write queues.
|
||||
This is an advanced debugging parameter.
|
||||
Don't change this unless you understand what it does.
|
||||
Set values only apply to pools imported/created after that.
|
||||
.
|
||||
.It Sy zvol_inhibit_dev Ns = Ns Sy 0 Ns | Ns 1 Pq uint
|
||||
Do not create zvol device nodes.
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
.\" Copyright 2018 Nexenta Systems, Inc.
|
||||
.\" Copyright 2019 Joyent, Inc.
|
||||
.\"
|
||||
.Dd March 16, 2022
|
||||
.Dd April 20, 2024
|
||||
.Dt ZFS-SET 8
|
||||
.Os
|
||||
.
|
||||
|
@ -158,6 +158,15 @@ A comma-separated list of types to display, where
|
|||
.Ar type
|
||||
is one of
|
||||
.Sy filesystem , snapshot , volume , bookmark , No or Sy all .
|
||||
.Sy fs ,
|
||||
.Sy snap ,
|
||||
or
|
||||
.Sy vol
|
||||
can be used as aliases for
|
||||
.Sy filesystem ,
|
||||
.Sy snapshot ,
|
||||
or
|
||||
.Sy volume .
|
||||
.El
|
||||
.It Xo
|
||||
.Nm zfs
|
||||
|
|
|
@ -129,6 +129,14 @@ Force a vdev error.
|
|||
.
|
||||
.It Xo
|
||||
.Nm zinject
|
||||
.Fl i Ar seconds
|
||||
.Ar pool
|
||||
.Xc
|
||||
Add an artificial delay during the future import of a pool.
|
||||
This injector is automatically cleared after the import is finished.
|
||||
.
|
||||
.It Xo
|
||||
.Nm zinject
|
||||
.Fl I
|
||||
.Op Fl s Ar seconds Ns | Ns Fl g Ar txgs
|
||||
.Ar pool
|
||||
|
@ -211,9 +219,11 @@ to flip a bit in the data after a read,
|
|||
.It Sy dtl
|
||||
for an ECHILD error,
|
||||
.It Sy io
|
||||
for an EIO error where reopening the device will succeed, or
|
||||
for an EIO error where reopening the device will succeed,
|
||||
.It Sy nxio
|
||||
for an ENXIO error where reopening the device will fail.
|
||||
for an ENXIO error where reopening the device will fail, or
|
||||
.It Sy noop
|
||||
to drop the IO without executing it, and return success.
|
||||
.El
|
||||
.Pp
|
||||
For EIO and ENXIO, the "failed" reads or writes still occur.
|
||||
|
|
|
@ -50,9 +50,10 @@ If the pool was suspended it will be brought back online provided the
|
|||
devices can be accessed.
|
||||
Pools with
|
||||
.Sy multihost
|
||||
enabled which have been suspended cannot be resumed.
|
||||
While the pool was suspended, it may have been imported on
|
||||
another host, and resuming I/O could result in pool damage.
|
||||
enabled which have been suspended cannot be resumed when there is evidence
|
||||
that the pool was imported by another host.
|
||||
The same checks performed during an import will be applied before the clear
|
||||
proceeds.
|
||||
.Bl -tag -width Ds
|
||||
.It Fl -power
|
||||
Power on the devices's slot in the storage enclosure and wait for the device
|
||||
|
|
|
@ -364,7 +364,7 @@ that is, the bits set in the good data which are cleared in the bad data.
|
|||
.Sh I/O STAGES
|
||||
The ZFS I/O pipeline is comprised of various stages which are defined below.
|
||||
The individual stages are used to construct these basic I/O
|
||||
operations: Read, Write, Free, Claim, Ioctl and Trim.
|
||||
operations: Read, Write, Free, Claim, Flush and Trim.
|
||||
These stages may be
|
||||
set on an event to describe the life cycle of a given I/O request.
|
||||
.Pp
|
||||
|
@ -373,7 +373,7 @@ tab(:);
|
|||
l l l .
|
||||
Stage:Bit Mask:Operations
|
||||
_:_:_
|
||||
ZIO_STAGE_OPEN:0x00000001:RWFCIT
|
||||
ZIO_STAGE_OPEN:0x00000001:RWFCXT
|
||||
|
||||
ZIO_STAGE_READ_BP_INIT:0x00000002:R-----
|
||||
ZIO_STAGE_WRITE_BP_INIT:0x00000004:-W----
|
||||
|
@ -403,13 +403,13 @@ ZIO_STAGE_DVA_CLAIM:0x00080000:---C--
|
|||
|
||||
ZIO_STAGE_READY:0x00100000:RWFCIT
|
||||
|
||||
ZIO_STAGE_VDEV_IO_START:0x00200000:RW--IT
|
||||
ZIO_STAGE_VDEV_IO_DONE:0x00400000:RW--IT
|
||||
ZIO_STAGE_VDEV_IO_ASSESS:0x00800000:RW--IT
|
||||
ZIO_STAGE_VDEV_IO_START:0x00200000:RW--XT
|
||||
ZIO_STAGE_VDEV_IO_DONE:0x00400000:RW--XT
|
||||
ZIO_STAGE_VDEV_IO_ASSESS:0x00800000:RW--XT
|
||||
|
||||
ZIO_STAGE_CHECKSUM_VERIFY:0x01000000:R-----
|
||||
|
||||
ZIO_STAGE_DONE:0x02000000:RWFCIT
|
||||
ZIO_STAGE_DONE:0x02000000:RWFCXT
|
||||
.TE
|
||||
.
|
||||
.Sh I/O FLAGS
|
||||
|
|
|
@ -102,10 +102,7 @@ ICP_OBJS := \
|
|||
algs/blake3/blake3_generic.o \
|
||||
algs/blake3/blake3_impl.o \
|
||||
algs/edonr/edonr.o \
|
||||
algs/modes/cbc.o \
|
||||
algs/modes/ccm.o \
|
||||
algs/modes/ctr.o \
|
||||
algs/modes/ecb.o \
|
||||
algs/modes/gcm.o \
|
||||
algs/modes/gcm_generic.o \
|
||||
algs/modes/modes.o \
|
||||
|
@ -126,7 +123,6 @@ ICP_OBJS := \
|
|||
illumos-crypto.o \
|
||||
io/aes.o \
|
||||
io/sha2_mod.o \
|
||||
io/skein_mod.o \
|
||||
spi/kcf_spi.o
|
||||
|
||||
ICP_OBJS_X86_64 := \
|
||||
|
|
|
@ -75,25 +75,17 @@ aes_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
|
|||
aes_ctx_t *aes_ctx = ctx;
|
||||
int rv;
|
||||
|
||||
if (aes_ctx->ac_flags & CTR_MODE) {
|
||||
rv = ctr_mode_contiguous_blocks(ctx, data, length, out,
|
||||
AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
|
||||
} else if (aes_ctx->ac_flags & CCM_MODE) {
|
||||
if (aes_ctx->ac_flags & CCM_MODE) {
|
||||
rv = ccm_mode_encrypt_contiguous_blocks(ctx, data, length,
|
||||
out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
|
||||
aes_xor_block);
|
||||
} else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) {
|
||||
} else if (aes_ctx->ac_flags & GCM_MODE) {
|
||||
rv = gcm_mode_encrypt_contiguous_blocks(ctx, data, length,
|
||||
out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
|
||||
aes_xor_block);
|
||||
} else if (aes_ctx->ac_flags & CBC_MODE) {
|
||||
rv = cbc_encrypt_contiguous_blocks(ctx,
|
||||
data, length, out, AES_BLOCK_LEN, aes_encrypt_block,
|
||||
aes_copy_block, aes_xor_block);
|
||||
} else {
|
||||
rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
|
||||
AES_BLOCK_LEN, aes_encrypt_block);
|
||||
}
|
||||
else
|
||||
__builtin_unreachable();
|
||||
return (rv);
|
||||
}
|
||||
|
||||
|
@ -108,28 +100,15 @@ aes_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
|
|||
aes_ctx_t *aes_ctx = ctx;
|
||||
int rv;
|
||||
|
||||
if (aes_ctx->ac_flags & CTR_MODE) {
|
||||
rv = ctr_mode_contiguous_blocks(ctx, data, length, out,
|
||||
AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
|
||||
if (rv == CRYPTO_DATA_LEN_RANGE)
|
||||
rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
|
||||
} else if (aes_ctx->ac_flags & CCM_MODE) {
|
||||
if (aes_ctx->ac_flags & CCM_MODE) {
|
||||
rv = ccm_mode_decrypt_contiguous_blocks(ctx, data, length,
|
||||
out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
|
||||
aes_xor_block);
|
||||
} else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) {
|
||||
} else if (aes_ctx->ac_flags & GCM_MODE) {
|
||||
rv = gcm_mode_decrypt_contiguous_blocks(ctx, data, length,
|
||||
out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
|
||||
aes_xor_block);
|
||||
} else if (aes_ctx->ac_flags & CBC_MODE) {
|
||||
rv = cbc_decrypt_contiguous_blocks(ctx, data, length, out,
|
||||
AES_BLOCK_LEN, aes_decrypt_block, aes_copy_block,
|
||||
aes_xor_block);
|
||||
} else {
|
||||
rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
|
||||
AES_BLOCK_LEN, aes_decrypt_block);
|
||||
if (rv == CRYPTO_DATA_LEN_RANGE)
|
||||
rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
|
||||
}
|
||||
} else
|
||||
__builtin_unreachable();
|
||||
return (rv);
|
||||
}
|
||||
|
|
|
@ -1,264 +0,0 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <modes/modes.h>
|
||||
#include <sys/crypto/common.h>
|
||||
#include <sys/crypto/impl.h>
|
||||
|
||||
/*
|
||||
* Algorithm independent CBC functions.
|
||||
*/
|
||||
int
|
||||
cbc_encrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length,
|
||||
crypto_data_t *out, size_t block_size,
|
||||
int (*encrypt)(const void *, const uint8_t *, uint8_t *),
|
||||
void (*copy_block)(uint8_t *, uint8_t *),
|
||||
void (*xor_block)(uint8_t *, uint8_t *))
|
||||
{
|
||||
size_t remainder = length;
|
||||
size_t need = 0;
|
||||
uint8_t *datap = (uint8_t *)data;
|
||||
uint8_t *blockp;
|
||||
uint8_t *lastp;
|
||||
void *iov_or_mp;
|
||||
offset_t offset;
|
||||
uint8_t *out_data_1;
|
||||
uint8_t *out_data_2;
|
||||
size_t out_data_1_len;
|
||||
|
||||
if (length + ctx->cbc_remainder_len < block_size) {
|
||||
/* accumulate bytes here and return */
|
||||
memcpy((uint8_t *)ctx->cbc_remainder + ctx->cbc_remainder_len,
|
||||
datap,
|
||||
length);
|
||||
ctx->cbc_remainder_len += length;
|
||||
ctx->cbc_copy_to = datap;
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
lastp = (uint8_t *)ctx->cbc_iv;
|
||||
crypto_init_ptrs(out, &iov_or_mp, &offset);
|
||||
|
||||
do {
|
||||
/* Unprocessed data from last call. */
|
||||
if (ctx->cbc_remainder_len > 0) {
|
||||
need = block_size - ctx->cbc_remainder_len;
|
||||
|
||||
if (need > remainder)
|
||||
return (CRYPTO_DATA_LEN_RANGE);
|
||||
|
||||
memcpy(&((uint8_t *)ctx->cbc_remainder)
|
||||
[ctx->cbc_remainder_len], datap, need);
|
||||
|
||||
blockp = (uint8_t *)ctx->cbc_remainder;
|
||||
} else {
|
||||
blockp = datap;
|
||||
}
|
||||
|
||||
/*
|
||||
* XOR the previous cipher block or IV with the
|
||||
* current clear block.
|
||||
*/
|
||||
xor_block(blockp, lastp);
|
||||
encrypt(ctx->cbc_keysched, lastp, lastp);
|
||||
crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
|
||||
&out_data_1_len, &out_data_2, block_size);
|
||||
|
||||
/* copy block to where it belongs */
|
||||
if (out_data_1_len == block_size) {
|
||||
copy_block(lastp, out_data_1);
|
||||
} else {
|
||||
memcpy(out_data_1, lastp, out_data_1_len);
|
||||
if (out_data_2 != NULL) {
|
||||
memcpy(out_data_2,
|
||||
lastp + out_data_1_len,
|
||||
block_size - out_data_1_len);
|
||||
}
|
||||
}
|
||||
/* update offset */
|
||||
out->cd_offset += block_size;
|
||||
|
||||
/* Update pointer to next block of data to be processed. */
|
||||
if (ctx->cbc_remainder_len != 0) {
|
||||
datap += need;
|
||||
ctx->cbc_remainder_len = 0;
|
||||
} else {
|
||||
datap += block_size;
|
||||
}
|
||||
|
||||
remainder = (size_t)&data[length] - (size_t)datap;
|
||||
|
||||
/* Incomplete last block. */
|
||||
if (remainder > 0 && remainder < block_size) {
|
||||
memcpy(ctx->cbc_remainder, datap, remainder);
|
||||
ctx->cbc_remainder_len = remainder;
|
||||
ctx->cbc_copy_to = datap;
|
||||
goto out;
|
||||
}
|
||||
ctx->cbc_copy_to = NULL;
|
||||
|
||||
} while (remainder > 0);
|
||||
|
||||
out:
|
||||
/*
|
||||
* Save the last encrypted block in the context.
|
||||
*/
|
||||
if (ctx->cbc_lastp != NULL) {
|
||||
copy_block((uint8_t *)ctx->cbc_lastp, (uint8_t *)ctx->cbc_iv);
|
||||
ctx->cbc_lastp = (uint8_t *)ctx->cbc_iv;
|
||||
}
|
||||
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
#define OTHER(a, ctx) \
|
||||
(((a) == (ctx)->cbc_lastblock) ? (ctx)->cbc_iv : (ctx)->cbc_lastblock)
|
||||
|
||||
int
|
||||
cbc_decrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length,
|
||||
crypto_data_t *out, size_t block_size,
|
||||
int (*decrypt)(const void *, const uint8_t *, uint8_t *),
|
||||
void (*copy_block)(uint8_t *, uint8_t *),
|
||||
void (*xor_block)(uint8_t *, uint8_t *))
|
||||
{
|
||||
size_t remainder = length;
|
||||
size_t need = 0;
|
||||
uint8_t *datap = (uint8_t *)data;
|
||||
uint8_t *blockp;
|
||||
uint8_t *lastp;
|
||||
void *iov_or_mp;
|
||||
offset_t offset;
|
||||
uint8_t *out_data_1;
|
||||
uint8_t *out_data_2;
|
||||
size_t out_data_1_len;
|
||||
|
||||
if (length + ctx->cbc_remainder_len < block_size) {
|
||||
/* accumulate bytes here and return */
|
||||
memcpy((uint8_t *)ctx->cbc_remainder + ctx->cbc_remainder_len,
|
||||
datap,
|
||||
length);
|
||||
ctx->cbc_remainder_len += length;
|
||||
ctx->cbc_copy_to = datap;
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
lastp = ctx->cbc_lastp;
|
||||
crypto_init_ptrs(out, &iov_or_mp, &offset);
|
||||
|
||||
do {
|
||||
/* Unprocessed data from last call. */
|
||||
if (ctx->cbc_remainder_len > 0) {
|
||||
need = block_size - ctx->cbc_remainder_len;
|
||||
|
||||
if (need > remainder)
|
||||
return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
|
||||
|
||||
memcpy(&((uint8_t *)ctx->cbc_remainder)
|
||||
[ctx->cbc_remainder_len], datap, need);
|
||||
|
||||
blockp = (uint8_t *)ctx->cbc_remainder;
|
||||
} else {
|
||||
blockp = datap;
|
||||
}
|
||||
|
||||
/* LINTED: pointer alignment */
|
||||
copy_block(blockp, (uint8_t *)OTHER((uint64_t *)lastp, ctx));
|
||||
|
||||
decrypt(ctx->cbc_keysched, blockp,
|
||||
(uint8_t *)ctx->cbc_remainder);
|
||||
blockp = (uint8_t *)ctx->cbc_remainder;
|
||||
|
||||
/*
|
||||
* XOR the previous cipher block or IV with the
|
||||
* currently decrypted block.
|
||||
*/
|
||||
xor_block(lastp, blockp);
|
||||
|
||||
/* LINTED: pointer alignment */
|
||||
lastp = (uint8_t *)OTHER((uint64_t *)lastp, ctx);
|
||||
|
||||
crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
|
||||
&out_data_1_len, &out_data_2, block_size);
|
||||
|
||||
memcpy(out_data_1, blockp, out_data_1_len);
|
||||
if (out_data_2 != NULL) {
|
||||
memcpy(out_data_2, blockp + out_data_1_len,
|
||||
block_size - out_data_1_len);
|
||||
}
|
||||
|
||||
/* update offset */
|
||||
out->cd_offset += block_size;
|
||||
|
||||
/* Update pointer to next block of data to be processed. */
|
||||
if (ctx->cbc_remainder_len != 0) {
|
||||
datap += need;
|
||||
ctx->cbc_remainder_len = 0;
|
||||
} else {
|
||||
datap += block_size;
|
||||
}
|
||||
|
||||
remainder = (size_t)&data[length] - (size_t)datap;
|
||||
|
||||
/* Incomplete last block. */
|
||||
if (remainder > 0 && remainder < block_size) {
|
||||
memcpy(ctx->cbc_remainder, datap, remainder);
|
||||
ctx->cbc_remainder_len = remainder;
|
||||
ctx->cbc_lastp = lastp;
|
||||
ctx->cbc_copy_to = datap;
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
ctx->cbc_copy_to = NULL;
|
||||
|
||||
} while (remainder > 0);
|
||||
|
||||
ctx->cbc_lastp = lastp;
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
cbc_init_ctx(cbc_ctx_t *cbc_ctx, char *param, size_t param_len,
|
||||
size_t block_size, void (*copy_block)(uint8_t *, uint64_t *))
|
||||
{
|
||||
/* Copy IV into context. */
|
||||
ASSERT3P(param, !=, NULL);
|
||||
ASSERT3U(param_len, ==, block_size);
|
||||
|
||||
copy_block((uchar_t *)param, cbc_ctx->cbc_iv);
|
||||
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
void *
|
||||
cbc_alloc_ctx(int kmflag)
|
||||
{
|
||||
cbc_ctx_t *cbc_ctx;
|
||||
|
||||
if ((cbc_ctx = kmem_zalloc(sizeof (cbc_ctx_t), kmflag)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
cbc_ctx->cbc_flags = CBC_MODE;
|
||||
return (cbc_ctx);
|
||||
}
|
|
@ -1,227 +0,0 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <modes/modes.h>
|
||||
#include <sys/crypto/common.h>
|
||||
#include <sys/crypto/impl.h>
|
||||
#include <sys/byteorder.h>
|
||||
|
||||
/*
|
||||
* Encrypt and decrypt multiple blocks of data in counter mode.
|
||||
*/
|
||||
int
|
||||
ctr_mode_contiguous_blocks(ctr_ctx_t *ctx, char *data, size_t length,
|
||||
crypto_data_t *out, size_t block_size,
|
||||
int (*cipher)(const void *ks, const uint8_t *pt, uint8_t *ct),
|
||||
void (*xor_block)(uint8_t *, uint8_t *))
|
||||
{
|
||||
size_t remainder = length;
|
||||
size_t need = 0;
|
||||
uint8_t *datap = (uint8_t *)data;
|
||||
uint8_t *blockp;
|
||||
uint8_t *lastp;
|
||||
void *iov_or_mp;
|
||||
offset_t offset;
|
||||
uint8_t *out_data_1;
|
||||
uint8_t *out_data_2;
|
||||
size_t out_data_1_len;
|
||||
uint64_t lower_counter, upper_counter;
|
||||
|
||||
if (length + ctx->ctr_remainder_len < block_size) {
|
||||
/* accumulate bytes here and return */
|
||||
memcpy((uint8_t *)ctx->ctr_remainder + ctx->ctr_remainder_len,
|
||||
datap,
|
||||
length);
|
||||
ctx->ctr_remainder_len += length;
|
||||
ctx->ctr_copy_to = datap;
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
crypto_init_ptrs(out, &iov_or_mp, &offset);
|
||||
|
||||
do {
|
||||
/* Unprocessed data from last call. */
|
||||
if (ctx->ctr_remainder_len > 0) {
|
||||
need = block_size - ctx->ctr_remainder_len;
|
||||
|
||||
if (need > remainder)
|
||||
return (CRYPTO_DATA_LEN_RANGE);
|
||||
|
||||
memcpy(&((uint8_t *)ctx->ctr_remainder)
|
||||
[ctx->ctr_remainder_len], datap, need);
|
||||
|
||||
blockp = (uint8_t *)ctx->ctr_remainder;
|
||||
} else {
|
||||
blockp = datap;
|
||||
}
|
||||
|
||||
/* ctr_cb is the counter block */
|
||||
cipher(ctx->ctr_keysched, (uint8_t *)ctx->ctr_cb,
|
||||
(uint8_t *)ctx->ctr_tmp);
|
||||
|
||||
lastp = (uint8_t *)ctx->ctr_tmp;
|
||||
|
||||
/*
|
||||
* Increment Counter.
|
||||
*/
|
||||
lower_counter = ntohll(ctx->ctr_cb[1] & ctx->ctr_lower_mask);
|
||||
lower_counter = htonll(lower_counter + 1);
|
||||
lower_counter &= ctx->ctr_lower_mask;
|
||||
ctx->ctr_cb[1] = (ctx->ctr_cb[1] & ~(ctx->ctr_lower_mask)) |
|
||||
lower_counter;
|
||||
|
||||
/* wrap around */
|
||||
if (lower_counter == 0) {
|
||||
upper_counter =
|
||||
ntohll(ctx->ctr_cb[0] & ctx->ctr_upper_mask);
|
||||
upper_counter = htonll(upper_counter + 1);
|
||||
upper_counter &= ctx->ctr_upper_mask;
|
||||
ctx->ctr_cb[0] =
|
||||
(ctx->ctr_cb[0] & ~(ctx->ctr_upper_mask)) |
|
||||
upper_counter;
|
||||
}
|
||||
|
||||
/*
|
||||
* XOR encrypted counter block with the current clear block.
|
||||
*/
|
||||
xor_block(blockp, lastp);
|
||||
|
||||
crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
|
||||
&out_data_1_len, &out_data_2, block_size);
|
||||
|
||||
/* copy block to where it belongs */
|
||||
memcpy(out_data_1, lastp, out_data_1_len);
|
||||
if (out_data_2 != NULL) {
|
||||
memcpy(out_data_2, lastp + out_data_1_len,
|
||||
block_size - out_data_1_len);
|
||||
}
|
||||
/* update offset */
|
||||
out->cd_offset += block_size;
|
||||
|
||||
/* Update pointer to next block of data to be processed. */
|
||||
if (ctx->ctr_remainder_len != 0) {
|
||||
datap += need;
|
||||
ctx->ctr_remainder_len = 0;
|
||||
} else {
|
||||
datap += block_size;
|
||||
}
|
||||
|
||||
remainder = (size_t)&data[length] - (size_t)datap;
|
||||
|
||||
/* Incomplete last block. */
|
||||
if (remainder > 0 && remainder < block_size) {
|
||||
memcpy(ctx->ctr_remainder, datap, remainder);
|
||||
ctx->ctr_remainder_len = remainder;
|
||||
ctx->ctr_copy_to = datap;
|
||||
goto out;
|
||||
}
|
||||
ctx->ctr_copy_to = NULL;
|
||||
|
||||
} while (remainder > 0);
|
||||
|
||||
out:
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
ctr_mode_final(ctr_ctx_t *ctx, crypto_data_t *out,
|
||||
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *))
|
||||
{
|
||||
uint8_t *lastp;
|
||||
void *iov_or_mp;
|
||||
offset_t offset;
|
||||
uint8_t *out_data_1;
|
||||
uint8_t *out_data_2;
|
||||
size_t out_data_1_len;
|
||||
uint8_t *p;
|
||||
int i;
|
||||
|
||||
if (out->cd_length < ctx->ctr_remainder_len)
|
||||
return (CRYPTO_DATA_LEN_RANGE);
|
||||
|
||||
encrypt_block(ctx->ctr_keysched, (uint8_t *)ctx->ctr_cb,
|
||||
(uint8_t *)ctx->ctr_tmp);
|
||||
|
||||
lastp = (uint8_t *)ctx->ctr_tmp;
|
||||
p = (uint8_t *)ctx->ctr_remainder;
|
||||
for (i = 0; i < ctx->ctr_remainder_len; i++) {
|
||||
p[i] ^= lastp[i];
|
||||
}
|
||||
|
||||
crypto_init_ptrs(out, &iov_or_mp, &offset);
|
||||
crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
|
||||
&out_data_1_len, &out_data_2, ctx->ctr_remainder_len);
|
||||
|
||||
memcpy(out_data_1, p, out_data_1_len);
|
||||
if (out_data_2 != NULL) {
|
||||
memcpy(out_data_2,
|
||||
(uint8_t *)p + out_data_1_len,
|
||||
ctx->ctr_remainder_len - out_data_1_len);
|
||||
}
|
||||
out->cd_offset += ctx->ctr_remainder_len;
|
||||
ctx->ctr_remainder_len = 0;
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
ctr_init_ctx(ctr_ctx_t *ctr_ctx, ulong_t count, uint8_t *cb,
|
||||
void (*copy_block)(uint8_t *, uint8_t *))
|
||||
{
|
||||
uint64_t upper_mask = 0;
|
||||
uint64_t lower_mask = 0;
|
||||
|
||||
if (count == 0 || count > 128) {
|
||||
return (CRYPTO_MECHANISM_PARAM_INVALID);
|
||||
}
|
||||
/* upper 64 bits of the mask */
|
||||
if (count >= 64) {
|
||||
count -= 64;
|
||||
upper_mask = (count == 64) ? UINT64_MAX : (1ULL << count) - 1;
|
||||
lower_mask = UINT64_MAX;
|
||||
} else {
|
||||
/* now the lower 63 bits */
|
||||
lower_mask = (1ULL << count) - 1;
|
||||
}
|
||||
ctr_ctx->ctr_lower_mask = htonll(lower_mask);
|
||||
ctr_ctx->ctr_upper_mask = htonll(upper_mask);
|
||||
|
||||
copy_block(cb, (uchar_t *)ctr_ctx->ctr_cb);
|
||||
ctr_ctx->ctr_lastp = (uint8_t *)&ctr_ctx->ctr_cb[0];
|
||||
ctr_ctx->ctr_flags |= CTR_MODE;
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
void *
|
||||
ctr_alloc_ctx(int kmflag)
|
||||
{
|
||||
ctr_ctx_t *ctr_ctx;
|
||||
|
||||
if ((ctr_ctx = kmem_zalloc(sizeof (ctr_ctx_t), kmflag)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
ctr_ctx->ctr_flags = CTR_MODE;
|
||||
return (ctr_ctx);
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <modes/modes.h>
|
||||
#include <sys/crypto/common.h>
|
||||
#include <sys/crypto/impl.h>
|
||||
|
||||
/*
|
||||
* Algorithm independent ECB functions.
|
||||
*/
|
||||
int
|
||||
ecb_cipher_contiguous_blocks(ecb_ctx_t *ctx, char *data, size_t length,
|
||||
crypto_data_t *out, size_t block_size,
|
||||
int (*cipher)(const void *ks, const uint8_t *pt, uint8_t *ct))
|
||||
{
|
||||
size_t remainder = length;
|
||||
size_t need = 0;
|
||||
uint8_t *datap = (uint8_t *)data;
|
||||
uint8_t *blockp;
|
||||
uint8_t *lastp;
|
||||
void *iov_or_mp;
|
||||
offset_t offset;
|
||||
uint8_t *out_data_1;
|
||||
uint8_t *out_data_2;
|
||||
size_t out_data_1_len;
|
||||
|
||||
if (length + ctx->ecb_remainder_len < block_size) {
|
||||
/* accumulate bytes here and return */
|
||||
memcpy((uint8_t *)ctx->ecb_remainder + ctx->ecb_remainder_len,
|
||||
datap,
|
||||
length);
|
||||
ctx->ecb_remainder_len += length;
|
||||
ctx->ecb_copy_to = datap;
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
lastp = (uint8_t *)ctx->ecb_iv;
|
||||
crypto_init_ptrs(out, &iov_or_mp, &offset);
|
||||
|
||||
do {
|
||||
/* Unprocessed data from last call. */
|
||||
if (ctx->ecb_remainder_len > 0) {
|
||||
need = block_size - ctx->ecb_remainder_len;
|
||||
|
||||
if (need > remainder)
|
||||
return (CRYPTO_DATA_LEN_RANGE);
|
||||
|
||||
memcpy(&((uint8_t *)ctx->ecb_remainder)
|
||||
[ctx->ecb_remainder_len], datap, need);
|
||||
|
||||
blockp = (uint8_t *)ctx->ecb_remainder;
|
||||
} else {
|
||||
blockp = datap;
|
||||
}
|
||||
|
||||
cipher(ctx->ecb_keysched, blockp, lastp);
|
||||
crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
|
||||
&out_data_1_len, &out_data_2, block_size);
|
||||
|
||||
/* copy block to where it belongs */
|
||||
memcpy(out_data_1, lastp, out_data_1_len);
|
||||
if (out_data_2 != NULL) {
|
||||
memcpy(out_data_2, lastp + out_data_1_len,
|
||||
block_size - out_data_1_len);
|
||||
}
|
||||
/* update offset */
|
||||
out->cd_offset += block_size;
|
||||
|
||||
/* Update pointer to next block of data to be processed. */
|
||||
if (ctx->ecb_remainder_len != 0) {
|
||||
datap += need;
|
||||
ctx->ecb_remainder_len = 0;
|
||||
} else {
|
||||
datap += block_size;
|
||||
}
|
||||
|
||||
remainder = (size_t)&data[length] - (size_t)datap;
|
||||
|
||||
/* Incomplete last block. */
|
||||
if (remainder > 0 && remainder < block_size) {
|
||||
memcpy(ctx->ecb_remainder, datap, remainder);
|
||||
ctx->ecb_remainder_len = remainder;
|
||||
ctx->ecb_copy_to = datap;
|
||||
goto out;
|
||||
}
|
||||
ctx->ecb_copy_to = NULL;
|
||||
|
||||
} while (remainder > 0);
|
||||
|
||||
out:
|
||||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
void *
|
||||
ecb_alloc_ctx(int kmflag)
|
||||
{
|
||||
ecb_ctx_t *ecb_ctx;
|
||||
|
||||
if ((ecb_ctx = kmem_zalloc(sizeof (ecb_ctx_t), kmflag)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
ecb_ctx->ecb_flags = ECB_MODE;
|
||||
return (ecb_ctx);
|
||||
}
|
|
@ -50,11 +50,6 @@
|
|||
static uint32_t icp_gcm_impl = IMPL_FASTEST;
|
||||
static uint32_t user_sel_impl = IMPL_FASTEST;
|
||||
|
||||
static inline int gcm_init_ctx_impl(boolean_t, gcm_ctx_t *, char *, size_t,
|
||||
int (*)(const void *, const uint8_t *, uint8_t *),
|
||||
void (*)(uint8_t *, uint8_t *),
|
||||
void (*)(uint8_t *, uint8_t *));
|
||||
|
||||
#ifdef CAN_USE_GCM_ASM
|
||||
/* Does the architecture we run on support the MOVBE instruction? */
|
||||
boolean_t gcm_avx_can_use_movbe = B_FALSE;
|
||||
|
@ -590,40 +585,11 @@ gcm_init(gcm_ctx_t *ctx, const uint8_t *iv, size_t iv_len,
|
|||
return (CRYPTO_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function is called at encrypt or decrypt init time
|
||||
* for AES GCM mode.
|
||||
*/
|
||||
int
|
||||
gcm_init_ctx(gcm_ctx_t *gcm_ctx, char *param, size_t block_size,
|
||||
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
|
||||
void (*copy_block)(uint8_t *, uint8_t *),
|
||||
void (*xor_block)(uint8_t *, uint8_t *))
|
||||
{
|
||||
return (gcm_init_ctx_impl(B_FALSE, gcm_ctx, param, block_size,
|
||||
encrypt_block, copy_block, xor_block));
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function is called at encrypt or decrypt init time
|
||||
* for AES GMAC mode.
|
||||
*/
|
||||
int
|
||||
gmac_init_ctx(gcm_ctx_t *gcm_ctx, char *param, size_t block_size,
|
||||
int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
|
||||
void (*copy_block)(uint8_t *, uint8_t *),
|
||||
void (*xor_block)(uint8_t *, uint8_t *))
|
||||
{
|
||||
return (gcm_init_ctx_impl(B_TRUE, gcm_ctx, param, block_size,
|
||||
encrypt_block, copy_block, xor_block));
|
||||
}
|
||||
|
||||
/*
|
||||
* Init the GCM context struct. Handle the cycle and avx implementations here.
|
||||
* Initialization of a GMAC context differs slightly from a GCM context.
|
||||
*/
|
||||
static inline int
|
||||
gcm_init_ctx_impl(boolean_t gmac_mode, gcm_ctx_t *gcm_ctx, char *param,
|
||||
int
|
||||
gcm_init_ctx(gcm_ctx_t *gcm_ctx, char *param,
|
||||
size_t block_size, int (*encrypt_block)(const void *, const uint8_t *,
|
||||
uint8_t *), void (*copy_block)(uint8_t *, uint8_t *),
|
||||
void (*xor_block)(uint8_t *, uint8_t *))
|
||||
|
@ -635,22 +601,16 @@ gcm_init_ctx_impl(boolean_t gmac_mode, gcm_ctx_t *gcm_ctx, char *param,
|
|||
if (param != NULL) {
|
||||
gcm_param = (CK_AES_GCM_PARAMS *)(void *)param;
|
||||
|
||||
if (gmac_mode == B_FALSE) {
|
||||
/* GCM mode. */
|
||||
if ((rv = gcm_validate_args(gcm_param)) != 0) {
|
||||
return (rv);
|
||||
}
|
||||
gcm_ctx->gcm_flags |= GCM_MODE;
|
||||
|
||||
size_t tbits = gcm_param->ulTagBits;
|
||||
tag_len = CRYPTO_BITS2BYTES(tbits);
|
||||
iv_len = gcm_param->ulIvLen;
|
||||
} else {
|
||||
/* GMAC mode. */
|
||||
gcm_ctx->gcm_flags |= GMAC_MODE;
|
||||
tag_len = CRYPTO_BITS2BYTES(AES_GMAC_TAG_BITS);
|
||||
iv_len = AES_GMAC_IV_LEN;
|
||||
/* GCM mode. */
|
||||
if ((rv = gcm_validate_args(gcm_param)) != 0) {
|
||||
return (rv);
|
||||
}
|
||||
gcm_ctx->gcm_flags |= GCM_MODE;
|
||||
|
||||
size_t tbits = gcm_param->ulTagBits;
|
||||
tag_len = CRYPTO_BITS2BYTES(tbits);
|
||||
iv_len = gcm_param->ulIvLen;
|
||||
|
||||
gcm_ctx->gcm_tag_len = tag_len;
|
||||
gcm_ctx->gcm_processed_data_len = 0;
|
||||
|
||||
|
@ -684,10 +644,9 @@ gcm_init_ctx_impl(boolean_t gmac_mode, gcm_ctx_t *gcm_ctx, char *param,
|
|||
}
|
||||
/*
|
||||
* If this is a GCM context, use the MOVBE and the BSWAP
|
||||
* variants alternately. GMAC contexts code paths do not
|
||||
* use the MOVBE instruction.
|
||||
* variants alternately.
|
||||
*/
|
||||
if (gcm_ctx->gcm_use_avx == B_TRUE && gmac_mode == B_FALSE &&
|
||||
if (gcm_ctx->gcm_use_avx == B_TRUE &&
|
||||
zfs_movbe_available() == B_TRUE) {
|
||||
(void) atomic_toggle_boolean_nv(
|
||||
(volatile boolean_t *)&gcm_avx_can_use_movbe);
|
||||
|
@ -758,18 +717,6 @@ gcm_alloc_ctx(int kmflag)
|
|||
return (gcm_ctx);
|
||||
}
|
||||
|
||||
void *
|
||||
gmac_alloc_ctx(int kmflag)
|
||||
{
|
||||
gcm_ctx_t *gcm_ctx;
|
||||
|
||||
if ((gcm_ctx = kmem_zalloc(sizeof (gcm_ctx_t), kmflag)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
gcm_ctx->gcm_flags = GMAC_MODE;
|
||||
return (gcm_ctx);
|
||||
}
|
||||
|
||||
/* GCM implementation that contains the fastest methods */
|
||||
static gcm_impl_ops_t gcm_fastest_impl = {
|
||||
.name = "fastest"
|
||||
|
|
|
@ -126,20 +126,7 @@ crypto_free_mode_ctx(void *ctx)
|
|||
{
|
||||
common_ctx_t *common_ctx = (common_ctx_t *)ctx;
|
||||
|
||||
switch (common_ctx->cc_flags &
|
||||
(ECB_MODE|CBC_MODE|CTR_MODE|CCM_MODE|GCM_MODE|GMAC_MODE)) {
|
||||
case ECB_MODE:
|
||||
kmem_free(common_ctx, sizeof (ecb_ctx_t));
|
||||
break;
|
||||
|
||||
case CBC_MODE:
|
||||
kmem_free(common_ctx, sizeof (cbc_ctx_t));
|
||||
break;
|
||||
|
||||
case CTR_MODE:
|
||||
kmem_free(common_ctx, sizeof (ctr_ctx_t));
|
||||
break;
|
||||
|
||||
switch (common_ctx->cc_flags & (CCM_MODE|GCM_MODE)) {
|
||||
case CCM_MODE:
|
||||
if (((ccm_ctx_t *)ctx)->ccm_pt_buf != NULL)
|
||||
vmem_free(((ccm_ctx_t *)ctx)->ccm_pt_buf,
|
||||
|
@ -149,9 +136,12 @@ crypto_free_mode_ctx(void *ctx)
|
|||
break;
|
||||
|
||||
case GCM_MODE:
|
||||
case GMAC_MODE:
|
||||
gcm_clear_ctx((gcm_ctx_t *)ctx);
|
||||
kmem_free(ctx, sizeof (gcm_ctx_t));
|
||||
break;
|
||||
|
||||
default:
|
||||
__builtin_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -400,15 +400,13 @@ SHA2Init(int algotype, SHA2_CTX *ctx)
|
|||
sha256_ctx *ctx256 = &ctx->sha256;
|
||||
sha512_ctx *ctx512 = &ctx->sha512;
|
||||
|
||||
ASSERT3S(algotype, >=, SHA256_MECH_INFO_TYPE);
|
||||
ASSERT3S(algotype, <=, SHA512_256_MECH_INFO_TYPE);
|
||||
ASSERT3S(algotype, >=, SHA512_HMAC_MECH_INFO_TYPE);
|
||||
ASSERT3S(algotype, <=, SHA512_256);
|
||||
|
||||
memset(ctx, 0, sizeof (*ctx));
|
||||
ctx->algotype = algotype;
|
||||
switch (ctx->algotype) {
|
||||
case SHA256_MECH_INFO_TYPE:
|
||||
case SHA256_HMAC_MECH_INFO_TYPE:
|
||||
case SHA256_HMAC_GEN_MECH_INFO_TYPE:
|
||||
case SHA256:
|
||||
ctx256->state[0] = 0x6a09e667;
|
||||
ctx256->state[1] = 0xbb67ae85;
|
||||
ctx256->state[2] = 0x3c6ef372;
|
||||
|
@ -420,24 +418,8 @@ SHA2Init(int algotype, SHA2_CTX *ctx)
|
|||
ctx256->count[0] = 0;
|
||||
ctx256->ops = sha256_get_ops();
|
||||
break;
|
||||
case SHA384_MECH_INFO_TYPE:
|
||||
case SHA384_HMAC_MECH_INFO_TYPE:
|
||||
case SHA384_HMAC_GEN_MECH_INFO_TYPE:
|
||||
ctx512->state[0] = 0xcbbb9d5dc1059ed8ULL;
|
||||
ctx512->state[1] = 0x629a292a367cd507ULL;
|
||||
ctx512->state[2] = 0x9159015a3070dd17ULL;
|
||||
ctx512->state[3] = 0x152fecd8f70e5939ULL;
|
||||
ctx512->state[4] = 0x67332667ffc00b31ULL;
|
||||
ctx512->state[5] = 0x8eb44a8768581511ULL;
|
||||
ctx512->state[6] = 0xdb0c2e0d64f98fa7ULL;
|
||||
ctx512->state[7] = 0x47b5481dbefa4fa4ULL;
|
||||
ctx512->count[0] = 0;
|
||||
ctx512->count[1] = 0;
|
||||
ctx512->ops = sha512_get_ops();
|
||||
break;
|
||||
case SHA512_MECH_INFO_TYPE:
|
||||
case SHA512:
|
||||
case SHA512_HMAC_MECH_INFO_TYPE:
|
||||
case SHA512_HMAC_GEN_MECH_INFO_TYPE:
|
||||
ctx512->state[0] = 0x6a09e667f3bcc908ULL;
|
||||
ctx512->state[1] = 0xbb67ae8584caa73bULL;
|
||||
ctx512->state[2] = 0x3c6ef372fe94f82bULL;
|
||||
|
@ -450,20 +432,7 @@ SHA2Init(int algotype, SHA2_CTX *ctx)
|
|||
ctx512->count[1] = 0;
|
||||
ctx512->ops = sha512_get_ops();
|
||||
break;
|
||||
case SHA512_224_MECH_INFO_TYPE:
|
||||
ctx512->state[0] = 0x8c3d37c819544da2ULL;
|
||||
ctx512->state[1] = 0x73e1996689dcd4d6ULL;
|
||||
ctx512->state[2] = 0x1dfab7ae32ff9c82ULL;
|
||||
ctx512->state[3] = 0x679dd514582f9fcfULL;
|
||||
ctx512->state[4] = 0x0f6d2b697bd44da8ULL;
|
||||
ctx512->state[5] = 0x77e36f7304c48942ULL;
|
||||
ctx512->state[6] = 0x3f9d85a86a1d36c8ULL;
|
||||
ctx512->state[7] = 0x1112e6ad91d692a1ULL;
|
||||
ctx512->count[0] = 0;
|
||||
ctx512->count[1] = 0;
|
||||
ctx512->ops = sha512_get_ops();
|
||||
break;
|
||||
case SHA512_256_MECH_INFO_TYPE:
|
||||
case SHA512_256:
|
||||
ctx512->state[0] = 0x22312194fc2bf72cULL;
|
||||
ctx512->state[1] = 0x9f555fa3c84c64c2ULL;
|
||||
ctx512->state[2] = 0x2393b86b6f53b151ULL;
|
||||
|
@ -490,25 +459,14 @@ SHA2Update(SHA2_CTX *ctx, const void *data, size_t len)
|
|||
ASSERT3P(data, !=, NULL);
|
||||
|
||||
switch (ctx->algotype) {
|
||||
case SHA256_MECH_INFO_TYPE:
|
||||
case SHA256_HMAC_MECH_INFO_TYPE:
|
||||
case SHA256_HMAC_GEN_MECH_INFO_TYPE:
|
||||
case SHA256:
|
||||
sha256_update(&ctx->sha256, data, len);
|
||||
break;
|
||||
case SHA384_MECH_INFO_TYPE:
|
||||
case SHA384_HMAC_MECH_INFO_TYPE:
|
||||
case SHA384_HMAC_GEN_MECH_INFO_TYPE:
|
||||
sha512_update(&ctx->sha512, data, len);
|
||||
break;
|
||||
case SHA512_MECH_INFO_TYPE:
|
||||
case SHA512:
|
||||
case SHA512_HMAC_MECH_INFO_TYPE:
|
||||
case SHA512_HMAC_GEN_MECH_INFO_TYPE:
|
||||
sha512_update(&ctx->sha512, data, len);
|
||||
break;
|
||||
case SHA512_224_MECH_INFO_TYPE:
|
||||
sha512_update(&ctx->sha512, data, len);
|
||||
break;
|
||||
case SHA512_256_MECH_INFO_TYPE:
|
||||
case SHA512_256:
|
||||
sha512_update(&ctx->sha512, data, len);
|
||||
break;
|
||||
}
|
||||
|
@ -519,25 +477,14 @@ void
|
|||
SHA2Final(void *digest, SHA2_CTX *ctx)
|
||||
{
|
||||
switch (ctx->algotype) {
|
||||
case SHA256_MECH_INFO_TYPE:
|
||||
case SHA256_HMAC_MECH_INFO_TYPE:
|
||||
case SHA256_HMAC_GEN_MECH_INFO_TYPE:
|
||||
case SHA256:
|
||||
sha256_final(&ctx->sha256, digest, 256);
|
||||
break;
|
||||
case SHA384_MECH_INFO_TYPE:
|
||||
case SHA384_HMAC_MECH_INFO_TYPE:
|
||||
case SHA384_HMAC_GEN_MECH_INFO_TYPE:
|
||||
sha512_final(&ctx->sha512, digest, 384);
|
||||
break;
|
||||
case SHA512_MECH_INFO_TYPE:
|
||||
case SHA512:
|
||||
case SHA512_HMAC_MECH_INFO_TYPE:
|
||||
case SHA512_HMAC_GEN_MECH_INFO_TYPE:
|
||||
sha512_final(&ctx->sha512, digest, 512);
|
||||
break;
|
||||
case SHA512_224_MECH_INFO_TYPE:
|
||||
sha512_final(&ctx->sha512, digest, 224);
|
||||
break;
|
||||
case SHA512_256_MECH_INFO_TYPE:
|
||||
case SHA512_256:
|
||||
sha512_final(&ctx->sha512, digest, 256);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,14 @@
|
|||
*/
|
||||
|
||||
#if defined(__aarch64__)
|
||||
|
||||
/* make gcc <= 9 happy */
|
||||
#if !defined(LD_VERSION) || LD_VERSION >= 233010000
|
||||
#define CFI_NEGATE_RA_STATE .cfi_negate_ra_state
|
||||
#else
|
||||
#define CFI_NEGATE_RA_STATE
|
||||
#endif
|
||||
|
||||
.text
|
||||
.section .note.gnu.property,"a",@note
|
||||
.p2align 3
|
||||
|
@ -51,7 +59,7 @@
|
|||
zfs_blake3_compress_in_place_sse2:
|
||||
.cfi_startproc
|
||||
hint #25
|
||||
.cfi_negate_ra_state
|
||||
CFI_NEGATE_RA_STATE
|
||||
sub sp, sp, #96
|
||||
stp x29, x30, [sp, #64]
|
||||
add x29, sp, #64
|
||||
|
@ -555,7 +563,7 @@ compress_pre:
|
|||
zfs_blake3_compress_xof_sse2:
|
||||
.cfi_startproc
|
||||
hint #25
|
||||
.cfi_negate_ra_state
|
||||
CFI_NEGATE_RA_STATE
|
||||
sub sp, sp, #96
|
||||
stp x29, x30, [sp, #64]
|
||||
add x29, sp, #64
|
||||
|
@ -608,7 +616,7 @@ zfs_blake3_compress_xof_sse2:
|
|||
zfs_blake3_hash_many_sse2:
|
||||
.cfi_startproc
|
||||
hint #25
|
||||
.cfi_negate_ra_state
|
||||
CFI_NEGATE_RA_STATE
|
||||
stp d15, d14, [sp, #-160]!
|
||||
stp d13, d12, [sp, #16]
|
||||
stp d11, d10, [sp, #32]
|
||||
|
|
|
@ -32,6 +32,14 @@
|
|||
*/
|
||||
|
||||
#if defined(__aarch64__)
|
||||
|
||||
/* make gcc <= 9 happy */
|
||||
#if !defined(LD_VERSION) || LD_VERSION >= 233010000
|
||||
#define CFI_NEGATE_RA_STATE .cfi_negate_ra_state
|
||||
#else
|
||||
#define CFI_NEGATE_RA_STATE
|
||||
#endif
|
||||
|
||||
.text
|
||||
.section .note.gnu.property,"a",@note
|
||||
.p2align 3
|
||||
|
@ -51,7 +59,7 @@
|
|||
zfs_blake3_compress_in_place_sse41:
|
||||
.cfi_startproc
|
||||
hint #25
|
||||
.cfi_negate_ra_state
|
||||
CFI_NEGATE_RA_STATE
|
||||
sub sp, sp, #96
|
||||
stp x29, x30, [sp, #64]
|
||||
add x29, sp, #64
|
||||
|
@ -565,7 +573,7 @@ compress_pre:
|
|||
zfs_blake3_compress_xof_sse41:
|
||||
.cfi_startproc
|
||||
hint #25
|
||||
.cfi_negate_ra_state
|
||||
CFI_NEGATE_RA_STATE
|
||||
sub sp, sp, #96
|
||||
stp x29, x30, [sp, #64]
|
||||
add x29, sp, #64
|
||||
|
|
|
@ -21,6 +21,16 @@
|
|||
|
||||
#if defined(__aarch64__)
|
||||
|
||||
.section .note.gnu.property,"a",@note
|
||||
.p2align 3
|
||||
.word 4
|
||||
.word 16
|
||||
.word 5
|
||||
.asciz "GNU"
|
||||
.word 3221225472
|
||||
.word 4
|
||||
.word 3
|
||||
.word 0
|
||||
.text
|
||||
|
||||
.align 6
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue