Compare commits

..
Author SHA1 Message Date
Ken Smith 54055718ff Get ready for 7.2-RELEASE builds.
Approved by:	re (implicit)
2009-05-01 02:18:54 +00:00
Ken Smith 1f61e76b51 Predict announcement day for 7.2-RELEASE.
Approved by:	re (implicit)
2009-05-01 02:17:08 +00:00
Hiroki Sato 69a8884af1 Merge r191705 change in the English version.
Submitted by:	delphij
Approved by:	re (implicit)
2009-04-30 21:39:56 +00:00
Hiroki Sato 510c6cf29a Revise entry for superpages.
Suggested by:	rwatson
Approved by:	re (implicit)
2009-04-30 21:20:09 +00:00
Xin LI c998438538 Sync with English revisions.
Approved by:	re (hrs)
2009-04-30 06:17:56 +00:00
Hiroki Sato 3649c5caff Various wording/grammar fixes.
Suggested by:	keramida
Approved by:	re (implicit)
2009-04-29 17:50:48 +00:00
Hiroki Sato 76322dbacd - Update entries for increased KVA on amd64 and superpages on
amd64/i386[1]
- BTX loader improved[2]
- Move sysctl node MPSAFE flag to the kernel section[3]
- u3g(4) added[4]
- Various grammer fixes[5]
- MAKE_JOBS_SAFE added in bsd.port.mk.

Suggested by:	ivoras[1], gavin[2], kib[3], edwin[4], and schweikh[5].
Approved by:	re (implicit)
2009-04-29 15:22:58 +00:00
Hiroki Sato f9a559a82d Fix a typo.
Spotted by:	pluknet at gmail.com
Approved by:	re (implicit)
2009-04-29 08:46:50 +00:00
Hiroki Sato 9070dd1518 Fix a typo.
Approved by:	re (implicit)
2009-04-29 07:37:07 +00:00
Hiroki Sato a54b5e9264 - Updare release notes:
currently jail+cpuset allows superuser inside the jail to
	change the CPU bindings,
	atkbd(4) + kbdmux(4) duplicated/missing chars issue on MP systems fixed,
	ULE machdep.hyperthreading_enabled support,
	bce(4) update,
	cxgb(4) update,
	ixgbe(4) update,
	a typo fix: s/<varname>/<replaceable>/,
	ata(4) nForce MCP67/MCP73 support improved,
	GEOM label UFS ID support,
	GEOM journal rootfs support,
	hptmv(4) updated,
	twa(4) 64-bit DMA support,
	fsck -C (check clean mode) support,
	getaddrinfo(3) SCTP support,
	make(1) -p, -Q, ${.MAKE.JOB.PREFIX}, ${.MAKE.PID} added, and
	mount(8) -o mountprog=/foo added.

- Various grammer and order fixes.

Approved by:	re (implicit)
2009-04-29 06:52:04 +00:00
Hiroki Sato 38f33e47a0 Updare release notes:
currently jail+cpuset allows superuser inside the jail to
	change the CPU bindings,
	atkbd(4) + kbdmux(4) duplicated/missing chars issue on MP systems fixed,
	ULE machdep.hyperthreading_enabled support,
	bce(4) update,
	cxgb(4) update,
	ixgbe(4) update,
	a typo fix: s/<varname>/<replaceable>/,
	ata(4) nForce MCP67/MCP73 support improved,
	GEOM label UFS ID support,
	GEOM journal rootfs support,
	hptmv(4) updated,
	twa(4) 64-bit DMA support,
	fsck -C (check clean mode) support,
	getaddrinfo(3) SCTP support,
	make(1) -p, -Q, ${.MAKE.JOB.PREFIX}, ${.MAKE.PID} added, and
	mount(8) -o mountprog=/foo added.

Approved by:	re (implicit)
2009-04-29 06:14:12 +00:00
Hiroki Sato e7b58bcd8d Update release notes:
schizo driver on sparc64,
	txp(4) various improvements,
	tap(4) SIOSIFMTU support.

Approved by:	re (implicit)
2009-04-28 04:45:06 +00:00
Hiroki Sato d35c52a536 Update release notes:
DDB show mount added,
	sparc64 US III support,
	DRM r600/r700,
	ae(4) WoL support,
	hardware MAC stats: cxgb(4), msk(4), nfe(4),
	re(4) hw.re.prefer_iomap,
	sis(4) VLAN tagging bugfix,
	txp(4) update,
	TCP MD5 signature option for IPv6,
	gpart(8) updated; APM and EBR scheme support,
	mpt(4) in GENERIC on sparc64,
	vfs.nfs.prime_access_cache for NFSv3,
	ncal(1) multibyte support,
	csup CVSMode support,
	du(1) -A and -B option added,
	makefs(8) added, and
	mergemaster(8) -F option added.

Approved by:	re (implicit)
2009-04-27 21:53:44 +00:00
Christian Brueffer bbee93cbf5 Document an issue of jail(8) in conjunction with cpuset(1).
Problem reported by:	Miroslav Lachman <[email protected]>
Reviewed by:	bz
Approved by:	re (kib)
2009-04-27 20:38:27 +00:00
Xin LI 4679e4f9c4 Add -C back.
Approved by:	re (kensmith)
2009-04-27 19:15:33 +00:00
Marc Fonvieille 5d7d08d44a Add a missing space and remove a superfluous char.
Approved by:	re (implicit)
2009-04-26 19:16:32 +00:00
Hiroki Sato 2b6caead9d Update release note:
type of shm_segsz in struct shmid_ds to size_t from int,
	AltiVec support on powerpc,
	INTx disabled when MSI/MSIX enabled,
	sysctl leaf node now has an MPSAFE flag,
	hw.drm.msi tunable added,
	ale(4) in GENERIC on amd64 and i386,
	ata-raid(4) initial support for DDF metadata,
	cam(4) kern.cam.cd.retry_count sysctl,
	ciss(4) max device openings count fix,
	btpand(8) for NAP, GN, PANU profiles of bluetooth added, and
	improve description of the fetch(1) If-Modified-Since support.

Approved by:	re (implicit)
2009-04-26 18:10:07 +00:00
Hiroki Sato e8fb91fe8b Update release note:
jail improvements: IPv4, IPv6, no address support, SCTP fix,
	cpuset(1) support, ddb show jails, version number bump,
	KTR_CALLOUT new tracepoint added,
	Superpages on amd64 and i386,
	acpu_asus(4) Asus A8Sr support added,
	axe(4) reduced csw for better performance,
	fxp(4) improvements including checksum offload, TSO, WoL, and VLAN,
	msk(4) hang up issue due to misalignment workaround,
	mxge(4) newer hardware support and media types,
	re(4) better miibus interaction support,
	rl(4) better miibus interaction support and fixes for >4GB system,
	IPv4 source address selection,
	tap(4) TAPGIFNAME ioctl added,
	unix(4) MPSAFE,
	sdhci(4) kernel dump support,
	EA semantics of [am]time update changed,
	atacontrol(8) minor nits fixed,
	dirname(1) multiple arguments support,
	dumpfs(8) -f flag added,
	fsck(8) s/-C/-D/,
	ln(1) -w flag added,
	netstat(1) unix sockets stats in -L flag,
	pciconf(8) -b flag added, and
	stat(1) octal s[gu]id in -x flag.

Approved by:	re (implicit)
2009-04-26 16:56:03 +00:00
Hiroki Sato 03a76b348d Update release notes:
FREEBSD32 syscall translation layer now supports
	addition/removal of syscall from kernel module,
	VFS_AIO syscalls added to FREEBSD32,
	ktr(4) new tracepoint for callout added,
	cpufreq(4) hw.est.msr_info added,
	kern.timecounter.invariant_tsc for i386 and amd64 added,
	vfs.lookup_shared improvement and removal of LOOKUP_SHARED option, and
	netstat(1) -ss for icmp6 section fixed.

Approved by:	re (implicit)
2009-04-26 14:03:52 +00:00
Marc Fonvieille 575826f183 s/&os:/&os;/ wrongly added by myself (damn it builded fine even with the
wrong version:( )

Submitted by:	marius
Approved by:	re (implicit)
2009-04-26 09:54:03 +00:00
Hiroki Sato 5b37f4de45 Update release notes:
amd64 KVA space to 6GB,
	variable reference in loader(8) script fixed,
	debug.batt.batt_sleep_ms added,
	snd_au88x0(4) removed,
	typo in igb(4) hw.igb.ave_latency fixed,
	gvinum plex access permission issue fixed,
	du(1) -l flag added,
	"netstat -m -N foo" issue fixed, and
	wc(1) -L flag added.

Approved by:	re (implicit)
2009-04-26 08:29:35 +00:00
Marc Fonvieille 45e294f985 - Add/usr trademarks for Windows;
- Various typo fixes.

Approved by:	re (implicit)
2009-04-26 08:17:14 +00:00
Marc Fonvieille af51f9df3c MFC:
r191509:
Unbreak the build of relnotes.

r191511:
Bump copyright year;
Add missing colon and fix broken entity.

Approved by:	re (implicit)
2009-04-26 08:00:41 +00:00
Hiroki Sato daf0e2ac5e Update release note:
boot0 volume ID and F6 PXE invoke support,
	DHCP options via kenv,
	cpuctl(4) added,
	ciphy(4) VSC8211 support,
	jme(4) newer JMC250/260 support,
	rl(4) improved,
	ata(4) Marvell PATA M88SX6121 support, and
	config(8) multiple makeoption support.

Approved by:	re (implicit)
2009-04-26 00:29:49 +00:00
Hiroki Sato 4304e5eb17 Update release note:
agp(4) Intel G4X support,
	DRM update,
	snd_hda(4) update,
	jail(8) FIB support,
	ng_netflow(4) egress netflow support,
	mmc(4) and mmcsd(4) improved,
	sdhci(4) added,
	mmc(4), mmcsd(4), and sdhci(4) as kernel module,
	fetch(1) -i flag,
	fsck(8) -C flag,
	ipfw(8) -q flag fixed,
	powerd(8) improved,
	rpc.yppasswdd(8) zombie process issue fixed, and
	pkg_create(1) -n fixed.

Approved by:	re (implicit)
2009-04-25 23:09:39 +00:00
Marius Strobl 421bcceeb8 MFC: r191491, r191492
Sync the sparc64 hardware notes with reality, mainly regarding support
of sun4u-machines based on USIII and beyond in 7.2-RELEASE.

Approved by:	re (blackend)
2009-04-25 23:08:59 +00:00
Hiroki Sato c1ff6d05f5 - Use arch="" attr instead of literal [&arch.xxx;].
- Bump copyright year.
- Delete trailing whitespaces.

Approved by:	re (implicit)
2009-04-25 21:32:48 +00:00
Hiroki Sato d550f5d3db Add &release.next;.
Approved by:	re (implicit)
2009-04-25 21:16:06 +00:00
Hiroki Sato 52ab77523b Bump version number for 7.2.
Approved by:	re (implicit)
2009-04-25 21:11:17 +00:00
Hiroki Sato 59fbe89293 Trim errata document for 7.2.
Approved by:	re (implicit)
2009-04-25 21:10:38 +00:00
Marc Fonvieille 2cfb122f55 Small attempt to update a bit relnotes:
ISC BIND 9.4.3-P2
timezone database tzdata2009f
GNOME 2.26
KDE 4.2.2

Approved by:	re (implicit)
2009-04-25 20:42:21 +00:00
Marc Fonvieille c4f7dce098 Add following Security Advisories:
SA-09:01.lukemftpd
SA-09:02.openssl
SA-09:03.ntpd
SA-09:04.bind
SA-09:05.telnetd
SA-09:06.ktimer
SA-09:07.libc
SA-09:08.openssl

Approved by:	re (implicit)
2009-04-25 13:52:47 +00:00
Marc Fonvieille 6df7da0052 Remove footer belonging to -STABLE version
Approved by:	re (implicit)
2009-04-25 12:58:01 +00:00
Marc Fonvieille b329f45a9a Update various entities required by release notes.
Approved by:	re (implicit)
2009-04-25 12:53:52 +00:00
Marc Fonvieille 04260ee25f Remove old (unmaintained) translations.
Approved by:	re (implicit)
2009-04-25 12:32:12 +00:00
Robert Watson 72f50b48c4 Merge r191434 from stable/7 to releng/7.2:
In sysctl_ifdata(), query the ifnet pointer using the index only
  once, rather than querying it, validating it, and then re-querying
  it without validating it.  This may avoid a NULL pointer
  dereference and resulting kernel page fault if an interface is
  being deleted while bsnmp or other tools are querying data on the
  interface.

  The full fix, to properly refcount the interface for the duration
  of the sysctl, is in 8.x, but is considered too high-risk for
  7.2, so instead will appear in 7.3 (if all goes well).

  Reported by:  mdtancsa

Approved by:	re (kensmith)
2009-04-23 18:23:08 +00:00
Christian Brueffer 563a73f034 MFC r191414
Correct the information about when the respective functionality first
appeared in FreeBSD.

Approved by:  re (kensmith)
2009-04-23 17:19:25 +00:00
Ken Smith 79c1c663cb Adjust for the 7.2-RELEASE package set.
Approved by:	re (kib)
2009-04-23 12:05:55 +00:00
Christian Brueffer 8fcffe2145 MFC r190822
Move an "end list" macro to the right place.

Approved by:	re (kensmith)
2009-04-23 08:11:48 +00:00
Ken Smith 6e5c517269 Get ready for 7.2-RC2 builds.
Approved by:	re (implicit)
2009-04-23 02:30:44 +00:00
Robert Noland 34e6868261 Merge 191274.
Don't try to setup interrupts for drivers that don't support them.

This causes sis and probably a couple of other driver to panic and fail.

Tested by:    cpghost <[email protected]>
Approved by:	re (kib)
2009-04-22 21:50:32 +00:00
Colin Percival 62309d46fc Don't leak information via uninitialized space in db(3) records. [09:07]
Sanity-check string lengths in order to stop OpenSSL crashing
when printing corrupt BMPString or UniversalString objects. [09:08]

Security:	FreeBSD-SA-09:07.libc
Security:	FreeBSD-SA-09:08.openssl
Security:	CVE-2009-0590
Approved by:	re (kensmith)
Approved by:	so (cperciva)
2009-04-22 14:07:14 +00:00
Ollivier Robert 9f5a40581d MFH of changeset r191200:
Add an entry for the French macbook keyboard layout.

Approved by:    re (kensmith)
2009-04-22 13:18:13 +00:00
Bjoern A. Zeeb f8cb494d51 MFC r191305:
Back out r186308 (r191014 in stable/7):

 In case of AF_LINK, which the kernel still returns for an RTAX_GATEWAY
 as an empty sockaddr_dl in the classic tun<n> case:
 copying the address into the message payload, but not the RTA_GATEWAY
 flag results in rt_xaddrs() in the kernel tripping over that and parsing
 the next attribute set with a flag, i.e. RTA_NETMASK, with the gateway
 address, resulting in bogus route entry.

Approved by:  re (kensmith)
2009-04-22 08:37:02 +00:00
Colin Percival 4e7ac0d6fc MFH r191302: Fix a buffer overflow.
For reasons of stack alignment, it does not appear that this is exploitable
on any systems FreeBSD runs on, so this will not be getting a security
advisory.

Approved by:	re (kib)
2009-04-21 10:54:47 +00:00
Marc Fonvieille 6e043e1a60 MFC: r191265
Add docs category.

Approved by:  re (kensmith)
2009-04-21 09:55:17 +00:00
Maksim Yevmenkin 23b937f516 MFC r191232
Fix bug in event timeout handling

Submitted by:	mav
Approved by:	re (kib)
2009-04-20 17:11:21 +00:00
Maksim Yevmenkin da2a3ace37 MFC r191164
Prevent atkbd(4) interrupt handler from calling keyboard callback function
when polled mode is enabled. This should help with duplicated/missing
characters problem at mountroot, geli, etc. prompts on multi CPU systems
while kbdmux(4) is enabled.

Tested by:	Tobias Grosser <grosser -at- fim -dot- uni-passau -dot- de>
Tested by:	Fabian Keil <freebsd-listen -at- fabiankeil -dot- de>
Approved by:	re (kib)
2009-04-20 17:09:53 +00:00
Edwin Groothuis 1b5ec3f62e MFC of tzdata2009f
Correct DST information for Pakistan for 2009.

Approved by:	re (kip)
2009-04-18 12:16:33 +00:00
Marius Strobl 516148ef3e MFC: r191076
- Remove the second license as I'm also fine with the first one.
- Remove redundant softc members for RIDs.
- Change some softc members to be unsigned where more appropriate.
- Add some missing const.
- Remove support for mmap(2)'ing VGA I/O as it was broken [1] and
  not required by X.Org anyway.
- Fix some confusion between bus, physical and virtual addresses
  which mostly consisted in using members of struct video_adapter
  inappropriately but wasn't fatal except for the regular framebuffer
  mmap(2)'ing.
- Remove redundant bzero(9)'ing of the softc.
- Don't map the framebuffer twice in case the firmware has already
  mapped it as besides wasting resources this isn't possible with
  all MMUs. This is a bit tricky as a) just because the firmware
  provides a property with a virtual address doesn't mean it's
  actually mapped (but typically is when the framebuffer is the
  console) and b) the firmware doesn't necessarily map it with
  the same byteorder as we do. This makes machfb(4) work on machines
  with cheetah-class MMUs (including X.Org).

Reported by:	Michael Plass [1]
Approved by:	re (kib)
2009-04-17 23:22:06 +00:00
Marius Strobl 6759c92a8d MFC: r191072
Fix whitespace.

Approved by:	re (kib)
2009-04-17 23:11:18 +00:00
Alexander Kabaev 9929416e83 MFC r191218 and related backout r191220.
More fallout from negative dotdot caching. Negative entries should
be removed from and reinserted to proper ncneg list.

Reported by:	pho
Submitted by:	kib
Approved by:	re (kib)
2009-04-17 21:18:17 +00:00
John Baldwin 7ff6b770c6 MFC: Use a disk address instead of an int to hold the starting offset of an
open partition.

Approved by:	re (kib)
2009-04-17 17:13:41 +00:00
Dmitry Chagin fec900bd04 Merge r190708 from HEAD to releng/7.2:
Fix KBI breakage by r190520 which affects older linux.ko binaries:

1) Move the new field (brand_note) to the end of the Brandinfo structure.
2) Add a new flag BI_BRAND_NOTE that indicates that the brand_note pointer
   is valid.
3) Use the brand_note field if the flag BI_BRAND_NOTE is set and as old
   modules won't have the flag set, so the new field brand_note would be
   ignored.

Suggested by:   jhb
Reviewed by:    jhb

Approved by:	re (Ken Smith), kib (mentor)
2009-04-17 17:05:31 +00:00
Alan Cox 1b65664c28 MFC r175055
Defer setting either PG_CACHED or PG_FREE until after the free page
  queues lock is acquired.  Otherwise, the state of a reservation's
  pages' flags and its population count can be inconsistent.  That could
  result in a page being freed twice.

(This change should have been included in the MFC of the superpages
support.)

Thanks to:	pho for an illuminating crash

Approved by:	re (kib)
2009-04-17 16:42:03 +00:00
Alexander Kabaev 6794374441 MFC r191081-191082:
Properly handle negative cache enries found through dotdot lookups.

Submitted by:	tegge
Approved by:	re(kib)
2009-04-15 16:36:13 +00:00
Ken Smith 2487bb6cb1 Add package directory for 7.2-REL. While here add the one for 6.4-REL.
Approved by:	re (implicit)
2009-04-15 04:28:22 +00:00
Ken Smith e175267715 Bump __FreeBSD_version for 7.2-REL plus the shift to show this is a
release branch.

Approved by:	re (implicit)
2009-04-15 04:27:04 +00:00
Ken Smith 98e57db40f Almost ready for 7.2-RC1 builds.
Approved by:	re (implicit)
2009-04-15 04:25:31 +00:00
Ken Smith 2a72044563 Update CVS tag to RELENG_7_2.
Approved by:	re (implicit)
2009-04-15 04:24:24 +00:00
Ken Smith 77bbc16437 Bump version from 7.1 to 7.2.
Approved by:	re (implicit)
2009-04-15 04:23:17 +00:00
Ken Smith 4c1e483f92 Change default version for manual pages to 7.2.
Approved by:	re (implicit)
2009-04-15 04:22:27 +00:00
Ken Smith af333ae2db Update branch to use.
Approved by:	re (implicit)
2009-04-15 04:21:21 +00:00
2443 changed files with 145170 additions and 286987 deletions

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@
The compilation of software known as FreeBSD is distributed under the
following terms:
Copyright (c) 1992-2010 The FreeBSD Project. All rights reserved.
Copyright (c) 1992-2009 The FreeBSD Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
+2 -2
View File
@@ -88,7 +88,7 @@ CLEANDIR= cleandir
.endif
CVS?= cvs
CVSFLAGS?= -r RELENG_7_3 -P -d -I!
CVSFLAGS?= -r RELENG_7_2 -P -d -I!
SUP?= /usr/bin/csup
SUPFLAGS?= -g -L 2
.if defined(SUPHOST)
@@ -985,7 +985,7 @@ build-tools:
#
# cross-tools: Build cross-building tools
#
.if ${TARGET_ARCH} != ${MACHINE_ARCH} || ${BOOTSTRAPPING} < 702102
.if ${TARGET_ARCH} != ${MACHINE_ARCH}
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386"
_btxld= usr.sbin/btxld
.endif
-4
View File
@@ -14,10 +14,6 @@
# The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last.
#
# 20091129: pecoff image activator removed
.if ${TARGET_ARCH} == "i386"
OLD_FILES+=usr/include/machine/pecoff_machdep.h
.endif
# 20090203: adding_user.8 moved to adding_user.7
OLD_FILES+=usr/share/man/man8/adding_user.8.gz
# 20080407: pkg_sign has been removed
+11 -35
View File
@@ -8,40 +8,16 @@ Items affecting the ports and packages system can be found in
/usr/ports/UPDATING. Please read that file before running
portupgrade.
20100323:
FreeBSD 7.3-RELEASE
20091129:
PECOFF image activator support removed.
20090831:
The newly imported zic(8) produces a new format in the
output. Please run tzsetup(8) to install the newly created
data to /etc/localtime.
20090731:
The ABI of various structures related to the SYSV IPC API have
been changed. Bump __FreeBSD_version to 702105.
20090606:
The components of PmcTools have been upgraded. Please
update world and the kernel.
20090521:
The k8temp(4) driver has been renamed to amdtemp(4) since
support for K10 and K11 CPU families was added.
20090520:
Update ZFS to version 13. ZFS users will need to re-build
and install both kernel and world simultaneously in order
for the ZFS tools to work. Existing pools will continue to work
without upgrade. If a pool is upgraded it will no longer be
usable by older kernel revs. ZFS send / recv between
pool version 6 and pool version 13 is not supported.
20090504:
FreeBSD 7.2-RELEASE
20090422: FreeBSD-SA-09:07.libc, FreeBSD-SA-09:08.openssl
Don't leak information via uninitialized space in db(3) records.
[09:07]
Sanity-check string lengths in order to stop OpenSSL crashing
when printing corrupt BMPString or UniversalString objects. [09:08]
20090326:
Following bug-fixes to TCP connection state flags, netstat, systat,
and sockstat will need to be rebuilt in order to properly print
@@ -158,13 +134,13 @@ portupgrade.
The important thing to note is that the 82575 adapters
were supported in the em driver in 7.0, but now needed
to be moved into igb, so if you have the affected cards
to be moved into igb, so if you have the effected cards
be sure and make any script changes to follow the name
change.
There are only 3 PCI ID's affected in this change:
There are only 3 PCI ID's effected in this change:
0x10A7, 0x10A9, and 0x10D6
So you can know ahead of time if they will be affected,
So you can know ahead of time if they will be effected,
these will now be supported in the igb driver. That
driver will also support the new 82576 followon.
@@ -176,7 +152,7 @@ portupgrade.
20080724:
I have MFC'd in code to support multiple routing tables.
See the man pages setfib(1) and setfib(2).
see the man pages setfib(1) and setfib(2).
This is a backwards compatible version,
but to make use of it you need to compile your kernel
with options ROUTETABLES=2 (or more up to 16).
-1
View File
@@ -26,7 +26,6 @@ SUBDIR= cat \
mv \
pax \
ps \
pwait \
pwd \
${_rcp} \
realpath \
+1 -1
View File
@@ -115,7 +115,7 @@ main(int argc, char *argv[])
fts_options |= FTS_LOGICAL;
}
} else
fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL;
fts_options = FTS_LOGICAL;
/* XXX: Why don't chflags and lchflags have compatible prototypes? */
if (hflag)
+1 -1
View File
@@ -339,7 +339,7 @@ setfile(struct stat *fs, int fd)
if (!gotstat || fs->st_flags != ts.st_flags)
if (fdval ?
fchflags(fd, fs->st_flags) :
(islink ? lchflags(to.p_path, fs->st_flags) :
(islink ? (errno = ENOSYS) :
chflags(to.p_path, fs->st_flags))) {
warn("chflags: %s", to.p_path);
rval = 1;
-11
View File
@@ -61,20 +61,9 @@ dl_iconv_open(const char *tocode, const char *fromcode)
if (iconvlib == NULL)
return (iconv_t)-1;
iconv_open = (iconv_open_t *)dlfunc(iconvlib, ICONV_OPEN);
if (iconv_open == NULL)
goto dlfunc_err;
dl_iconv = (dl_iconv_t *)dlfunc(iconvlib, ICONV_ENGINE);
if (dl_iconv == NULL)
goto dlfunc_err;
dl_iconv_close = (dl_iconv_close_t *)dlfunc(iconvlib,
ICONV_CLOSE);
if (dl_iconv_close == NULL)
goto dlfunc_err;
}
return iconv_open(tocode, fromcode);
dlfunc_err:
dlclose(iconvlib);
iconvlib = NULL;
return (iconv_t)-1;
}
+2 -7
View File
@@ -78,20 +78,15 @@ this overrides the
.Ev BLOCKSIZE
specification from the environment.
.It Fl H
.Dq Human-readable
output.
"Human-readable" output.
Use unit suffixes: Byte, Kilobyte, Megabyte,
Gigabyte, Terabyte and Petabyte in order to reduce the number of
digits to four or fewer using base 10 for sizes.
.It Fl h
.Dq Human-readable
output.
"Human-readable" output.
Use unit suffixes: Byte, Kilobyte, Megabyte,
Gigabyte, Terabyte and Petabyte in order to reduce the number of
digits to four or fewer using base 2 for sizes.
Inodes statistics, if enabled with
.Fl i ,
are always printed in base 10.
.It Fl i
Include statistics on the number of free inodes.
.It Fl k
+4 -30
View File
@@ -364,23 +364,6 @@ prthumanval(int64_t bytes)
(void)printf(" %6s", buf);
}
/*
* Print an inode count in "human-readable" format.
*/
static void
prthumanvalinode(int64_t bytes)
{
char buf[6];
int flags;
flags = HN_NOSPACE | HN_DECIMAL | HN_DIVISOR_1000;
humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1),
bytes, "", HN_AUTOSCALE, flags);
(void)printf(" %5s", buf);
}
/*
* Convert statfs returned file system size into BLOCKSIZE units.
* Attempts to avoid overflow for large file systems.
@@ -423,10 +406,8 @@ prtstat(struct statfs *sfsp, struct maxwidths *mwp)
mwp->mntfrom, "Filesystem", mwp->total, header,
mwp->used, "Used", mwp->avail, "Avail");
if (iflag) {
mwp->iused = imax(hflag ? 0 : mwp->iused,
(int)strlen(" iused"));
mwp->ifree = imax(hflag ? 0 : mwp->ifree,
(int)strlen("ifree"));
mwp->iused = imax(mwp->iused, (int)strlen(" iused"));
mwp->ifree = imax(mwp->ifree, (int)strlen("ifree"));
(void)printf(" %*s %*s %%iused",
mwp->iused - 2, "iused", mwp->ifree, "ifree");
}
@@ -450,15 +431,8 @@ prtstat(struct statfs *sfsp, struct maxwidths *mwp)
if (iflag) {
inodes = sfsp->f_files;
used = inodes - sfsp->f_ffree;
if (hflag) {
(void)printf(" ");
prthumanvalinode(used);
prthumanvalinode(sfsp->f_ffree);
} else {
(void)printf(" %*jd %*jd", mwp->iused, (intmax_t)used,
mwp->ifree, (intmax_t)sfsp->f_ffree);
}
(void)printf(" %4.0f%% ", inodes == 0 ? 100.0 :
(void)printf(" %*jd %*jd %4.0f%% ", mwp->iused, (intmax_t)used,
mwp->ifree, (intmax_t)sfsp->f_ffree, inodes == 0 ? 100.0 :
(double)used / (double)inodes * 100.0);
} else
(void)printf(" ");
-1
View File
@@ -396,7 +396,6 @@ trng_add(char *str)
default:
paxwarn(1, "Bad option %c with time range %s",
*flgpt, str);
free(pt);
goto out;
}
++flgpt;
+1 -2
View File
@@ -39,7 +39,7 @@ extern fixpt_t ccpu;
extern int cflag, eval, fscale, nlistread, rawcpu;
extern unsigned long mempages;
extern time_t now;
extern int showthreads, sumrusage, termwidth, totwidth;
extern int sumrusage, termwidth, totwidth;
extern STAILQ_HEAD(velisthead, varent) varlist;
__BEGIN_DECLS
@@ -71,7 +71,6 @@ void priorityr(KINFO *, VARENT *);
void rgroupname(KINFO *, VARENT *);
void runame(KINFO *, VARENT *);
void rvar(KINFO *, VARENT *);
int s_comm(KINFO *);
int s_label(KINFO *);
int s_rgroupname(KINFO *);
int s_runame(KINFO *);
+9 -12
View File
@@ -79,8 +79,8 @@ static VAR var[] = {
CHAR, NULL, 0},
{"blocked", "", "sigmask", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
{"caught", "", "sigcatch", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
{"comm", "COMMAND", NULL, LJUST|DSIZ, ucomm, s_comm,
COMMLEN + OCOMMLEN + 1, 0, CHAR, NULL, 0},
{"comm", "COMMAND", NULL, LJUST, ucomm, NULL, MAXCOMLEN, 0, CHAR,
NULL, 0},
{"command", "COMMAND", NULL, COMM|LJUST|USER, command, NULL, 16, 0,
CHAR, NULL, 0},
{"cpu", "CPU", NULL, 0, kvar, NULL, 3, KOFF(ki_estcpu), UINT, "d",
@@ -135,13 +135,12 @@ static VAR var[] = {
LONG, "ld", 0},
{"nvcsw", "NVCSW", NULL, USER, rvar, NULL, 5, ROFF(ru_nvcsw),
LONG, "ld", 0},
{"nwchan", "NWCHAN", NULL, LJUST, nwchan, NULL, sizeof(void *) * 2, 0,
CHAR, NULL, 0},
{"nwchan", "NWCHAN", NULL, LJUST, nwchan, NULL, 8, 0, CHAR, NULL, 0},
{"oublk", "OUBLK", NULL, USER, rvar, NULL, 4, ROFF(ru_oublock),
LONG, "ld", 0},
{"oublock", "", "oublk", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
{"paddr", "PADDR", NULL, 0, kvar, NULL, sizeof(void *) * 2,
KOFF(ki_paddr), KPTR, "lx", 0},
{"paddr", "PADDR", NULL, 0, kvar, NULL, 8, KOFF(ki_paddr), KPTR,
"lx", 0},
{"pagein", "PAGEIN", NULL, USER, pagein, NULL, 6, 0, CHAR, NULL, 0},
{"pcpu", "", "%cpu", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
{"pending", "", "sig", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
@@ -195,13 +194,13 @@ static VAR var[] = {
{"tsiz", "TSIZ", NULL, 0, kvar, NULL, 4, KOFF(ki_tsize), PGTOK, "ld", 0},
{"tt", "TT ", NULL, 0, tname, NULL, 4, 0, CHAR, NULL, 0},
{"tty", "TTY", NULL, LJUST, longtname, NULL, 8, 0, CHAR, NULL, 0},
{"ucomm", "UCOMM", NULL, LJUST|DSIZ, ucomm, s_comm,
COMMLEN + OCOMMLEN + 1, 0, CHAR, NULL, 0},
{"ucomm", "UCOMM", NULL, LJUST, ucomm, NULL, MAXCOMLEN, 0, CHAR, NULL,
0},
{"uid", "UID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_uid), UINT,
UIDFMT, 0},
{"upr", "UPR", NULL, 0, upr, NULL, 3, 0, CHAR, NULL, 0},
{"uprocp", "UPROCP", NULL, 0, kvar, NULL, sizeof(void *) * 2,
KOFF(ki_paddr), KPTR, "lx", 0},
{"uprocp", "UPROCP", NULL, 0, kvar, NULL, 8, KOFF(ki_paddr), KPTR,
"lx", 0},
{"user", "USER", NULL, LJUST|DSIZ, uname, s_uname, USERLEN, 0, CHAR,
NULL, 0},
{"usrpri", "", "upr", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
@@ -325,8 +324,6 @@ findvar(char *p, int user, char **header)
*/
rflen = strlen(v->alias) + strlen(hp) + 2;
realfmt = malloc(rflen);
if (realfmt == NULL)
errx(1, "malloc failed");
snprintf(realfmt, rflen, "%s=%s", v->alias, hp);
parsefmt(realfmt, user);
}
+14 -53
View File
@@ -129,33 +129,25 @@ command(KINFO *k, VARENT *ve)
v = ve->var;
if (cflag) {
/* If it is the last field, then don't pad */
if (STAILQ_NEXT(ve, next_ve) == NULL) {
if (k->ki_d.prefix)
(void)printf("%s", k->ki_d.prefix);
if (STAILQ_NEXT(ve, next_ve) == NULL)
(void)printf("%s", k->ki_p->ki_comm);
} else
else
(void)printf("%-*s", v->width, k->ki_p->ki_comm);
return;
}
if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL)
errx(1, "malloc failed");
strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH);
if (k->ki_env) {
if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) == NULL)
errx(1, "malloc failed");
strvis(vis_env, k->ki_env, VIS_TAB | VIS_NL | VIS_NOSLASH);
} else
vis_env = NULL;
if (STAILQ_NEXT(ve, next_ve) == NULL) {
/* last field */
if (k->ki_env) {
if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1))
== NULL)
errx(1, "malloc failed");
strvis(vis_env, k->ki_env,
VIS_TAB | VIS_NL | VIS_NOSLASH);
} else
vis_env = NULL;
if (termwidth == UNLIMITED) {
if (k->ki_d.prefix)
(void)printf("%s", k->ki_d.prefix);
if (vis_env)
(void)printf("%s ", vis_env);
(void)printf("%s", vis_args);
@@ -163,9 +155,6 @@ command(KINFO *k, VARENT *ve)
left = termwidth - (totwidth - v->width);
if (left < 1) /* already wrapped, just use std width */
left = v->width;
if ((cp = k->ki_d.prefix) != NULL)
while (--left >= 0 && *cp)
(void)putchar(*cp++);
if ((cp = vis_env) != NULL) {
while (--left >= 0 && *cp)
(void)putchar(*cp++);
@@ -175,34 +164,24 @@ command(KINFO *k, VARENT *ve)
for (cp = vis_args; --left >= 0 && *cp != '\0';)
(void)putchar(*cp++);
}
if (vis_env != NULL)
free(vis_env);
} else
/* ki_d.prefix & ki_env aren't shown for interim fields */
/* XXX env? */
(void)printf("%-*.*s", v->width, v->width, vis_args);
free(vis_args);
if (vis_env != NULL)
free(vis_env);
}
void
ucomm(KINFO *k, VARENT *ve)
{
char tmpbuff[COMMLEN + OCOMMLEN + 2];
VAR *v;
v = ve->var;
if (STAILQ_NEXT(ve, next_ve) == NULL) { /* last field, don't pad */
if (k->ki_d.prefix)
(void)printf("%s", k->ki_d.prefix);
if (STAILQ_NEXT(ve, next_ve) == NULL) /* last field, don't pad */
(void)printf("%s", k->ki_p->ki_comm);
} else {
bzero(tmpbuff, sizeof(tmpbuff));
if (showthreads && k->ki_p->ki_numthreads > 1)
sprintf(tmpbuff, "%s/%s", k->ki_p->ki_comm,
k->ki_p->ki_ocomm);
else
sprintf(tmpbuff, "%s", k->ki_p->ki_comm);
(void)printf("%-*s", v->width, tmpbuff);
}
else
(void)printf("%-*s", v->width, k->ki_p->ki_comm);
}
void
@@ -580,10 +559,6 @@ elapsed(KINFO *k, VARENT *ve)
char obuff[128];
v = ve->var;
if (!k->ki_valid) {
(void)printf("%-*s", v->width, "-");
return;
}
val = now - k->ki_p->ki_start.tv_sec;
days = val / (24 * 60 * 60);
val %= 24 * 60 * 60;
@@ -829,20 +804,6 @@ out:
return;
}
int
s_comm(KINFO *k)
{
char tmpbuff[COMMLEN + OCOMMLEN + 2];
bzero(tmpbuff, sizeof(tmpbuff));
if (showthreads && k->ki_p->ki_numthreads > 1)
sprintf(tmpbuff, "%s/%s", k->ki_p->ki_comm,
k->ki_p->ki_ocomm);
else
sprintf(tmpbuff, "%s", k->ki_p->ki_comm);
return (strlen(tmpbuff));
}
int
s_label(KINFO *k)
{
+2 -11
View File
@@ -29,7 +29,7 @@
.\" @(#)ps.1 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
.Dd May 16, 2009
.Dd August 21, 2006
.Dt PS 1
.Os
.Sh NAME
@@ -37,7 +37,7 @@
.Nd process status
.Sh SYNOPSIS
.Nm
.Op Fl aCcdefHhjlmrSTuvwXxZ
.Op Fl aCcefHhjlmrSTuvwXxZ
.Op Fl O Ar fmt | Fl o Ar fmt
.Op Fl G Ar gid Ns Op , Ns Ar gid Ns Ar ...
.Op Fl M Ar core
@@ -122,15 +122,6 @@ CPU calculation that ignores
.Dq resident
time (this normally has
no effect).
.It Fl d
Arrange processes into descendancy order and prefix each command with
indentation text showing sibling and parent/child relationships.
If either of the
.Fl m
and
.Fl r
options are also used, they control how sibling processes are sorted
relative to eachother.
.It Fl e
Display the environment as well.
.It Fl f
+5 -132
View File
@@ -100,7 +100,6 @@ int rawcpu; /* -C */
int sumrusage; /* -S */
int termwidth; /* Width of the screen (0 == infinity). */
int totwidth; /* Calculated-width of requested variables. */
int showthreads; /* will threads be shown? */
struct velisthead varlist = STAILQ_HEAD_INITIALIZER(varlist);
@@ -138,7 +137,6 @@ static int addelem_pid(struct listinfo *, const char *);
static int addelem_tty(struct listinfo *, const char *);
static int addelem_uid(struct listinfo *, const char *);
static void add_list(struct listinfo *, const char *);
static void descendant_sort(KINFO *, int);
static void dynsizevars(KINFO *);
static void *expand_list(struct listinfo *);
static const char *
@@ -164,7 +162,7 @@ static char vfmt[] = "pid,state,time,sl,re,pagein,vsz,rss,lim,tsiz,"
"%cpu,%mem,command";
static char Zfmt[] = "label";
#define PS_ARGS "AaCcde" OPT_LAZY_f "G:gHhjLlM:mN:O:o:p:rSTt:U:uvwXxZ"
#define PS_ARGS "AaCce" OPT_LAZY_f "G:gHhjLlM:mN:O:o:p:rSTt:U:uvwXxZ"
int
main(int argc, char *argv[])
@@ -178,8 +176,8 @@ main(int argc, char *argv[])
const char *nlistf, *memf;
char *cols;
int all, ch, elem, flag, _fmt, i, lineno;
int descendancy, nentries, nkept, nselectors;
int prtheader, wflag, what, xkeep, xkeep_implied;
int nentries, nkept, nselectors;
int prtheader, showthreads, wflag, what, xkeep, xkeep_implied;
char errbuf[_POSIX2_LINE_MAX];
(void) setlocale(LC_ALL, "");
@@ -202,7 +200,7 @@ main(int argc, char *argv[])
if (argc > 1)
argv[1] = kludge_oldps_options(PS_ARGS, argv[1], argv[2]);
all = descendancy = _fmt = nselectors = optfatal = 0;
all = _fmt = nselectors = optfatal = 0;
prtheader = showthreads = wflag = xkeep_implied = 0;
xkeep = -1; /* Neither -x nor -X. */
init_list(&gidlist, addelem_gid, sizeof(gid_t), "group");
@@ -234,9 +232,6 @@ main(int argc, char *argv[])
case 'c':
cflag = 1;
break;
case 'd':
descendancy = 1;
break;
case 'e': /* XXX set ufmt */
needenv = 1;
break;
@@ -579,8 +574,6 @@ main(int argc, char *argv[])
keepit:
next_KINFO = &kinfo[nkept];
next_KINFO->ki_p = kp;
next_KINFO->ki_d.level = 0;
next_KINFO->ki_d.prefix = NULL;
next_KINFO->ki_pcpu = getpcpu(next_KINFO);
if (sortby == SORTMEM)
next_KINFO->ki_memsize = kp->ki_tsize +
@@ -605,13 +598,6 @@ main(int argc, char *argv[])
* sort proc list
*/
qsort(kinfo, nkept, sizeof(KINFO), pscomp);
/*
* We want things in descendant order
*/
if (descendancy)
descendant_sort(kinfo, nkept);
/*
* For each process, call each variable output function.
*/
@@ -635,9 +621,6 @@ main(int argc, char *argv[])
free_list(&sesslist);
free_list(&ttylist);
free_list(&uidlist);
for (i = 0; i < nkept; i++)
free(kinfo[i].ki_d.prefix);
free(kinfo);
exit(eval);
}
@@ -906,116 +889,6 @@ add_list(struct listinfo *inf, const char *argp)
}
}
static void
descendant_sort(KINFO *ki, int items)
{
int dst, lvl, maxlvl, n, ndst, nsrc, siblings, src;
unsigned char *path;
KINFO kn;
/*
* First, sort the entries by descendancy, tracking the descendancy
* depth in the ki_d.level field.
*/
src = 0;
maxlvl = 0;
while (src < items) {
if (ki[src].ki_d.level) {
src++;
continue;
}
for (nsrc = 1; src + nsrc < items; nsrc++)
if (!ki[src + nsrc].ki_d.level)
break;
for (dst = 0; dst < items; dst++) {
if (ki[dst].ki_p->ki_pid == ki[src].ki_p->ki_pid)
continue;
if (ki[dst].ki_p->ki_pid == ki[src].ki_p->ki_ppid)
break;
}
if (dst == items) {
src += nsrc;
continue;
}
for (ndst = 1; dst + ndst < items; ndst++)
if (ki[dst + ndst].ki_d.level <= ki[dst].ki_d.level)
break;
for (n = src; n < src + nsrc; n++) {
ki[n].ki_d.level += ki[dst].ki_d.level + 1;
if (maxlvl < ki[n].ki_d.level)
maxlvl = ki[n].ki_d.level;
}
while (nsrc) {
if (src < dst) {
kn = ki[src];
memmove(ki + src, ki + src + 1,
(dst - src + ndst - 1) * sizeof *ki);
ki[dst + ndst - 1] = kn;
nsrc--;
dst--;
ndst++;
} else if (src != dst + ndst) {
kn = ki[src];
memmove(ki + dst + ndst + 1, ki + dst + ndst,
(src - dst - ndst) * sizeof *ki);
ki[dst + ndst] = kn;
ndst++;
nsrc--;
src++;
} else {
ndst += nsrc;
src += nsrc;
nsrc = 0;
}
}
}
/*
* Now populate ki_d.prefix (instead of ki_d.level) with the command
* prefix used to show descendancies.
*/
path = malloc((maxlvl + 7) / 8);
memset(path, '\0', (maxlvl + 7) / 8);
for (src = 0; src < items; src++) {
if ((lvl = ki[src].ki_d.level) == 0) {
ki[src].ki_d.prefix = NULL;
continue;
}
if ((ki[src].ki_d.prefix = malloc(lvl * 2 + 1)) == NULL)
errx(1, "malloc failed");
for (n = 0; n < lvl - 2; n++) {
ki[src].ki_d.prefix[n * 2] =
path[n / 8] & 1 << (n % 8) ? '|' : ' ';
ki[src].ki_d.prefix[n * 2 + 1] = ' ';
}
if (n == lvl - 2) {
/* Have I any more siblings? */
for (siblings = 0, dst = src + 1; dst < items; dst++) {
if (ki[dst].ki_d.level > lvl)
continue;
if (ki[dst].ki_d.level == lvl)
siblings = 1;
break;
}
if (siblings)
path[n / 8] |= 1 << (n % 8);
else
path[n / 8] &= ~(1 << (n % 8));
ki[src].ki_d.prefix[n * 2] = siblings ? '|' : '`';
ki[src].ki_d.prefix[n * 2 + 1] = '-';
n++;
}
strcpy(ki[src].ki_d.prefix + n * 2, "- ");
}
free(path);
}
static void *
expand_list(struct listinfo *inf)
{
@@ -1332,7 +1205,7 @@ check_procfs(void)
static void
usage(void)
{
#define SINGLE_OPTS "[-aCcde" OPT_LAZY_f "HhjlmrSTuvwXxZ]"
#define SINGLE_OPTS "[-aCce" OPT_LAZY_f "HhjlmrSTuvwXxZ]"
(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
"usage: ps " SINGLE_OPTS " [-O fmt | -o fmt] [-G gid[,gid...]]",
-4
View File
@@ -42,10 +42,6 @@ typedef struct kinfo {
int ki_valid; /* 1 => uarea stuff valid */
double ki_pcpu; /* calculated in main() */
segsz_t ki_memsize; /* calculated in main() */
union {
int level; /* used in decendant_sort() */
char *prefix; /* calculated in decendant_sort() */
} ki_d;
} KINFO;
/* Variables. */
-5
View File
@@ -1,5 +0,0 @@
# $FreeBSD$
PROG= pwait
.include <bsd.prog.mk>
-78
View File
@@ -1,78 +0,0 @@
.\"
.\" Copyright (c) 2004-2009, Jilles Tjoelker
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with
.\" or without modification, are permitted provided that the
.\" following conditions are met:
.\"
.\" 1. Redistributions of source code must retain the above
.\" copyright notice, this list of conditions and the
.\" following disclaimer.
.\" 2. Redistributions in binary form must reproduce the
.\" above copyright notice, this list of conditions and
.\" the following disclaimer in the documentation and/or
.\" other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
.\" COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
.\" USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
.\" OF SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd November 1, 2009
.Os
.Dt PWAIT 1
.Sh NAME
.Nm pwait
.Nd wait for processes to terminate
.Sh SYNOPSIS
.Nm
.Op Fl v
.Ar pid
\&...
.Sh DESCRIPTION
The
.Nm
utility will wait until each of the given processes has terminated.
.Pp
The following option is available:
.Bl -tag -width indent
.It Fl v
Print the exit status when each process terminates.
.El
.Sh DIAGNOSTICS
.Pp
The
.Nm
utility returns 0 on success, and >0 if an error occurs.
.Pp
Invalid pids elicit a warning message but are otherwise ignored.
.Sh SEE ALSO
.Xr kill 1 ,
.Xr pkill 1 ,
.Xr ps 1 ,
.Xr wait 1 ,
.Xr kqueue 2
.Sh NOTES
.Nm
is not a substitute for the
.Xr wait 1
builtin
as it will not clean up any zombies or state in the parent process.
.Sh HISTORY
A
.Nm
command first appeared in SunOS 5.8.
-145
View File
@@ -1,145 +0,0 @@
/*-
* Copyright (c) 2004-2009, Jilles Tjoelker
* All rights reserved.
*
* Redistribution and use in source and binary forms, with
* or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
static void
usage(void)
{
fprintf(stderr, "usage: pwait [-v] pid ...\n");
exit(EX_USAGE);
}
/*
* pwait - wait for processes to terminate
*/
int
main(int argc, char *argv[])
{
int kq;
struct kevent *e;
int verbose = 0;
int opt, nleft, n, i, duplicate, status;
long pid;
char *s, *end;
while ((opt = getopt(argc, argv, "v")) != -1) {
switch (opt) {
case 'v':
verbose = 1;
break;
default:
usage();
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
if (argc == 0)
usage();
kq = kqueue();
if (kq == -1)
err(1, "kqueue");
e = malloc(argc * sizeof(struct kevent));
if (e == NULL)
err(1, "malloc");
nleft = 0;
for (n = 0; n < argc; n++) {
s = argv[n];
if (!strncmp(s, "/proc/", 6)) /* Undocumented Solaris compat */
s += 6;
errno = 0;
pid = strtol(s, &end, 10);
if (pid < 0 || *end != '\0' || errno != 0) {
warnx("%s: bad process id", s);
continue;
}
duplicate = 0;
for (i = 0; i < nleft; i++)
if (e[i].ident == (uintptr_t)pid)
duplicate = 1;
if (!duplicate) {
EV_SET(e + nleft, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT,
0, NULL);
if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1)
warn("%ld", pid);
else
nleft++;
}
}
while (nleft > 0) {
n = kevent(kq, NULL, 0, e, nleft, NULL);
if (n == -1)
err(1, "kevent");
if (verbose)
for (i = 0; i < n; i++) {
status = e[i].data;
if (WIFEXITED(status))
printf("%ld: exited with status %d.\n",
(long)e[i].ident,
WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("%ld: killed by signal %d.\n",
(long)e[i].ident,
WTERMSIG(status));
else
printf("%ld: terminated.\n",
(long)e[i].ident);
}
nleft -= n;
}
return 0;
}
+3 -3
View File
@@ -231,7 +231,7 @@ rm_tree(char **argv)
else if (!uid &&
(p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
!(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) &&
lchflags(p->fts_accpath,
chflags(p->fts_accpath,
p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0)
goto err;
continue;
@@ -250,7 +250,7 @@ rm_tree(char **argv)
if (!uid &&
(p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
!(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)))
rval = lchflags(p->fts_accpath,
rval = chflags(p->fts_accpath,
p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE));
if (rval == 0) {
/*
@@ -350,7 +350,7 @@ rm_file(char **argv)
if (!uid && !S_ISWHT(sb.st_mode) &&
(sb.st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
!(sb.st_flags & (SF_APPEND|SF_IMMUTABLE)))
rval = lchflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE));
rval = chflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE));
if (rval == 0) {
if (S_ISWHT(sb.st_mode))
rval = undelete(f);
+1 -1
View File
@@ -22,7 +22,7 @@ LFLAGS= -8 # 8-bit lex scanner for arithmetic
CFLAGS+=-DSHELL -I. -I${.CURDIR}
# for debug:
# CFLAGS+= -g -DDEBUG=2
WARNS?= 2
WARNS?= 3
WFORMAT=0
.PATH: ${.CURDIR}/bltin \
+3 -23
View File
@@ -51,13 +51,6 @@ __FBSDID("$FreeBSD$");
int yylex(void);
struct varname
{
struct varname *next;
char name[1];
};
static struct varname *varnames;
#undef YY_INPUT
#define YY_INPUT(buf,result,max) \
result = (*buf = *arith_buf++) ? 1 : YY_NULL;
@@ -87,14 +80,11 @@ static struct varname *varnames;
* If variable doesn't exist, we should initialize
* it to zero.
*/
struct varname *temp;
char *temp;
if (lookupvar(yytext) == NULL)
setvarsafe(yytext, "0", 0);
temp = ckmalloc(sizeof(struct varname) +
strlen(yytext));
temp->next = varnames;
varnames = temp;
yylval.s_value = strcpy(temp->name, yytext);
temp = (char *)ckmalloc(strlen(yytext) + 1);
yylval.s_value = strcpy(temp, yytext);
return ARITH_VAR;
}
@@ -140,15 +130,5 @@ static struct varname *varnames;
void
arith_lex_reset(void)
{
struct varname *name, *next;
YY_NEW_FILE;
name = varnames;
while (name != NULL) {
next = name->next;
ckfree(name);
name = next;
}
varnames = NULL;
}
+2 -5
View File
@@ -773,7 +773,6 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
INTOFF;
savelocalvars = localvars;
localvars = NULL;
reffunc(cmdentry.u.func);
INTON;
if (setjmp(jmploc.loc)) {
if (exception == EXSHELLPROC)
@@ -782,7 +781,6 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
freeparam(&shellparam);
shellparam = saveparam;
}
unreffunc(cmdentry.u.func);
poplocalvars();
localvars = savelocalvars;
handler = savehandler;
@@ -794,12 +792,11 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
mklocal(sp->text);
funcnest++;
if (flags & EV_TESTED)
evaltree(getfuncnode(cmdentry.u.func), EV_TESTED);
evaltree(cmdentry.u.func, EV_TESTED);
else
evaltree(getfuncnode(cmdentry.u.func), 0);
evaltree(cmdentry.u.func, 0);
funcnest--;
INTOFF;
unreffunc(cmdentry.u.func);
poplocalvars();
localvars = savelocalvars;
freeparam(&shellparam);
+4 -4
View File
@@ -285,7 +285,7 @@ printentry(struct tblentry *cmdp, int verbose)
out1fmt("function %s", cmdp->cmdname);
if (verbose) {
INTOFF;
name = commandtext(getfuncnode(cmdp->param.func));
name = commandtext(cmdp->param.func);
out1c(' ');
out1str(name);
ckfree(name);
@@ -582,7 +582,7 @@ deletefuncs(void)
while ((cmdp = *pp) != NULL) {
if (cmdp->cmdtype == CMDFUNCTION) {
*pp = cmdp->next;
unreffunc(cmdp->param.func);
freefunc(cmdp->param.func);
ckfree(cmdp);
} else {
pp = &cmdp->next;
@@ -669,7 +669,7 @@ addcmdentry(char *name, struct cmdentry *entry)
INTOFF;
cmdp = cmdlookup(name, 1);
if (cmdp->cmdtype == CMDFUNCTION) {
unreffunc(cmdp->param.func);
freefunc(cmdp->param.func);
}
cmdp->cmdtype = entry->cmdtype;
cmdp->param = entry->u;
@@ -704,7 +704,7 @@ unsetfunc(char *name)
struct tblentry *cmdp;
if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {
unreffunc(cmdp->param.func);
freefunc(cmdp->param.func);
delete_cmd_entry();
return (0);
}
+1 -2
View File
@@ -46,12 +46,11 @@ enum {
TYPECMD_TYPE /* type */
};
union node;
struct cmdentry {
int cmdtype;
union param {
int index;
struct funcdef *func;
union node *func;
} u;
int special;
};
+2 -5
View File
@@ -248,11 +248,8 @@ output(char *file)
fputs("\tstruct nodelist *next;\n", hfile);
fputs("\tunion node *n;\n", hfile);
fputs("};\n\n\n", hfile);
fputs("struct funcdef;\n", hfile);
fputs("struct funcdef *copyfunc(union node *);\n", hfile);
fputs("union node *getfuncnode(struct funcdef *);\n", hfile);
fputs("void reffunc(struct funcdef *);\n", hfile);
fputs("void unreffunc(struct funcdef *);\n", hfile);
fputs("union node *copyfunc(union node *);\n", hfile);
fputs("void freefunc(union node *);\n", hfile);
fputs(writer, cfile);
while (fgets(line, sizeof line, patfile) != NULL) {
+9 -37
View File
@@ -35,7 +35,6 @@
#include <sys/param.h>
#include <stdlib.h>
#include <stddef.h>
/*
* Routine for dealing with parsed shell commands.
*/
@@ -61,40 +60,25 @@ STATIC struct nodelist *copynodelist(struct nodelist *);
STATIC char *nodesavestr(char *);
struct funcdef {
unsigned int refcount;
union node n;
};
/*
* Make a copy of a parse tree.
*/
struct funcdef *
union node *
copyfunc(union node *n)
{
struct funcdef *fn;
if (n == NULL)
return NULL;
funcblocksize = offsetof(struct funcdef, n);
funcblocksize = 0;
funcstringsize = 0;
calcsize(n);
fn = ckmalloc(funcblocksize + funcstringsize);
fn->refcount = 1;
funcblock = (char *)fn + offsetof(struct funcdef, n);
funcstring = (char *)fn + funcblocksize;
copynode(n);
return fn;
funcblock = ckmalloc(funcblocksize + funcstringsize);
funcstring = (char *)funcblock + funcblocksize;
return copynode(n);
}
union node *
getfuncnode(struct funcdef *fn)
{
return fn == NULL ? NULL : &fn->n;
}
STATIC void
calcsize(union node *n)
@@ -160,26 +144,14 @@ nodesavestr(char *s)
}
void
reffunc(struct funcdef *fn)
{
if (fn)
fn->refcount++;
}
/*
* Decrement the reference count of a function definition, freeing it
* if it falls to 0.
* Free a parse tree.
*/
void
unreffunc(struct funcdef *fn)
freefunc(union node *n)
{
if (fn) {
fn->refcount--;
if (fn->refcount > 0)
return;
ckfree(fn);
}
if (n)
ckfree(n);
}
-1
View File
@@ -250,7 +250,6 @@ pipeline(void)
int negate;
negate = 0;
checkkwd = 2;
TRACE(("pipeline: entered\n"));
while (readtoken() == TNOT)
negate = !negate;
+2 -6
View File
@@ -375,10 +375,6 @@ introduces a comment if used at the beginning of a word.
The word starting with
.Ql #
and the rest of the line are ignored.
.Pp
.Tn ASCII
.Dv NUL
characters (character code 0) are not allowed in shell input.
.Ss Quoting
Quoting is used to remove the special meaning of certain characters
or words to the shell, such as operators, whitespace, keywords,
@@ -856,7 +852,7 @@ command is:
If
.Ic in
and the following words are omitted,
.Ic in Li \&"$@\&"
.Ic in Li $@
is used instead.
The words are expanded, and then the list is executed
repeatedly with the variable set to each word in turn.
@@ -1071,7 +1067,7 @@ and
is
.Dq Li "def ghi" ,
then
.Li \&"$@\&"
.Dq Li $@
expands to
the two arguments:
.Bd -literal -offset indent
-2
View File
@@ -6,5 +6,3 @@ OPENSOLARIS_SYS_DISTDIR= ${.CURDIR}/../../../sys/cddl/contrib/opensolaris
IGNORE_PRAGMA= YES
CFLAGS+= -DNEED_SOLARIS_BOOLEAN
CSTD?= gnu89
@@ -1,36 +0,0 @@
/*-
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _OPENSOLARIS_LIBSHARE_H_
#define _OPENSOLARIS_LIBSHARE_H_
#define SA_OK 0
#define SA_INIT_CONTROL_API 0
#endif /* !_OPENSOLARIS_LIBSHARE_H_ */
-2
View File
@@ -9,8 +9,6 @@
#define MNTTAB _PATH_DEVNULL
#define MNT_LINE_MAX 1024
#define umount2(p, f) unmount(p, f)
struct mnttab {
char *mnt_special;
char *mnt_mountp;
+5 -1
View File
@@ -94,7 +94,11 @@ int
devid_get(int fd, ddi_devid_t *retdevid)
{
return (ENOENT);
if (ioctl(fd, DIOCGIDENT, retdevid->devid) == -1)
return (errno);
if (retdevid->devid[0] == '\0')
return (ENOENT);
return (0);
}
int
-2
View File
@@ -37,8 +37,6 @@ __FBSDID("$FreeBSD$");
#include <sys/mntent.h>
#include <sys/mnttab.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char *
mntopt(char **p)
+2 -3
View File
@@ -35,10 +35,9 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/uio.h>
#include <sys/mntent.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
static void
build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val,
@@ -87,7 +86,7 @@ zmount(const char *spec, const char *dir, int mflag, char *fstype,
assert(optlen > 0);
optstr = strdup(optptr);
assert(optstr != NULL);
assert(optptr != NULL);
iov = NULL;
iovlen = 0;
+2 -2
View File
@@ -32,7 +32,7 @@
#include <sys/sysctl.h>
#include <sys/zone.h>
zoneid_t
int
getzoneid(void)
{
size_t size;
@@ -42,5 +42,5 @@ getzoneid(void)
size = sizeof(jailid);
if (sysctlbyname("security.jail.jailed", &jailid, &size, NULL, 0) == -1)
assert(!"No security.jail.jailed sysctl!");
return ((zoneid_t)jailid);
return (jailid);
}
-9
View File
@@ -28,18 +28,13 @@ zdb \- ZFS debugger
.fi
.SH DESCRIPTION
.sp
.LP
The \fBzdb\fR command is used by support engineers to diagnose failures and gather statistics. Since the \fBZFS\fR file system is always consistent on disk and is self-repairing, \fBzdb\fR should only be run under the direction by a support engineer.
.sp
.LP
If no arguments are specified, \fBzdb\fR, performs basic consistency checks on the pool and associated datasets, and report any problems detected.
.sp
.LP
Any options supported by this command are internal to Sun and subject to change at any time.
.SH EXIT STATUS
.sp
.LP
The following exit values are returned:
.sp
@@ -76,9 +71,6 @@ Invalid command line options were specified.
.RE
.SH ATTRIBUTES
.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -97,6 +89,5 @@ Interface StabilityUnstable
.TE
.SH SEE ALSO
.sp
.LP
\fBzfs\fR(1M), \fBzpool\fR(1M), \fBattributes\fR(5)
File diff suppressed because it is too large. Load diff
+15 -24
View File
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -233,26 +233,19 @@ typedef struct zil_rec_info {
} zil_rec_info_t;
static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
{ NULL, "Total " },
{ zil_prt_rec_create, "TX_CREATE " },
{ zil_prt_rec_create, "TX_MKDIR " },
{ zil_prt_rec_create, "TX_MKXATTR " },
{ zil_prt_rec_create, "TX_SYMLINK " },
{ zil_prt_rec_remove, "TX_REMOVE " },
{ zil_prt_rec_remove, "TX_RMDIR " },
{ zil_prt_rec_link, "TX_LINK " },
{ zil_prt_rec_rename, "TX_RENAME " },
{ zil_prt_rec_write, "TX_WRITE " },
{ zil_prt_rec_truncate, "TX_TRUNCATE " },
{ zil_prt_rec_setattr, "TX_SETATTR " },
{ zil_prt_rec_acl, "TX_ACL_V0 " },
{ zil_prt_rec_acl, "TX_ACL_ACL " },
{ zil_prt_rec_create, "TX_CREATE_ACL " },
{ zil_prt_rec_create, "TX_CREATE_ATTR " },
{ zil_prt_rec_create, "TX_CREATE_ACL_ATTR " },
{ zil_prt_rec_create, "TX_MKDIR_ACL " },
{ zil_prt_rec_create, "TX_MKDIR_ATTR " },
{ zil_prt_rec_create, "TX_MKDIR_ACL_ATTR " },
{ NULL, "Total " },
{ zil_prt_rec_create, "TX_CREATE " },
{ zil_prt_rec_create, "TX_MKDIR " },
{ zil_prt_rec_create, "TX_MKXATTR " },
{ zil_prt_rec_create, "TX_SYMLINK " },
{ zil_prt_rec_remove, "TX_REMOVE " },
{ zil_prt_rec_remove, "TX_RMDIR " },
{ zil_prt_rec_link, "TX_LINK " },
{ zil_prt_rec_rename, "TX_RENAME " },
{ zil_prt_rec_write, "TX_WRITE " },
{ zil_prt_rec_truncate, "TX_TRUNCATE" },
{ zil_prt_rec_setattr, "TX_SETATTR " },
{ zil_prt_rec_acl, "TX_ACL " },
};
/* ARGSUSED */
@@ -262,14 +255,12 @@ print_log_record(zilog_t *zilog, lr_t *lr, void *arg, uint64_t claim_txg)
int txtype;
int verbose = MAX(dump_opt['d'], dump_opt['i']);
/* reduce size of txtype to strip off TX_CI bit */
txtype = lr->lrc_txtype;
ASSERT(txtype != 0 && (uint_t)txtype < TX_MAX_TYPE);
ASSERT(lr->lrc_txg);
(void) printf("\t\t%s%s len %6llu, txg %llu, seq %llu\n",
(lr->lrc_txtype & TX_CI) ? "CI-" : "",
(void) printf("\t\t%s len %6llu, txg %llu, seq %llu\n",
zil_rec_info[txtype].zri_name,
(u_longlong_t)lr->lrc_reclen,
(u_longlong_t)lr->lrc_txg,
File diff suppressed because it is too large. Load diff
+28 -43
View File
@@ -19,10 +19,12 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <libintl.h>
#include <libuutil.h>
#include <stddef.h>
@@ -54,43 +56,28 @@ typedef struct zfs_node {
typedef struct callback_data {
uu_avl_t *cb_avl;
int cb_flags;
int cb_recurse;
zfs_type_t cb_types;
zfs_sort_column_t *cb_sortcol;
zprop_list_t **cb_proplist;
zfs_proplist_t **cb_proplist;
} callback_data_t;
uu_avl_pool_t *avl_pool;
/*
* Include snaps if they were requested or if this a zfs list where types
* were not specified and the "listsnapshots" property is set on this pool.
*/
static int
zfs_include_snapshots(zfs_handle_t *zhp, callback_data_t *cb)
{
zpool_handle_t *zph;
if ((cb->cb_flags & ZFS_ITER_PROP_LISTSNAPS) == 0)
return (cb->cb_types & ZFS_TYPE_SNAPSHOT);
zph = zfs_get_pool_handle(zhp);
return (zpool_get_prop_int(zph, ZPOOL_PROP_LISTSNAPS, NULL));
}
/*
* Called for each dataset. If the object is of an appropriate type,
* Called for each dataset. If the object the object is of an appropriate type,
* add it to the avl tree and recurse over any children as necessary.
*/
static int
int
zfs_callback(zfs_handle_t *zhp, void *data)
{
callback_data_t *cb = data;
int dontclose = 0;
int include_snaps = zfs_include_snapshots(zhp, cb);
if ((zfs_get_type(zhp) & cb->cb_types) ||
((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
/*
* If this object is of the appropriate type, add it to the AVL tree.
*/
if (zfs_get_type(zhp) & cb->cb_types) {
uu_avl_index_t idx;
zfs_node_t *node = safe_malloc(sizeof (zfs_node_t));
@@ -113,12 +100,10 @@ zfs_callback(zfs_handle_t *zhp, void *data)
/*
* Recurse if necessary.
*/
if (cb->cb_flags & ZFS_ITER_RECURSE) {
if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
(void) zfs_iter_filesystems(zhp, zfs_callback, data);
if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps)
(void) zfs_iter_snapshots(zhp, zfs_callback, data);
}
if (cb->cb_recurse && (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM ||
(zfs_get_type(zhp) == ZFS_TYPE_VOLUME && (cb->cb_types &
ZFS_TYPE_SNAPSHOT))))
(void) zfs_iter_children(zhp, zfs_callback, data);
if (!dontclose)
zfs_close(zhp);
@@ -133,7 +118,7 @@ zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
zfs_sort_column_t *col;
zfs_prop_t prop;
if ((prop = zfs_name_to_prop(name)) == ZPROP_INVAL &&
if ((prop = zfs_name_to_prop(name)) == ZFS_PROP_INVAL &&
!zfs_prop_user(name))
return (-1);
@@ -141,7 +126,7 @@ zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
col->sc_prop = prop;
col->sc_reverse = reverse;
if (prop == ZPROP_INVAL) {
if (prop == ZFS_PROP_INVAL) {
col->sc_user_prop = safe_malloc(strlen(name) + 1);
(void) strcpy(col->sc_user_prop, name);
}
@@ -258,7 +243,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
* Otherwise, we compare 'lnum' and 'rnum'.
*/
lstr = rstr = NULL;
if (psc->sc_prop == ZPROP_INVAL) {
if (psc->sc_prop == ZFS_PROP_INVAL) {
nvlist_t *luser, *ruser;
nvlist_t *lval, *rval;
@@ -272,10 +257,10 @@ zfs_sort(const void *larg, const void *rarg, void *data)
if (lvalid)
verify(nvlist_lookup_string(lval,
ZPROP_VALUE, &lstr) == 0);
ZFS_PROP_VALUE, &lstr) == 0);
if (rvalid)
verify(nvlist_lookup_string(rval,
ZPROP_VALUE, &rstr) == 0);
ZFS_PROP_VALUE, &rstr) == 0);
} else if (zfs_prop_is_string(psc->sc_prop)) {
lvalid = (zfs_prop_get(l, psc->sc_prop, lbuf,
@@ -308,7 +293,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
if (lstr)
ret = strcmp(lstr, rstr);
else if (lnum < rnum)
if (lnum < rnum)
ret = -1;
else if (lnum > rnum)
ret = 1;
@@ -324,9 +309,9 @@ zfs_sort(const void *larg, const void *rarg, void *data)
}
int
zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
zfs_sort_column_t *sortcol, zprop_list_t **proplist,
zfs_iter_f callback, void *data)
zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
zfs_sort_column_t *sortcol, zfs_proplist_t **proplist, zfs_iter_f callback,
void *data, boolean_t args_can_be_paths)
{
callback_data_t cb;
int ret = 0;
@@ -343,7 +328,7 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
}
cb.cb_sortcol = sortcol;
cb.cb_flags = flags;
cb.cb_recurse = recurse;
cb.cb_proplist = proplist;
cb.cb_types = types;
if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) {
@@ -356,7 +341,7 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
/*
* If given no arguments, iterate over all datasets.
*/
cb.cb_flags |= ZFS_ITER_RECURSE;
cb.cb_recurse = 1;
ret = zfs_iter_root(g_zfs, zfs_callback, &cb);
} else {
int i;
@@ -369,14 +354,14 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
* can take volumes as well.
*/
argtype = types;
if (flags & ZFS_ITER_RECURSE) {
if (recurse) {
argtype |= ZFS_TYPE_FILESYSTEM;
if (types & ZFS_TYPE_SNAPSHOT)
argtype |= ZFS_TYPE_VOLUME;
}
for (i = 0; i < argc; i++) {
if (flags & ZFS_ITER_ARGS_CAN_BE_PATHS) {
if (args_can_be_paths) {
zhp = zfs_path_to_zhandle(g_zfs, argv[i],
argtype);
} else {
+5 -7
View File
@@ -19,13 +19,15 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef ZFS_ITER_H
#define ZFS_ITER_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
@@ -38,12 +40,8 @@ typedef struct zfs_sort_column {
boolean_t sc_reverse;
} zfs_sort_column_t;
#define ZFS_ITER_RECURSE (1 << 0)
#define ZFS_ITER_ARGS_CAN_BE_PATHS (1 << 1)
#define ZFS_ITER_PROP_LISTSNAPS (1 << 2)
int zfs_for_each(int, char **, int options, zfs_type_t,
zfs_sort_column_t *, zprop_list_t **, zfs_iter_f, void *);
int zfs_for_each(int, char **, boolean_t, zfs_type_t, zfs_sort_column_t *,
zfs_proplist_t **, zfs_iter_f, void *, boolean_t);
int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t);
void zfs_free_sort_columns(zfs_sort_column_t *);
File diff suppressed because it is too large. Load diff
@@ -1,460 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <libzfs.h>
#undef verify /* both libzfs.h and zfs_context.h want to define this */
#include <sys/zfs_context.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/file.h>
#include <sys/mntent.h>
#include <sys/mnttab.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/dmu.h>
#include <sys/dmu_objset.h>
#include <sys/dnode.h>
#include <sys/vdev_impl.h>
#include "zinject.h"
#include <assert.h>
#define verify assert
extern void kernel_init(int);
extern void kernel_fini(void);
static int debug;
static void
ziprintf(const char *fmt, ...)
{
va_list ap;
if (!debug)
return;
va_start(ap, fmt);
(void) vprintf(fmt, ap);
va_end(ap);
}
/*
* Given a full path to a file, translate into a dataset name and a relative
* path within the dataset. 'dataset' must be at least MAXNAMELEN characters,
* and 'relpath' must be at least MAXPATHLEN characters. We also pass a stat64
* buffer, which we need later to get the object ID.
*/
static int
parse_pathname(const char *fullpath, char *dataset, char *relpath,
struct stat64 *statbuf)
{
struct statfs sfs;
const char *rel;
if (fullpath[0] != '/') {
(void) fprintf(stderr, "invalid object '%s': must be full "
"path\n", fullpath);
usage();
return (-1);
}
if (strlen(fullpath) >= MAXPATHLEN) {
(void) fprintf(stderr, "invalid object; pathname too long\n");
return (-1);
}
if (stat64(fullpath, statbuf) != 0) {
(void) fprintf(stderr, "cannot open '%s': %s\n",
fullpath, strerror(errno));
return (-1);
}
if (statfs(fullpath, &sfs) == -1) {
(void) fprintf(stderr, "cannot find mountpoint for '%s': %s\n",
fullpath, strerror(errno));
return (-1);
}
if (strcmp(sfs.f_fstypename, MNTTYPE_ZFS) != 0) {
(void) fprintf(stderr, "invalid path '%s': not a ZFS "
"filesystem\n", fullpath);
return (-1);
}
if (strncmp(fullpath, sfs.f_mntonname, strlen(sfs.f_mntonname)) != 0) {
(void) fprintf(stderr, "invalid path '%s': mountpoint "
"doesn't match path\n", fullpath);
return (-1);
}
(void) strcpy(dataset, sfs.f_mntfromname);
rel = fullpath + strlen(sfs.f_mntonname);
if (rel[0] == '/')
rel++;
(void) strcpy(relpath, rel);
return (0);
}
/*
* Convert from a (dataset, path) pair into a (objset, object) pair. Note that
* we grab the object number from the inode number, since looking this up via
* libzpool is a real pain.
*/
/* ARGSUSED */
static int
object_from_path(const char *dataset, const char *path, struct stat64 *statbuf,
zinject_record_t *record)
{
objset_t *os;
int err;
/*
* Before doing any libzpool operations, call sync() to ensure that the
* on-disk state is consistent with the in-core state.
*/
sync();
if ((err = dmu_objset_open(dataset, DMU_OST_ZFS,
DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) {
(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
dataset, strerror(err));
return (-1);
}
record->zi_objset = dmu_objset_id(os);
record->zi_object = statbuf->st_ino;
dmu_objset_close(os);
return (0);
}
/*
* Calculate the real range based on the type, level, and range given.
*/
static int
calculate_range(const char *dataset, err_type_t type, int level, char *range,
zinject_record_t *record)
{
objset_t *os = NULL;
dnode_t *dn = NULL;
int err;
int ret = -1;
/*
* Determine the numeric range from the string.
*/
if (range == NULL) {
/*
* If range is unspecified, set the range to [0,-1], which
* indicates that the whole object should be treated as an
* error.
*/
record->zi_start = 0;
record->zi_end = -1ULL;
} else {
char *end;
/* XXX add support for suffixes */
record->zi_start = strtoull(range, &end, 10);
if (*end == '\0')
record->zi_end = record->zi_start + 1;
else if (*end == ',')
record->zi_end = strtoull(end + 1, &end, 10);
if (*end != '\0') {
(void) fprintf(stderr, "invalid range '%s': must be "
"a numeric range of the form 'start[,end]'\n",
range);
goto out;
}
}
switch (type) {
case TYPE_DATA:
break;
case TYPE_DNODE:
/*
* If this is a request to inject faults into the dnode, then we
* must translate the current (objset,object) pair into an
* offset within the metadnode for the objset. Specifying any
* kind of range with type 'dnode' is illegal.
*/
if (range != NULL) {
(void) fprintf(stderr, "range cannot be specified when "
"type is 'dnode'\n");
goto out;
}
record->zi_start = record->zi_object * sizeof (dnode_phys_t);
record->zi_end = record->zi_start + sizeof (dnode_phys_t);
record->zi_object = 0;
break;
}
/*
* Get the dnode associated with object, so we can calculate the block
* size.
*/
if ((err = dmu_objset_open(dataset, DMU_OST_ANY,
DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) {
(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
dataset, strerror(err));
goto out;
}
if (record->zi_object == 0) {
dn = os->os->os_meta_dnode;
} else {
err = dnode_hold(os->os, record->zi_object, FTAG, &dn);
if (err != 0) {
(void) fprintf(stderr, "failed to hold dnode "
"for object %llu\n",
(u_longlong_t)record->zi_object);
goto out;
}
}
ziprintf("data shift: %d\n", (int)dn->dn_datablkshift);
ziprintf(" ind shift: %d\n", (int)dn->dn_indblkshift);
/*
* Translate range into block IDs.
*/
if (record->zi_start != 0 || record->zi_end != -1ULL) {
record->zi_start >>= dn->dn_datablkshift;
record->zi_end >>= dn->dn_datablkshift;
}
/*
* Check level, and then translate level 0 blkids into ranges
* appropriate for level of indirection.
*/
record->zi_level = level;
if (level > 0) {
ziprintf("level 0 blkid range: [%llu, %llu]\n",
record->zi_start, record->zi_end);
if (level >= dn->dn_nlevels) {
(void) fprintf(stderr, "level %d exceeds max level "
"of object (%d)\n", level, dn->dn_nlevels - 1);
goto out;
}
if (record->zi_start != 0 || record->zi_end != 0) {
int shift = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
for (; level > 0; level--) {
record->zi_start >>= shift;
record->zi_end >>= shift;
}
}
}
ret = 0;
out:
if (dn) {
if (dn != os->os->os_meta_dnode)
dnode_rele(dn, FTAG);
}
if (os)
dmu_objset_close(os);
return (ret);
}
int
translate_record(err_type_t type, const char *object, const char *range,
int level, zinject_record_t *record, char *poolname, char *dataset)
{
char path[MAXPATHLEN];
char *slash;
struct stat64 statbuf;
int ret = -1;
kernel_init(FREAD);
debug = (getenv("ZINJECT_DEBUG") != NULL);
ziprintf("translating: %s\n", object);
if (MOS_TYPE(type)) {
/*
* MOS objects are treated specially.
*/
switch (type) {
case TYPE_MOS:
record->zi_type = 0;
break;
case TYPE_MOSDIR:
record->zi_type = DMU_OT_OBJECT_DIRECTORY;
break;
case TYPE_METASLAB:
record->zi_type = DMU_OT_OBJECT_ARRAY;
break;
case TYPE_CONFIG:
record->zi_type = DMU_OT_PACKED_NVLIST;
break;
case TYPE_BPLIST:
record->zi_type = DMU_OT_BPLIST;
break;
case TYPE_SPACEMAP:
record->zi_type = DMU_OT_SPACE_MAP;
break;
case TYPE_ERRLOG:
record->zi_type = DMU_OT_ERROR_LOG;
break;
}
dataset[0] = '\0';
(void) strcpy(poolname, object);
return (0);
}
/*
* Convert a full path into a (dataset, file) pair.
*/
if (parse_pathname(object, dataset, path, &statbuf) != 0)
goto err;
ziprintf(" dataset: %s\n", dataset);
ziprintf(" path: %s\n", path);
/*
* Convert (dataset, file) into (objset, object)
*/
if (object_from_path(dataset, path, &statbuf, record) != 0)
goto err;
ziprintf("raw objset: %llu\n", record->zi_objset);
ziprintf("raw object: %llu\n", record->zi_object);
/*
* For the given object, calculate the real (type, level, range)
*/
if (calculate_range(dataset, type, level, (char *)range, record) != 0)
goto err;
ziprintf(" objset: %llu\n", record->zi_objset);
ziprintf(" object: %llu\n", record->zi_object);
if (record->zi_start == 0 &&
record->zi_end == -1ULL)
ziprintf(" range: all\n");
else
ziprintf(" range: [%llu, %llu]\n", record->zi_start,
record->zi_end);
/*
* Copy the pool name
*/
(void) strcpy(poolname, dataset);
if ((slash = strchr(poolname, '/')) != NULL)
*slash = '\0';
ret = 0;
err:
kernel_fini();
return (ret);
}
int
translate_raw(const char *str, zinject_record_t *record)
{
/*
* A raw bookmark of the form objset:object:level:blkid, where each
* number is a hexidecimal value.
*/
if (sscanf(str, "%llx:%llx:%x:%llx", (u_longlong_t *)&record->zi_objset,
(u_longlong_t *)&record->zi_object, &record->zi_level,
(u_longlong_t *)&record->zi_start) != 4) {
(void) fprintf(stderr, "bad raw spec '%s': must be of the form "
"'objset:object:level:blkid'\n", str);
return (-1);
}
record->zi_end = record->zi_start;
return (0);
}
int
translate_device(const char *pool, const char *device, err_type_t label_type,
zinject_record_t *record)
{
char *end;
zpool_handle_t *zhp;
nvlist_t *tgt;
boolean_t isspare, iscache;
/*
* Given a device name or GUID, create an appropriate injection record
* with zi_guid set.
*/
if ((zhp = zpool_open(g_zfs, pool)) == NULL)
return (-1);
record->zi_guid = strtoull(device, &end, 16);
if (record->zi_guid == 0 || *end != '\0') {
tgt = zpool_find_vdev(zhp, device, &isspare, &iscache, NULL);
if (tgt == NULL) {
(void) fprintf(stderr, "cannot find device '%s' in "
"pool '%s'\n", device, pool);
return (-1);
}
verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
&record->zi_guid) == 0);
}
switch (label_type) {
case TYPE_LABEL_UBERBLOCK:
record->zi_start = offsetof(vdev_label_t, vl_uberblock[0]);
record->zi_end = record->zi_start + VDEV_UBERBLOCK_RING - 1;
break;
case TYPE_LABEL_NVLIST:
record->zi_start = offsetof(vdev_label_t, vl_vdev_phys);
record->zi_end = record->zi_start + VDEV_PHYS_SIZE - 1;
break;
}
return (0);
}
@@ -1,771 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* ZFS Fault Injector
*
* This userland component takes a set of options and uses libzpool to translate
* from a user-visible object type and name to an internal representation.
* There are two basic types of faults: device faults and data faults.
*
*
* DEVICE FAULTS
*
* Errors can be injected into a particular vdev using the '-d' option. This
* option takes a path or vdev GUID to uniquely identify the device within a
* pool. There are two types of errors that can be injected, EIO and ENXIO,
* that can be controlled through the '-e' option. The default is ENXIO. For
* EIO failures, any attempt to read data from the device will return EIO, but
* subsequent attempt to reopen the device will succeed. For ENXIO failures,
* any attempt to read from the device will return EIO, but any attempt to
* reopen the device will also return ENXIO.
* For label faults, the -L option must be specified. This allows faults
* to be injected into either the nvlist or uberblock region of all the labels
* for the specified device.
*
* This form of the command looks like:
*
* zinject -d device [-e errno] [-L <uber | nvlist>] pool
*
*
* DATA FAULTS
*
* We begin with a tuple of the form:
*
* <type,level,range,object>
*
* type A string describing the type of data to target. Each type
* implicitly describes how to interpret 'object'. Currently,
* the following values are supported:
*
* data User data for a file
* dnode Dnode for a file or directory
*
* The following MOS objects are special. Instead of injecting
* errors on a particular object or blkid, we inject errors across
* all objects of the given type.
*
* mos Any data in the MOS
* mosdir object directory
* config pool configuration
* bplist blkptr list
* spacemap spacemap
* metaslab metaslab
* errlog persistent error log
*
* level Object level. Defaults to '0', not applicable to all types. If
* a range is given, this corresponds to the indirect block
* corresponding to the specific range.
*
* range A numerical range [start,end) within the object. Defaults to
* the full size of the file.
*
* object A string describing the logical location of the object. For
* files and directories (currently the only supported types),
* this is the path of the object on disk.
*
* This is translated, via libzpool, into the following internal representation:
*
* <type,objset,object,level,range>
*
* These types should be self-explanatory. This tuple is then passed to the
* kernel via a special ioctl() to initiate fault injection for the given
* object. Note that 'type' is not strictly necessary for fault injection, but
* is used when translating existing faults into a human-readable string.
*
*
* The command itself takes one of the forms:
*
* zinject
* zinject <-a | -u pool>
* zinject -c <id|all>
* zinject [-q] <-t type> [-f freq] [-u] [-a] [-m] [-e errno] [-l level]
* [-r range] <object>
* zinject [-f freq] [-a] [-m] [-u] -b objset:object:level:start:end pool
*
* With no arguments, the command prints all currently registered injection
* handlers, with their numeric identifiers.
*
* The '-c' option will clear the given handler, or all handlers if 'all' is
* specified.
*
* The '-e' option takes a string describing the errno to simulate. This must
* be either 'io' or 'checksum'. In most cases this will result in the same
* behavior, but RAID-Z will produce a different set of ereports for this
* situation.
*
* The '-a', '-u', and '-m' flags toggle internal flush behavior. If '-a' is
* specified, then the ARC cache is flushed appropriately. If '-u' is
* specified, then the underlying SPA is unloaded. Either of these flags can be
* specified independently of any other handlers. The '-m' flag automatically
* does an unmount and remount of the underlying dataset to aid in flushing the
* cache.
*
* The '-f' flag controls the frequency of errors injected, expressed as a
* integer percentage between 1 and 100. The default is 100.
*
* The this form is responsible for actually injecting the handler into the
* framework. It takes the arguments described above, translates them to the
* internal tuple using libzpool, and then issues an ioctl() to register the
* handler.
*
* The final form can target a specific bookmark, regardless of whether a
* human-readable interface has been designed. It allows developers to specify
* a particular block by number.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <sys/fs/zfs.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <libzfs.h>
#undef verify /* both libzfs.h and zfs_context.h want to define this */
#include "zinject.h"
libzfs_handle_t *g_zfs;
int zfs_fd;
#ifndef ECKSUM
#define ECKSUM EBADE
#endif
static const char *errtable[TYPE_INVAL] = {
"data",
"dnode",
"mos",
"mosdir",
"metaslab",
"config",
"bplist",
"spacemap",
"errlog",
"uber",
"nvlist"
};
static err_type_t
name_to_type(const char *arg)
{
int i;
for (i = 0; i < TYPE_INVAL; i++)
if (strcmp(errtable[i], arg) == 0)
return (i);
return (TYPE_INVAL);
}
static const char *
type_to_name(uint64_t type)
{
switch (type) {
case DMU_OT_OBJECT_DIRECTORY:
return ("mosdir");
case DMU_OT_OBJECT_ARRAY:
return ("metaslab");
case DMU_OT_PACKED_NVLIST:
return ("config");
case DMU_OT_BPLIST:
return ("bplist");
case DMU_OT_SPACE_MAP:
return ("spacemap");
case DMU_OT_ERROR_LOG:
return ("errlog");
default:
return ("-");
}
}
/*
* Print usage message.
*/
void
usage(void)
{
(void) printf(
"usage:\n"
"\n"
"\tzinject\n"
"\n"
"\t\tList all active injection records.\n"
"\n"
"\tzinject -c <id|all>\n"
"\n"
"\t\tClear the particular record (if given a numeric ID), or\n"
"\t\tall records if 'all' is specificed.\n"
"\n"
"\tzinject -d device [-e errno] [-L <nvlist|uber>] pool\n"
"\t\tInject a fault into a particular device or the device's\n"
"\t\tlabel. Label injection can either be 'nvlist' or 'uber'.\n"
"\t\t'errno' can either be 'nxio' (the default) or 'io'.\n"
"\n"
"\tzinject -b objset:object:level:blkid pool\n"
"\n"
"\t\tInject an error into pool 'pool' with the numeric bookmark\n"
"\t\tspecified by the remaining tuple. Each number is in\n"
"\t\thexidecimal, and only one block can be specified.\n"
"\n"
"\tzinject [-q] <-t type> [-e errno] [-l level] [-r range]\n"
"\t [-a] [-m] [-u] [-f freq] <object>\n"
"\n"
"\t\tInject an error into the object specified by the '-t' option\n"
"\t\tand the object descriptor. The 'object' parameter is\n"
"\t\tinterperted depending on the '-t' option.\n"
"\n"
"\t\t-q\tQuiet mode. Only print out the handler number added.\n"
"\t\t-e\tInject a specific error. Must be either 'io' or\n"
"\t\t\t'checksum'. Default is 'io'.\n"
"\t\t-l\tInject error at a particular block level. Default is "
"0.\n"
"\t\t-m\tAutomatically remount underlying filesystem.\n"
"\t\t-r\tInject error over a particular logical range of an\n"
"\t\t\tobject. Will be translated to the appropriate blkid\n"
"\t\t\trange according to the object's properties.\n"
"\t\t-a\tFlush the ARC cache. Can be specified without any\n"
"\t\t\tassociated object.\n"
"\t\t-u\tUnload the associated pool. Can be specified with only\n"
"\t\t\ta pool object.\n"
"\t\t-f\tOnly inject errors a fraction of the time. Expressed as\n"
"\t\t\ta percentage between 1 and 100.\n"
"\n"
"\t-t data\t\tInject an error into the plain file contents of a\n"
"\t\t\tfile. The object must be specified as a complete path\n"
"\t\t\tto a file on a ZFS filesystem.\n"
"\n"
"\t-t dnode\tInject an error into the metadnode in the block\n"
"\t\t\tcorresponding to the dnode for a file or directory. The\n"
"\t\t\t'-r' option is incompatible with this mode. The object\n"
"\t\t\tis specified as a complete path to a file or directory\n"
"\t\t\ton a ZFS filesystem.\n"
"\n"
"\t-t <mos>\tInject errors into the MOS for objects of the given\n"
"\t\t\ttype. Valid types are: mos, mosdir, config, bplist,\n"
"\t\t\tspacemap, metaslab, errlog. The only valid <object> is\n"
"\t\t\tthe poolname.\n");
}
static int
iter_handlers(int (*func)(int, const char *, zinject_record_t *, void *),
void *data)
{
zfs_cmd_t zc;
int ret;
zc.zc_guid = 0;
while (ioctl(zfs_fd, ZFS_IOC_INJECT_LIST_NEXT, &zc) == 0)
if ((ret = func((int)zc.zc_guid, zc.zc_name,
&zc.zc_inject_record, data)) != 0)
return (ret);
return (0);
}
static int
print_data_handler(int id, const char *pool, zinject_record_t *record,
void *data)
{
int *count = data;
if (record->zi_guid != 0)
return (0);
if (*count == 0) {
(void) printf("%3s %-15s %-6s %-6s %-8s %3s %-15s\n",
"ID", "POOL", "OBJSET", "OBJECT", "TYPE", "LVL", "RANGE");
(void) printf("--- --------------- ------ "
"------ -------- --- ---------------\n");
}
*count += 1;
(void) printf("%3d %-15s %-6llu %-6llu %-8s %3d ", id, pool,
(u_longlong_t)record->zi_objset, (u_longlong_t)record->zi_object,
type_to_name(record->zi_type), record->zi_level);
if (record->zi_start == 0 &&
record->zi_end == -1ULL)
(void) printf("all\n");
else
(void) printf("[%llu, %llu]\n", (u_longlong_t)record->zi_start,
(u_longlong_t)record->zi_end);
return (0);
}
static int
print_device_handler(int id, const char *pool, zinject_record_t *record,
void *data)
{
int *count = data;
if (record->zi_guid == 0)
return (0);
if (*count == 0) {
(void) printf("%3s %-15s %s\n", "ID", "POOL", "GUID");
(void) printf("--- --------------- ----------------\n");
}
*count += 1;
(void) printf("%3d %-15s %llx\n", id, pool,
(u_longlong_t)record->zi_guid);
return (0);
}
/*
* Print all registered error handlers. Returns the number of handlers
* registered.
*/
static int
print_all_handlers(void)
{
int count = 0;
(void) iter_handlers(print_device_handler, &count);
(void) printf("\n");
count = 0;
(void) iter_handlers(print_data_handler, &count);
return (count);
}
/* ARGSUSED */
static int
cancel_one_handler(int id, const char *pool, zinject_record_t *record,
void *data)
{
zfs_cmd_t zc;
zc.zc_guid = (uint64_t)id;
if (ioctl(zfs_fd, ZFS_IOC_CLEAR_FAULT, &zc) != 0) {
(void) fprintf(stderr, "failed to remove handler %d: %s\n",
id, strerror(errno));
return (1);
}
return (0);
}
/*
* Remove all fault injection handlers.
*/
static int
cancel_all_handlers(void)
{
int ret = iter_handlers(cancel_one_handler, NULL);
(void) printf("removed all registered handlers\n");
return (ret);
}
/*
* Remove a specific fault injection handler.
*/
static int
cancel_handler(int id)
{
zfs_cmd_t zc;
zc.zc_guid = (uint64_t)id;
if (ioctl(zfs_fd, ZFS_IOC_CLEAR_FAULT, &zc) != 0) {
(void) fprintf(stderr, "failed to remove handler %d: %s\n",
id, strerror(errno));
return (1);
}
(void) printf("removed handler %d\n", id);
return (0);
}
/*
* Register a new fault injection handler.
*/
static int
register_handler(const char *pool, int flags, zinject_record_t *record,
int quiet)
{
zfs_cmd_t zc;
(void) strcpy(zc.zc_name, pool);
zc.zc_inject_record = *record;
zc.zc_guid = flags;
if (ioctl(zfs_fd, ZFS_IOC_INJECT_FAULT, &zc) != 0) {
(void) fprintf(stderr, "failed to add handler: %s\n",
strerror(errno));
return (1);
}
if (flags & ZINJECT_NULL)
return (0);
if (quiet) {
(void) printf("%llu\n", (u_longlong_t)zc.zc_guid);
} else {
(void) printf("Added handler %llu with the following "
"properties:\n", (u_longlong_t)zc.zc_guid);
(void) printf(" pool: %s\n", pool);
if (record->zi_guid) {
(void) printf(" vdev: %llx\n",
(u_longlong_t)record->zi_guid);
} else {
(void) printf("objset: %llu\n",
(u_longlong_t)record->zi_objset);
(void) printf("object: %llu\n",
(u_longlong_t)record->zi_object);
(void) printf(" type: %llu\n",
(u_longlong_t)record->zi_type);
(void) printf(" level: %d\n", record->zi_level);
if (record->zi_start == 0 &&
record->zi_end == -1ULL)
(void) printf(" range: all\n");
else
(void) printf(" range: [%llu, %llu)\n",
(u_longlong_t)record->zi_start,
(u_longlong_t)record->zi_end);
}
}
return (0);
}
int
main(int argc, char **argv)
{
int c;
char *range = NULL;
char *cancel = NULL;
char *end;
char *raw = NULL;
char *device = NULL;
int level = 0;
int quiet = 0;
int error = 0;
int domount = 0;
err_type_t type = TYPE_INVAL;
err_type_t label = TYPE_INVAL;
zinject_record_t record = { 0 };
char pool[MAXNAMELEN];
char dataset[MAXNAMELEN];
zfs_handle_t *zhp;
int ret;
int flags = 0;
if ((g_zfs = libzfs_init()) == NULL) {
(void) fprintf(stderr, "internal error: failed to "
"initialize ZFS library\n");
return (1);
}
libzfs_print_on_error(g_zfs, B_TRUE);
if ((zfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
(void) fprintf(stderr, "failed to open ZFS device\n");
return (1);
}
if (argc == 1) {
/*
* No arguments. Print the available handlers. If there are no
* available handlers, direct the user to '-h' for help
* information.
*/
if (print_all_handlers() == 0) {
(void) printf("No handlers registered.\n");
(void) printf("Run 'zinject -h' for usage "
"information.\n");
}
return (0);
}
while ((c = getopt(argc, argv, ":ab:d:f:qhc:t:l:mr:e:uL:")) != -1) {
switch (c) {
case 'a':
flags |= ZINJECT_FLUSH_ARC;
break;
case 'b':
raw = optarg;
break;
case 'c':
cancel = optarg;
break;
case 'd':
device = optarg;
break;
case 'e':
if (strcasecmp(optarg, "io") == 0) {
error = EIO;
} else if (strcasecmp(optarg, "checksum") == 0) {
error = ECKSUM;
} else if (strcasecmp(optarg, "nxio") == 0) {
error = ENXIO;
} else {
(void) fprintf(stderr, "invalid error type "
"'%s': must be 'io', 'checksum' or "
"'nxio'\n", optarg);
usage();
return (1);
}
break;
case 'f':
record.zi_freq = atoi(optarg);
if (record.zi_freq < 1 || record.zi_freq > 100) {
(void) fprintf(stderr, "frequency range must "
"be in the range (0, 100]\n");
return (1);
}
break;
case 'h':
usage();
return (0);
case 'l':
level = (int)strtol(optarg, &end, 10);
if (*end != '\0') {
(void) fprintf(stderr, "invalid level '%s': "
"must be an integer\n", optarg);
usage();
return (1);
}
break;
case 'm':
domount = 1;
break;
case 'q':
quiet = 1;
break;
case 'r':
range = optarg;
break;
case 't':
if ((type = name_to_type(optarg)) == TYPE_INVAL &&
!MOS_TYPE(type)) {
(void) fprintf(stderr, "invalid type '%s'\n",
optarg);
usage();
return (1);
}
break;
case 'u':
flags |= ZINJECT_UNLOAD_SPA;
break;
case 'L':
if ((label = name_to_type(optarg)) == TYPE_INVAL &&
!LABEL_TYPE(type)) {
(void) fprintf(stderr, "invalid label type "
"'%s'\n", optarg);
usage();
return (1);
}
break;
case ':':
(void) fprintf(stderr, "option -%c requires an "
"operand\n", optopt);
usage();
return (1);
case '?':
(void) fprintf(stderr, "invalid option '%c'\n",
optopt);
usage();
return (2);
}
}
argc -= optind;
argv += optind;
if (cancel != NULL) {
/*
* '-c' is invalid with any other options.
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
level != 0) {
(void) fprintf(stderr, "cancel (-c) incompatible with "
"any other options\n");
usage();
return (2);
}
if (argc != 0) {
(void) fprintf(stderr, "extraneous argument to '-c'\n");
usage();
return (2);
}
if (strcmp(cancel, "all") == 0) {
return (cancel_all_handlers());
} else {
int id = (int)strtol(cancel, &end, 10);
if (*end != '\0') {
(void) fprintf(stderr, "invalid handle id '%s':"
" must be an integer or 'all'\n", cancel);
usage();
return (1);
}
return (cancel_handler(id));
}
}
if (device != NULL) {
/*
* Device (-d) injection uses a completely different mechanism
* for doing injection, so handle it separately here.
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
level != 0) {
(void) fprintf(stderr, "device (-d) incompatible with "
"data error injection\n");
usage();
return (2);
}
if (argc != 1) {
(void) fprintf(stderr, "device (-d) injection requires "
"a single pool name\n");
usage();
return (2);
}
(void) strcpy(pool, argv[0]);
dataset[0] = '\0';
if (error == ECKSUM) {
(void) fprintf(stderr, "device error type must be "
"'io' or 'nxio'\n");
return (1);
}
if (translate_device(pool, device, label, &record) != 0)
return (1);
if (!error)
error = ENXIO;
} else if (raw != NULL) {
if (range != NULL || type != TYPE_INVAL || level != 0) {
(void) fprintf(stderr, "raw (-b) format with "
"any other options\n");
usage();
return (2);
}
if (argc != 1) {
(void) fprintf(stderr, "raw (-b) format expects a "
"single pool name\n");
usage();
return (2);
}
(void) strcpy(pool, argv[0]);
dataset[0] = '\0';
if (error == ENXIO) {
(void) fprintf(stderr, "data error type must be "
"'checksum' or 'io'\n");
return (1);
}
if (translate_raw(raw, &record) != 0)
return (1);
if (!error)
error = EIO;
} else if (type == TYPE_INVAL) {
if (flags == 0) {
(void) fprintf(stderr, "at least one of '-b', '-d', "
"'-t', '-a', or '-u' must be specified\n");
usage();
return (2);
}
if (argc == 1 && (flags & ZINJECT_UNLOAD_SPA)) {
(void) strcpy(pool, argv[0]);
dataset[0] = '\0';
} else if (argc != 0) {
(void) fprintf(stderr, "extraneous argument for "
"'-f'\n");
usage();
return (2);
}
flags |= ZINJECT_NULL;
} else {
if (argc != 1) {
(void) fprintf(stderr, "missing object\n");
usage();
return (2);
}
if (error == ENXIO) {
(void) fprintf(stderr, "data error type must be "
"'checksum' or 'io'\n");
return (1);
}
if (translate_record(type, argv[0], range, level, &record, pool,
dataset) != 0)
return (1);
if (!error)
error = EIO;
}
/*
* If this is pool-wide metadata, unmount everything. The ioctl() will
* unload the pool, so that we trigger spa-wide reopen of metadata next
* time we access the pool.
*/
if (dataset[0] != '\0' && domount) {
if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
return (1);
if (zfs_unmount(zhp, NULL, 0) != 0)
return (1);
}
record.zi_error = error;
ret = register_handler(pool, flags, &record, quiet);
if (dataset[0] != '\0' && domount)
ret = (zfs_mount(zhp, NULL, 0) != 0);
libzfs_fini(g_zfs);
return (ret);
}
@@ -1,71 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _ZINJECT_H
#define _ZINJECT_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/zfs_ioctl.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
TYPE_DATA, /* plain file contents */
TYPE_DNODE, /* metadnode contents */
TYPE_MOS, /* all MOS data */
TYPE_MOSDIR, /* MOS object directory */
TYPE_METASLAB, /* metaslab objects */
TYPE_CONFIG, /* MOS config */
TYPE_BPLIST, /* block pointer list */
TYPE_SPACEMAP, /* space map objects */
TYPE_ERRLOG, /* persistent error log */
TYPE_LABEL_UBERBLOCK, /* label specific uberblock */
TYPE_LABEL_NVLIST, /* label specific nvlist */
TYPE_INVAL
} err_type_t;
#define MOS_TYPE(t) \
((t) >= TYPE_MOS && (t) < TYPE_LABEL_UBERBLOCK)
#define LABEL_TYPE(t) \
((t) >= TYPE_LABEL_UBERBLOCK && (t) < TYPE_INVAL)
int translate_record(err_type_t type, const char *object, const char *range,
int level, zinject_record_t *record, char *poolname, char *dataset);
int translate_raw(const char *raw, zinject_record_t *record);
int translate_device(const char *pool, const char *device,
err_type_t label_type, zinject_record_t *record);
void usage(void);
extern libzfs_handle_t *g_zfs;
#ifdef __cplusplus
}
#endif
#endif /* _ZINJECT_H */
File diff suppressed because it is too large. Load diff
@@ -53,7 +53,6 @@ struct zpool_list {
boolean_t zl_findall;
uu_avl_t *zl_avl;
uu_avl_pool_t *zl_pool;
zprop_list_t **zl_proplist;
};
/* ARGSUSED */
@@ -82,12 +81,6 @@ add_pool(zpool_handle_t *zhp, void *data)
node->zn_handle = zhp;
uu_avl_node_init(node, &node->zn_avlnode, zlp->zl_pool);
if (uu_avl_find(zlp->zl_avl, node, NULL, &idx) == NULL) {
if (zlp->zl_proplist &&
zpool_expand_proplist(zhp, zlp->zl_proplist) != 0) {
zpool_close(zhp);
free(node);
return (-1);
}
uu_avl_insert(zlp->zl_avl, node, idx);
} else {
zpool_close(zhp);
@@ -105,7 +98,7 @@ add_pool(zpool_handle_t *zhp, void *data)
* line.
*/
zpool_list_t *
pool_list_get(int argc, char **argv, zprop_list_t **proplist, int *err)
pool_list_get(int argc, char **argv, zpool_proplist_t **proplist, int *err)
{
zpool_list_t *zlp;
@@ -121,8 +114,6 @@ pool_list_get(int argc, char **argv, zprop_list_t **proplist, int *err)
UU_DEFAULT)) == NULL)
zpool_no_memory();
zlp->zl_proplist = proplist;
if (argc == 0) {
(void) zpool_iter(g_zfs, add_pool, zlp);
zlp->zl_findall = B_TRUE;
@@ -132,12 +123,13 @@ pool_list_get(int argc, char **argv, zprop_list_t **proplist, int *err)
for (i = 0; i < argc; i++) {
zpool_handle_t *zhp;
if (zhp = zpool_open_canfail(g_zfs, argv[i])) {
if (add_pool(zhp, zlp) != 0)
if ((zhp = zpool_open_canfail(g_zfs,
argv[i])) != NULL && add_pool(zhp, zlp) == 0) {
if (proplist &&
zpool_expand_proplist(zhp, proplist) != 0)
*err = B_TRUE;
} else {
} else
*err = B_TRUE;
}
}
}
@@ -236,7 +228,7 @@ pool_list_count(zpool_list_t *zlp)
*/
int
for_each_pool(int argc, char **argv, boolean_t unavail,
zprop_list_t **proplist, zpool_iter_f func, void *data)
zpool_proplist_t **proplist, zpool_iter_f func, void *data)
{
zpool_list_t *list;
int ret = 0;
File diff suppressed because it is too large. Load diff
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -77,28 +77,3 @@ zpool_no_memory(void)
gettext("internal error: out of memory\n"));
exit(1);
}
/*
* Return the number of logs in supplied nvlist
*/
uint_t
num_logs(nvlist_t *nv)
{
uint_t nlogs = 0;
uint_t c, children;
nvlist_t **child;
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
&child, &children) != 0)
return (0);
for (c = 0; c < children; c++) {
uint64_t is_log = B_FALSE;
(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
&is_log);
if (is_log)
nlogs++;
}
return (nlogs);
}
@@ -19,13 +19,15 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef ZPOOL_UTIL_H
#define ZPOOL_UTIL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <libnvpair.h>
#include <libzfs.h>
@@ -39,24 +41,22 @@ extern "C" {
void *safe_malloc(size_t);
char *safe_strdup(const char *);
void zpool_no_memory(void);
uint_t num_logs(nvlist_t *nv);
/*
* Virtual device functions
*/
nvlist_t *make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
boolean_t isreplace, boolean_t dryrun, int argc, char **argv);
nvlist_t *make_root_vdev(nvlist_t *poolconfig, int force, int check_rep,
boolean_t isreplace, int argc, char **argv);
/*
* Pool list functions
*/
int for_each_pool(int, char **, boolean_t unavail, zprop_list_t **,
int for_each_pool(int, char **, boolean_t unavail, zpool_proplist_t **,
zpool_iter_f, void *);
typedef struct zpool_list zpool_list_t;
zpool_list_t *pool_list_get(int, char **, zprop_list_t **, int *);
zpool_list_t *pool_list_get(int, char **, zpool_proplist_t **, int *);
void pool_list_update(zpool_list_t *);
int pool_list_iter(zpool_list_t *, int unavail, zpool_iter_f, void *);
void pool_list_free(zpool_list_t *);
+81 -325
View File
@@ -20,10 +20,12 @@
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Functions to convert between a list of vdevs and an nvlist representing the
* configuration. Each entry in the list can be one of:
@@ -46,8 +48,8 @@
* Hot spares are a special case, and passed down as an array of disk vdevs, at
* the same level as the root of the vdev tree.
*
* The only function exported by this file is 'make_root_vdev'. The
* function performs several passes:
* The only function exported by this file is 'get_vdev_spec'. The function
* performs several passes:
*
* 1. Construct the vdev specification. Performs syntax validation and
* makes sure each device is valid.
@@ -57,7 +59,6 @@
* 3. Check for replication errors if the 'force' flag is not specified.
* validates that the replication level is consistent across the
* entire pool.
* 4. Call libzfs to label any whole disks with an EFI label.
*/
#include <assert.h>
@@ -75,6 +76,8 @@
#include <sys/mntent.h>
#include <libgeom.h>
#include <libzfs.h>
#include "zpool_util.h"
/*
@@ -108,105 +111,53 @@ vdev_error(const char *fmt, ...)
}
/*
* Check that a file is valid. All we can do in this case is check that it's
* not in use by another pool, and not in use by swap.
* Validate a GEOM provider.
*/
static int
check_file(const char *file, boolean_t force, boolean_t isspare)
{
char *name;
int fd;
int ret = 0;
int err;
pool_state_t state;
boolean_t inuse;
#if 0
if (dm_inuse_swap(file, &err)) {
if (err)
libdiskmgt_error(err);
else
vdev_error(gettext("%s is currently used by swap. "
"Please see swap(1M).\n"), file);
return (-1);
}
#endif
if ((fd = open(file, O_RDONLY)) < 0)
return (0);
if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) == 0 && inuse) {
const char *desc;
switch (state) {
case POOL_STATE_ACTIVE:
desc = gettext("active");
break;
case POOL_STATE_EXPORTED:
desc = gettext("exported");
break;
case POOL_STATE_POTENTIALLY_ACTIVE:
desc = gettext("potentially active");
break;
default:
desc = gettext("unknown");
break;
}
/*
* Allow hot spares to be shared between pools.
*/
if (state == POOL_STATE_SPARE && isspare)
return (0);
if (state == POOL_STATE_ACTIVE ||
state == POOL_STATE_SPARE || !force) {
switch (state) {
case POOL_STATE_SPARE:
vdev_error(gettext("%s is reserved as a hot "
"spare for pool %s\n"), file, name);
break;
default:
vdev_error(gettext("%s is part of %s pool "
"'%s'\n"), file, desc, name);
break;
}
ret = -1;
}
free(name);
}
(void) close(fd);
return (ret);
}
static int
check_provider(const char *name, boolean_t force, boolean_t isspare)
{
char path[MAXPATHLEN];
struct gmesh mesh;
struct gclass *mp;
struct ggeom *gp;
struct gprovider *pp;
int rv;
if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV) - 1) != 0)
snprintf(path, sizeof(path), "%s%s", _PATH_DEV, name);
else
strlcpy(path, name, sizeof(path));
/* XXX: What to do with isspare? */
return (check_file(path, force, isspare));
if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
name += sizeof(_PATH_DEV) - 1;
rv = geom_gettree(&mesh);
assert(rv == 0);
pp = NULL;
LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
if (strcmp(pp->lg_name, name) == 0)
goto out;
}
}
}
out:
rv = -1;
if (pp == NULL)
vdev_error("no such provider %s\n", name);
else {
int acr, acw, ace;
VERIFY(sscanf(pp->lg_mode, "r%dw%de%d", &acr, &acw, &ace) == 3);
if (acw == 0 && ace == 0)
rv = 0;
else
vdev_error("%s is in use (%s)\n", name, pp->lg_mode);
}
geom_deletetree(&mesh);
return (rv);
}
/*
* By "whole disk" we mean an entire physical disk (something we can
* label, toggle the write cache on, etc.) as opposed to the full
* capacity of a pseudo-device such as lofi or did. We act as if we
* are labeling the disk, which should be a pretty good test of whether
* it's a viable device or not. Returns B_TRUE if it is and B_FALSE if
* it isn't.
*/
static boolean_t
is_whole_disk(const char *name)
is_provider(const char *name)
{
int fd;
@@ -216,8 +167,8 @@ is_whole_disk(const char *name)
return (B_TRUE);
}
return (B_FALSE);
}
}
/*
* Create a leaf vdev. Determine if this is a GEOM provider.
* Valid forms for a leaf vdev are:
@@ -225,8 +176,8 @@ is_whole_disk(const char *name)
* /dev/xxx Complete path to a GEOM provider
* xxx Shorthand for /dev/xxx
*/
static nvlist_t *
make_leaf_vdev(const char *arg, uint64_t is_log)
nvlist_t *
make_leaf_vdev(const char *arg)
{
char ident[DISK_IDENT_SIZE], path[MAXPATHLEN];
struct stat64 statbuf;
@@ -234,72 +185,16 @@ make_leaf_vdev(const char *arg, uint64_t is_log)
char *type = NULL;
boolean_t wholedisk = B_FALSE;
/*
* Determine what type of vdev this is, and put the full path into
* 'path'. We detect whether this is a device of file afterwards by
* checking the st_mode of the file.
*/
if (arg[0] == '/') {
/*
* Complete device or file path. Exact type is determined by
* examining the file descriptor afterwards.
*/
wholedisk = is_whole_disk(arg);
if (!wholedisk && (stat64(arg, &statbuf) != 0)) {
(void) fprintf(stderr,
gettext("cannot open '%s': %s\n"),
arg, strerror(errno));
return (NULL);
}
if (strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
strlcpy(path, arg, sizeof (path));
else
snprintf(path, sizeof (path), "%s%s", _PATH_DEV, arg);
(void) strlcpy(path, arg, sizeof (path));
} else {
/*
* This may be a short path for a device, or it could be total
* gibberish. Check to see if it's a known device in
* /dev/dsk/. As part of this check, see if we've been given a
* an entire disk (minus the slice number).
*/
if (strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
strlcpy(path, arg, sizeof (path));
else
snprintf(path, sizeof (path), "%s%s", _PATH_DEV, arg);
wholedisk = is_whole_disk(path);
if (!wholedisk && (stat64(path, &statbuf) != 0)) {
/*
* If we got ENOENT, then the user gave us
* gibberish, so try to direct them with a
* reasonable error message. Otherwise,
* regurgitate strerror() since it's the best we
* can do.
*/
if (errno == ENOENT) {
(void) fprintf(stderr,
gettext("cannot open '%s': no such "
"GEOM provider\n"), arg);
(void) fprintf(stderr,
gettext("must be a full path or "
"shorthand device name\n"));
return (NULL);
} else {
(void) fprintf(stderr,
gettext("cannot open '%s': %s\n"),
path, strerror(errno));
return (NULL);
}
}
}
/*
* Determine whether this is a device or a file.
*/
if (wholedisk) {
if (is_provider(path))
type = VDEV_TYPE_DISK;
} else if (S_ISREG(statbuf.st_mode)) {
type = VDEV_TYPE_FILE;
} else {
else {
(void) fprintf(stderr, gettext("cannot use '%s': must be a "
"GEOM provider or regular file\n"), path);
"GEOM provider\n"), path);
return (NULL);
}
@@ -311,7 +206,6 @@ make_leaf_vdev(const char *arg, uint64_t is_log)
verify(nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) == 0);
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0);
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0);
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_LOG, is_log) == 0);
if (strcmp(type, VDEV_TYPE_DISK) == 0)
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
(uint64_t)B_FALSE) == 0);
@@ -373,14 +267,12 @@ typedef struct replication_level {
uint64_t zprl_parity;
} replication_level_t;
#define ZPOOL_FUZZ (16 * 1024 * 1024)
/*
* Given a list of toplevel vdevs, return the current replication level. If
* the config is inconsistent, then NULL is returned. If 'fatal' is set, then
* an error message will be displayed for each self-inconsistent vdev.
*/
static replication_level_t *
replication_level_t *
get_replication(nvlist_t *nvroot, boolean_t fatal)
{
nvlist_t **top;
@@ -399,20 +291,10 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
lastrep.zprl_type = NULL;
for (t = 0; t < toplevels; t++) {
uint64_t is_log = B_FALSE;
nv = top[t];
/*
* For separate logs we ignore the top level vdev replication
* constraints.
*/
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
if (is_log)
continue;
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE,
&type) == 0);
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
&child, &children) != 0) {
/*
@@ -446,7 +328,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
}
/*
* The 'dontreport' variable indicates that we've
* The 'dontreport' variable indicatest that we've
* already reported an error for this spec, so don't
* bother doing it again.
*/
@@ -467,7 +349,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
ZPOOL_CONFIG_TYPE, &childtype) == 0);
/*
* If this is a replacing or spare vdev, then
* If this is a a replacing or spare vdev, then
* get the real first child of the vdev.
*/
if (strcmp(childtype,
@@ -527,30 +409,22 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
*/
if ((fd = open(path, O_RDONLY)) >= 0) {
err = fstat64(fd, &statbuf);
if (err == 0 &&
S_ISCHR(statbuf.st_mode)) {
err = ioctl(fd, DIOCGMEDIASIZE,
&statbuf.st_size);
}
(void) close(fd);
} else {
err = stat64(path, &statbuf);
}
if (err != 0 || statbuf.st_size == 0)
continue;
size = statbuf.st_size;
/*
* Also make sure that devices and
* slices have a consistent size. If
* they differ by a significant amount
* (~16MB) then report an error.
* Also check the size of each device. If they
* differ, then report an error.
*/
if (!dontreport &&
(vdev_size != -1ULL &&
(labs(size - vdev_size) >
ZPOOL_FUZZ))) {
if (!dontreport && vdev_size != -1ULL &&
size != vdev_size) {
if (ret != NULL)
free(ret);
ret = NULL;
@@ -632,11 +506,9 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
* has a consistent replication level, then we ignore any errors. Otherwise,
* report any difference between the two.
*/
static int
int
check_replication(nvlist_t *config, nvlist_t *newroot)
{
nvlist_t **child;
uint_t children;
replication_level_t *current = NULL, *new;
int ret;
@@ -652,23 +524,6 @@ check_replication(nvlist_t *config, nvlist_t *newroot)
if ((current = get_replication(nvroot, B_FALSE)) == NULL)
return (0);
}
/*
* for spares there may be no children, and therefore no
* replication level to check
*/
if ((nvlist_lookup_nvlist_array(newroot, ZPOOL_CONFIG_CHILDREN,
&child, &children) != 0) || (children == 0)) {
free(current);
return (0);
}
/*
* If all we have is logs then there's no replication level to check.
*/
if (num_logs(newroot) == children) {
free(current);
return (0);
}
/*
* Get the replication level of the new vdev spec, reporting any
@@ -766,7 +621,7 @@ is_spare(nvlist_t *config, const char *path)
* Go through and find any devices that are in use. We rely on libdiskmgt for
* the majority of this task.
*/
static int
int
check_in_use(nvlist_t *config, nvlist_t *nv, int force, int isreplacing,
int isspare)
{
@@ -798,9 +653,6 @@ check_in_use(nvlist_t *config, nvlist_t *nv, int force, int isreplacing,
if (strcmp(type, VDEV_TYPE_DISK) == 0)
ret = check_provider(path, force, isspare);
if (strcmp(type, VDEV_TYPE_FILE) == 0)
ret = check_file(path, force, isspare);
return (ret);
}
@@ -816,17 +668,10 @@ check_in_use(nvlist_t *config, nvlist_t *nv, int force, int isreplacing,
isreplacing, B_TRUE)) != 0)
return (ret);
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
&child, &children) == 0)
for (c = 0; c < children; c++)
if ((ret = check_in_use(config, child[c], force,
isreplacing, B_FALSE)) != 0)
return (ret);
return (0);
}
static const char *
const char *
is_grouping(const char *type, int *mindev)
{
if (strcmp(type, "raidz") == 0 || strcmp(type, "raidz1") == 0) {
@@ -853,18 +698,6 @@ is_grouping(const char *type, int *mindev)
return (VDEV_TYPE_SPARE);
}
if (strcmp(type, "log") == 0) {
if (mindev != NULL)
*mindev = 1;
return (VDEV_TYPE_LOG);
}
if (strcmp(type, "cache") == 0) {
if (mindev != NULL)
*mindev = 1;
return (VDEV_TYPE_L2CACHE);
}
return (NULL);
}
@@ -877,21 +710,14 @@ is_grouping(const char *type, int *mindev)
nvlist_t *
construct_spec(int argc, char **argv)
{
nvlist_t *nvroot, *nv, **top, **spares, **l2cache;
int t, toplevels, mindev, nspares, nlogs, nl2cache;
nvlist_t *nvroot, *nv, **top, **spares;
int t, toplevels, mindev, nspares;
const char *type;
uint64_t is_log;
boolean_t seen_logs;
top = NULL;
toplevels = 0;
spares = NULL;
l2cache = NULL;
nspares = 0;
nlogs = 0;
nl2cache = 0;
is_log = B_FALSE;
seen_logs = B_FALSE;
while (argc > 0) {
nv = NULL;
@@ -904,56 +730,12 @@ construct_spec(int argc, char **argv)
nvlist_t **child = NULL;
int c, children = 0;
if (strcmp(type, VDEV_TYPE_SPARE) == 0) {
if (spares != NULL) {
(void) fprintf(stderr,
gettext("invalid vdev "
"specification: 'spare' can be "
"specified only once\n"));
return (NULL);
}
is_log = B_FALSE;
}
if (strcmp(type, VDEV_TYPE_LOG) == 0) {
if (seen_logs) {
(void) fprintf(stderr,
gettext("invalid vdev "
"specification: 'log' can be "
"specified only once\n"));
return (NULL);
}
seen_logs = B_TRUE;
is_log = B_TRUE;
argc--;
argv++;
/*
* A log is not a real grouping device.
* We just set is_log and continue.
*/
continue;
}
if (strcmp(type, VDEV_TYPE_L2CACHE) == 0) {
if (l2cache != NULL) {
(void) fprintf(stderr,
gettext("invalid vdev "
"specification: 'cache' can be "
"specified only once\n"));
return (NULL);
}
is_log = B_FALSE;
}
if (is_log) {
if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
(void) fprintf(stderr,
gettext("invalid vdev "
"specification: unsupported 'log' "
"device: %s\n"), type);
return (NULL);
}
nlogs++;
if (strcmp(type, VDEV_TYPE_SPARE) == 0 &&
spares != NULL) {
(void) fprintf(stderr, gettext("invalid vdev "
"specification: 'spare' can be "
"specified only once\n"));
return (NULL);
}
for (c = 1; c < argc; c++) {
@@ -964,8 +746,7 @@ construct_spec(int argc, char **argv)
children * sizeof (nvlist_t *));
if (child == NULL)
zpool_no_memory();
if ((nv = make_leaf_vdev(argv[c], B_FALSE))
== NULL)
if ((nv = make_leaf_vdev(argv[c])) == NULL)
return (NULL);
child[children - 1] = nv;
}
@@ -984,17 +765,11 @@ construct_spec(int argc, char **argv)
spares = child;
nspares = children;
continue;
} else if (strcmp(type, VDEV_TYPE_L2CACHE) == 0) {
l2cache = child;
nl2cache = children;
continue;
} else {
verify(nvlist_alloc(&nv, NV_UNIQUE_NAME,
0) == 0);
verify(nvlist_add_string(nv, ZPOOL_CONFIG_TYPE,
type) == 0);
verify(nvlist_add_uint64(nv,
ZPOOL_CONFIG_IS_LOG, is_log) == 0);
if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
verify(nvlist_add_uint64(nv,
ZPOOL_CONFIG_NPARITY,
@@ -1013,10 +788,8 @@ construct_spec(int argc, char **argv)
* We have a device. Pass off to make_leaf_vdev() to
* construct the appropriate nvlist describing the vdev.
*/
if ((nv = make_leaf_vdev(argv[0], is_log)) == NULL)
if ((nv = make_leaf_vdev(argv[0])) == NULL)
return (NULL);
if (is_log)
nlogs++;
argc--;
argv++;
}
@@ -1028,19 +801,13 @@ construct_spec(int argc, char **argv)
top[toplevels - 1] = nv;
}
if (toplevels == 0 && nspares == 0 && nl2cache == 0) {
if (toplevels == 0 && nspares == 0) {
(void) fprintf(stderr, gettext("invalid vdev "
"specification: at least one toplevel vdev must be "
"specified\n"));
return (NULL);
}
if (seen_logs && nlogs == 0) {
(void) fprintf(stderr, gettext("invalid vdev specification: "
"log requires at least 1 device\n"));
return (NULL);
}
/*
* Finally, create nvroot and add all top-level vdevs to it.
*/
@@ -1052,26 +819,18 @@ construct_spec(int argc, char **argv)
if (nspares != 0)
verify(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
spares, nspares) == 0);
if (nl2cache != 0)
verify(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
l2cache, nl2cache) == 0);
for (t = 0; t < toplevels; t++)
nvlist_free(top[t]);
for (t = 0; t < nspares; t++)
nvlist_free(spares[t]);
for (t = 0; t < nl2cache; t++)
nvlist_free(l2cache[t]);
if (spares)
free(spares);
if (l2cache)
free(l2cache);
free(top);
return (nvroot);
}
/*
* Get and validate the contents of the given vdev specification. This ensures
* that the nvlist returned is well-formed, that all the devices exist, and that
@@ -1083,11 +842,11 @@ construct_spec(int argc, char **argv)
* added, even if they appear in use.
*/
nvlist_t *
make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
boolean_t isreplacing, boolean_t dryrun, int argc, char **argv)
make_root_vdev(nvlist_t *poolconfig, int force, int check_rep,
boolean_t isreplacing, int argc, char **argv)
{
nvlist_t *newroot;
nvlist_t *poolconfig = NULL;
is_force = force;
/*
@@ -1098,9 +857,6 @@ make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
if ((newroot = construct_spec(argc, argv)) == NULL)
return (NULL);
if (zhp && ((poolconfig = zpool_get_config(zhp, NULL)) == NULL))
return (NULL);
/*
* Validate each device to make sure that its not shared with another
* subsystem. We do this even if 'force' is set, because there are some
File diff suppressed because it is too large. Load diff
+3 -2
View File
@@ -39,7 +39,7 @@ extern "C" {
#if defined(__STDC__)
#if __STDC_VERSION__ - 0 >= 199901L
extern void __assert(const char *, const char *, int);
extern void __assert_c99(const char *, const char *, int, const char *);
#else
extern void __assert(const char *, const char *, int);
#endif /* __STDC_VERSION__ - 0 >= 199901L */
@@ -70,7 +70,8 @@ extern void _assert();
#if defined(__STDC__)
#if __STDC_VERSION__ - 0 >= 199901L
#define assert(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
#define assert(EX) (void)((EX) || \
(__assert_c99(#EX, __FILE__, __LINE__, __func__), 0))
#else
#define assert(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
#endif /* __STDC_VERSION__ - 0 >= 199901L */
+5 -6
View File
@@ -2,8 +2,9 @@
* 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.
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,10 +20,11 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Libintl is a library of advanced internationalization functions. */
#ifndef _LIBINTL_H
#define _LIBINTL_H
@@ -61,9 +63,6 @@ typedef long wchar_t;
#define TEXTDOMAINMAX 256
#define __GNU_GETTEXT_SUPPORTED_REVISION(m) \
((((m) == 0) || ((m) == 1)) ? 1 : -1)
#ifdef __STDC__
extern char *dcgettext(const char *, const char *, const int);
extern char *dgettext(const char *, const char *);
+8 -10
View File
@@ -2,8 +2,9 @@
* 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.
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -18,9 +19,8 @@
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -81,12 +81,12 @@ typedef lwp_cond_t cond_t;
* Because we have to deal with C++, we cannot redefine this one as that one.
*/
typedef struct _rwlock {
int32_t readers; /* rwstate word */
int32_t readers; /* -1 == writer else # of readers */
uint16_t type;
uint16_t magic;
mutex_t mutex; /* used with process-shared rwlocks */
cond_t readercv; /* used only to indicate ownership */
cond_t writercv; /* used only to indicate ownership */
mutex_t mutex; /* used to indicate ownership */
cond_t readercv; /* unused */
cond_t writercv; /* unused */
} rwlock_t;
#ifdef __STDC__
@@ -111,7 +111,6 @@ int cond_signal(cond_t *);
int cond_broadcast(cond_t *);
int mutex_init(mutex_t *, int, void *);
int mutex_destroy(mutex_t *);
int mutex_consistent(mutex_t *);
int mutex_lock(mutex_t *);
int mutex_trylock(mutex_t *);
int mutex_unlock(mutex_t *);
@@ -153,7 +152,6 @@ int cond_signal();
int cond_broadcast();
int mutex_init();
int mutex_destroy();
int mutex_consistent();
int mutex_lock();
int mutex_trylock();
int mutex_unlock();
-2
View File
@@ -30,7 +30,6 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#include <pthread.h>
#include <pthread_np.h>
#include <assert.h>
/*
@@ -53,7 +52,6 @@ typedef pthread_rwlock_t rwlock_t;
#define mutex_lock(l) pthread_mutex_lock(l)
#define mutex_trylock(l) pthread_mutex_trylock(l)
#define mutex_unlock(l) pthread_mutex_unlock(l)
#define mutex_owned(l) pthread_mutex_isowned_np(l)
#define rwlock_init(l,f,a) pthread_rwlock_init(l,NULL)
#define rwlock_destroy(l) pthread_rwlock_destroy(l)
#define rw_rdlock(l) pthread_rwlock_rdlock(l)
@@ -2,8 +2,9 @@
* 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.
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,13 +20,12 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <inttypes.h>
#include <unistd.h>
#include <strings.h>
#include "libnvpair.h"
@@ -137,12 +137,6 @@ nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth)
(void) fprintf(fp, " 0x%llx", (u_longlong_t)val);
break;
}
case DATA_TYPE_DOUBLE: {
double val;
(void) nvpair_value_double(nvp, &val);
(void) fprintf(fp, " 0x%llf", val);
break;
}
case DATA_TYPE_STRING: {
char *val;
(void) nvpair_value_string(nvp, &val);
@@ -270,348 +264,3 @@ nvlist_print(FILE *fp, nvlist_t *nvl)
{
nvlist_print_with_indent(fp, nvl, 0);
}
/*
* Determine if string 'value' matches 'nvp' value. The 'value' string is
* converted, depending on the type of 'nvp', prior to match. For numeric
* types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
* is an array type, 'ai' is the index into the array against which we are
* checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
* in a regex_t compilation of value in 'value_regex' to trigger regular
* expression string match instead of simple strcmp().
*
* Return 1 on match, 0 on no-match, and -1 on error. If the error is
* related to value syntax error and 'ep' is non-NULL, *ep will point into
* the 'value' string at the location where the error exists.
*
* NOTE: It may be possible to move the non-regex_t version of this into
* common code used by library/kernel/boot.
*/
int
nvpair_value_match_regex(nvpair_t *nvp, int ai,
char *value, regex_t *value_regex, char **ep)
{
char *evalue;
uint_t a_len;
int sr;
if (ep)
*ep = NULL;
if ((nvp == NULL) || (value == NULL))
return (-1); /* error fail match - invalid args */
/* make sure array and index combination make sense */
if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
(!nvpair_type_is_array(nvp) && (ai >= 0)))
return (-1); /* error fail match - bad index */
/* non-string values should be single 'chunk' */
if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
(nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
value += strspn(value, " \t");
evalue = value + strcspn(value, " \t");
if (*evalue) {
if (ep)
*ep = evalue;
return (-1); /* error fail match - syntax */
}
}
sr = EOF;
switch (nvpair_type(nvp)) {
case DATA_TYPE_STRING: {
char *val;
/* check string value for match */
if (nvpair_value_string(nvp, &val) == 0) {
if (value_regex) {
if (regexec(value_regex, val,
(size_t)0, NULL, 0) == 0)
return (1); /* match */
} else {
if (strcmp(value, val) == 0)
return (1); /* match */
}
}
break;
}
case DATA_TYPE_STRING_ARRAY: {
char **val_array;
/* check indexed string value of array for match */
if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len)) {
if (value_regex) {
if (regexec(value_regex, val_array[ai],
(size_t)0, NULL, 0) == 0)
return (1);
} else {
if (strcmp(value, val_array[ai]) == 0)
return (1);
}
}
break;
}
case DATA_TYPE_BYTE: {
uchar_t val, val_arg;
/* scanf uchar_t from value and check for match */
sr = sscanf(value, "%c", &val_arg);
if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_BYTE_ARRAY: {
uchar_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%c", &val_arg);
if ((sr == 1) &&
(nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT8: {
int8_t val, val_arg;
/* scanf int8_t from value and check for match */
sr = sscanf(value, "%"SCNi8, &val_arg);
if ((sr == 1) &&
(nvpair_value_int8(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT8_ARRAY: {
int8_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi8, &val_arg);
if ((sr == 1) &&
(nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT8: {
uint8_t val, val_arg;
/* scanf uint8_t from value and check for match */
sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint8(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT8_ARRAY: {
uint8_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT16: {
int16_t val, val_arg;
/* scanf int16_t from value and check for match */
sr = sscanf(value, "%"SCNi16, &val_arg);
if ((sr == 1) &&
(nvpair_value_int16(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT16_ARRAY: {
int16_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi16, &val_arg);
if ((sr == 1) &&
(nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT16: {
uint16_t val, val_arg;
/* scanf uint16_t from value and check for match */
sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint16(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT16_ARRAY: {
uint16_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT32: {
int32_t val, val_arg;
/* scanf int32_t from value and check for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_int32(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT32_ARRAY: {
int32_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT32: {
uint32_t val, val_arg;
/* scanf uint32_t from value and check for match */
sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint32(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT32_ARRAY: {
uint32_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT64: {
int64_t val, val_arg;
/* scanf int64_t from value and check for match */
sr = sscanf(value, "%"SCNi64, &val_arg);
if ((sr == 1) &&
(nvpair_value_int64(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT64_ARRAY: {
int64_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi64, &val_arg);
if ((sr == 1) &&
(nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT64: {
uint64_t val_arg, val;
/* scanf uint64_t from value and check for match */
sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint64(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT64_ARRAY: {
uint64_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_BOOLEAN_VALUE: {
boolean_t val, val_arg;
/* scanf boolean_t from value and check for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_boolean_value(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_BOOLEAN_ARRAY: {
boolean_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_boolean_array(nvp,
&val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_HRTIME:
case DATA_TYPE_NVLIST:
case DATA_TYPE_NVLIST_ARRAY:
case DATA_TYPE_BOOLEAN:
case DATA_TYPE_DOUBLE:
case DATA_TYPE_UNKNOWN:
default:
/*
* unknown/unsupported data type
*/
return (-1); /* error fail match */
}
/*
* check to see if sscanf failed conversion, return approximate
* pointer to problem
*/
if (sr != 1) {
if (ep)
*ep = value;
return (-1); /* error fail match - syntax */
}
return (0); /* fail match */
}
int
nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
{
return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
}
@@ -2,8 +2,9 @@
* 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.
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,7 +20,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,15 +32,12 @@
#include <sys/nvpair.h>
#include <stdlib.h>
#include <stdio.h>
#include <regex.h>
#ifdef __cplusplus
extern "C" {
#endif
void nvlist_print(FILE *, nvlist_t *);
int nvpair_value_match(nvpair_t *, int, char *, char **);
int nvpair_value_match_regex(nvpair_t *, int, char *, regex_t *, char **);
#ifdef __cplusplus
}
@@ -2,8 +2,9 @@
* 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.
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,13 +20,15 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBUUTIL_H
#define _LIBUUTIL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <solaris.h>
#include <sys/types.h>
#include <stdarg.h>
@@ -146,7 +149,6 @@ extern int uu_open_tmp(const char *dir, uint_t uflags);
/*PRINTFLIKE1*/
extern char *uu_msprintf(const char *format, ...);
extern void *uu_zalloc(size_t);
extern char *uu_strdup(const char *);
extern void uu_free(void *);
/*
@@ -2,8 +2,9 @@
* 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.
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +21,7 @@
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,6 +30,16 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#include <solaris.h>
/*
* We don't bind to the internal libc interfaces if this is a
* native build.
*/
#ifndef NATIVE_BUILD
#include "c_synonyms.h"
#endif
#include <libuutil.h>
#include <libuutil_impl.h>
@@ -2,8 +2,9 @@
* 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.
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,10 +20,12 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "libuutil_common.h"
#include <stdarg.h>
@@ -51,22 +54,6 @@ uu_free(void *p)
free(p);
}
char *
uu_strdup(const char *str)
{
char *buf = NULL;
if (str != NULL) {
size_t sz;
sz = strlen(str) + 1;
buf = uu_zalloc(sz);
if (buf != NULL)
(void) memcpy(buf, str, sz);
}
return (buf);
}
char *
uu_msprintf(const char *format, ...)
{
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -120,8 +120,7 @@ uu_avl_pool_destroy(uu_avl_pool_t *pp)
UU_PTR_ENCODE(&pp->uap_null_avl)) {
uu_panic("uu_avl_pool_destroy: Pool \"%.*s\" (%p) has "
"outstanding avls, or is corrupt.\n",
(int)sizeof (pp->uap_name), pp->uap_name,
(void *)pp);
sizeof (pp->uap_name), pp->uap_name, pp);
}
}
(void) pthread_mutex_lock(&uu_apool_list_lock);
@@ -143,14 +142,14 @@ uu_avl_node_init(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp)
if (offset + sizeof (*np) > pp->uap_objsize) {
uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): "
"offset %ld doesn't fit in object (size %ld)\n",
base, (void *)np, (void *)pp, pp->uap_name,
(long)offset, (long)pp->uap_objsize);
base, np, pp, pp->uap_name, offset,
pp->uap_objsize);
}
if (offset != pp->uap_nodeoffset) {
uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): "
"offset %ld doesn't match pool's offset (%ld)\n",
base, (void *)np, (void *)pp, pp->uap_name,
(long)offset, (long)pp->uap_objsize);
base, np, pp, pp->uap_name, offset,
pp->uap_objsize);
}
}
@@ -167,12 +166,12 @@ uu_avl_node_fini(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp)
if (na[0] == DEAD_MARKER && na[1] == DEAD_MARKER) {
uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): "
"node already finied\n",
base, (void *)np, (void *)pp, pp->uap_name);
base, np, pp, pp->uap_name);
}
if (na[0] != POOL_TO_MARKER(pp) || na[1] != 0) {
uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): "
"node corrupt, in tree, or in different pool\n",
base, (void *)np, (void *)pp, pp->uap_name);
base, np, pp, pp->uap_name);
}
}
@@ -252,13 +251,12 @@ uu_avl_destroy(uu_avl_t *ap)
if (ap->ua_debug) {
if (avl_numnodes(&ap->ua_tree) != 0) {
uu_panic("uu_avl_destroy(%p): tree not empty\n",
(void *)ap);
uu_panic("uu_avl_destroy(%p): tree not empty\n", ap);
}
if (ap->ua_null_walk.uaw_next != &ap->ua_null_walk ||
ap->ua_null_walk.uaw_prev != &ap->ua_null_walk) {
uu_panic("uu_avl_destroy(%p): outstanding walkers\n",
(void *)ap);
ap);
}
}
(void) pthread_mutex_lock(&pp->uap_lock);
@@ -443,7 +441,7 @@ uu_avl_remove(uu_avl_t *ap, void *elem)
(void) _avl_walk_advance(wp, ap);
} else if (wp->uaw_next_result != NULL) {
uu_panic("uu_avl_remove(%p, %p): active non-robust "
"walker\n", (void *)ap, elem);
"walker\n", ap, elem);
}
}
@@ -499,19 +497,19 @@ uu_avl_insert(uu_avl_t *ap, void *elem, uu_avl_index_t idx)
if (na[1] != 0)
uu_panic("uu_avl_insert(%p, %p, %p): node already "
"in tree, or corrupt\n",
(void *)ap, elem, (void *)idx);
ap, elem, idx);
if (na[0] == 0)
uu_panic("uu_avl_insert(%p, %p, %p): node not "
"initialized\n",
(void *)ap, elem, (void *)idx);
ap, elem, idx);
if (na[0] != POOL_TO_MARKER(pp))
uu_panic("uu_avl_insert(%p, %p, %p): node from "
"other pool, or corrupt\n",
(void *)ap, elem, (void *)idx);
ap, elem, idx);
if (!INDEX_VALID(ap, idx))
uu_panic("uu_avl_insert(%p, %p, %p): %s\n",
(void *)ap, elem, (void *)idx,
ap, elem, idx,
INDEX_CHECK(idx)? "outdated index" :
"invalid index");
@@ -528,8 +526,8 @@ uu_avl_nearest_next(uu_avl_t *ap, uu_avl_index_t idx)
{
if (ap->ua_debug && !INDEX_VALID(ap, idx))
uu_panic("uu_avl_nearest_next(%p, %p): %s\n",
(void *)ap, (void *)idx, INDEX_CHECK(idx)?
"outdated index" : "invalid index");
ap, idx, INDEX_CHECK(idx)? "outdated index" :
"invalid index");
return (avl_nearest(&ap->ua_tree, INDEX_DECODE(idx), AVL_AFTER));
}
@@ -538,8 +536,8 @@ uu_avl_nearest_prev(uu_avl_t *ap, uu_avl_index_t idx)
{
if (ap->ua_debug && !INDEX_VALID(ap, idx))
uu_panic("uu_avl_nearest_prev(%p, %p): %s\n",
(void *)ap, (void *)idx, INDEX_CHECK(idx)?
"outdated index" : "invalid index");
ap, idx, INDEX_CHECK(idx)? "outdated index" :
"invalid index");
return (avl_nearest(&ap->ua_tree, INDEX_DECODE(idx), AVL_BEFORE));
}
@@ -33,7 +33,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#define FACILITY_FMT "%s (%s): "
@@ -2,8 +2,9 @@
* 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.
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,7 +20,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -116,8 +117,7 @@ uu_list_pool_destroy(uu_list_pool_t *pp)
UU_PTR_ENCODE(&pp->ulp_null_list)) {
uu_panic("uu_list_pool_destroy: Pool \"%.*s\" (%p) has "
"outstanding lists, or is corrupt.\n",
(int)sizeof (pp->ulp_name), pp->ulp_name,
(void *)pp);
sizeof (pp->ulp_name), pp->ulp_name, pp);
}
}
(void) pthread_mutex_lock(&uu_lpool_list_lock);
@@ -139,14 +139,14 @@ uu_list_node_init(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp)
if (offset + sizeof (*np) > pp->ulp_objsize) {
uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): "
"offset %ld doesn't fit in object (size %ld)\n",
base, (void *)np, (void *)pp, pp->ulp_name,
(long)offset, (long)pp->ulp_objsize);
base, np, pp, pp->ulp_name, offset,
pp->ulp_objsize);
}
if (offset != pp->ulp_nodeoffset) {
uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): "
"offset %ld doesn't match pool's offset (%ld)\n",
base, (void *)np, (void *)pp, pp->ulp_name,
(long)offset, (long)pp->ulp_objsize);
base, np, pp, pp->ulp_name, offset,
pp->ulp_objsize);
}
}
np->uln_next = POOL_TO_MARKER(pp);
@@ -163,13 +163,13 @@ uu_list_node_fini(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp)
np->uln_prev == NULL) {
uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): "
"node already finied\n",
base, (void *)np_arg, (void *)pp, pp->ulp_name);
base, np_arg, pp, pp->ulp_name);
}
if (np->uln_next != POOL_TO_MARKER(pp) ||
np->uln_prev != NULL) {
uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): "
"node corrupt or on list\n",
base, (void *)np_arg, (void *)pp, pp->ulp_name);
base, np_arg, pp, pp->ulp_name);
}
}
np->uln_next = NULL;
@@ -190,7 +190,7 @@ uu_list_create(uu_list_pool_t *pp, void *parent, uint32_t flags)
if (pp->ulp_debug)
uu_panic("uu_list_create(%p, ...): requested "
"UU_LIST_SORTED, but pool has no comparison func\n",
(void *)pp);
pp);
uu_set_error(UU_ERROR_NOT_SUPPORTED);
return (NULL);
}
@@ -236,16 +236,16 @@ uu_list_destroy(uu_list_t *lp)
if (lp->ul_null_node.uln_next != &lp->ul_null_node ||
lp->ul_null_node.uln_prev != &lp->ul_null_node) {
uu_panic("uu_list_destroy(%p): list not empty\n",
(void *)lp);
lp);
}
if (lp->ul_numnodes != 0) {
uu_panic("uu_list_destroy(%p): numnodes is nonzero, "
"but list is empty\n", (void *)lp);
"but list is empty\n", lp);
}
if (lp->ul_null_walk.ulw_next != &lp->ul_null_walk ||
lp->ul_null_walk.ulw_prev != &lp->ul_null_walk) {
uu_panic("uu_list_destroy(%p): outstanding walkers\n",
(void *)lp);
lp);
}
}
@@ -266,14 +266,13 @@ list_insert(uu_list_t *lp, uu_list_node_impl_t *np, uu_list_node_impl_t *prev,
if (lp->ul_debug) {
if (next->uln_prev != prev || prev->uln_next != next)
uu_panic("insert(%p): internal error: %p and %p not "
"neighbors\n", (void *)lp, (void *)next,
(void *)prev);
"neighbors\n", lp, next, prev);
if (np->uln_next != POOL_TO_MARKER(lp->ul_pool) ||
np->uln_prev != NULL) {
uu_panic("insert(%p): elem %p node %p corrupt, "
"not initialized, or already in a list.\n",
(void *)lp, NODE_TO_ELEM(lp, np), (void *)np);
lp, NODE_TO_ELEM(lp, np), np);
}
/*
* invalidate outstanding uu_list_index_ts.
@@ -300,12 +299,12 @@ uu_list_insert(uu_list_t *lp, void *elem, uu_list_index_t idx)
if (lp->ul_debug) {
if (!INDEX_VALID(lp, idx))
uu_panic("uu_list_insert(%p, %p, %p): %s\n",
(void *)lp, elem, (void *)idx,
lp, elem, idx,
INDEX_CHECK(idx)? "outdated index" :
"invalid index");
if (np->uln_prev == NULL)
uu_panic("uu_list_insert(%p, %p, %p): out-of-date "
"index\n", (void *)lp, elem, (void *)idx);
"index\n", lp, elem, idx);
}
list_insert(lp, ELEM_TO_NODE(lp, elem), np->uln_prev, np);
@@ -355,12 +354,11 @@ uu_list_nearest_next(uu_list_t *lp, uu_list_index_t idx)
if (lp->ul_debug) {
if (!INDEX_VALID(lp, idx))
uu_panic("uu_list_nearest_next(%p, %p): %s\n",
(void *)lp, (void *)idx,
INDEX_CHECK(idx)? "outdated index" :
lp, idx, INDEX_CHECK(idx)? "outdated index" :
"invalid index");
if (np->uln_prev == NULL)
uu_panic("uu_list_nearest_next(%p, %p): out-of-date "
"index\n", (void *)lp, (void *)idx);
"index\n", lp, idx);
}
if (np == &lp->ul_null_node)
@@ -380,11 +378,11 @@ uu_list_nearest_prev(uu_list_t *lp, uu_list_index_t idx)
if (lp->ul_debug) {
if (!INDEX_VALID(lp, idx))
uu_panic("uu_list_nearest_prev(%p, %p): %s\n",
(void *)lp, (void *)idx, INDEX_CHECK(idx)?
"outdated index" : "invalid index");
lp, idx, INDEX_CHECK(idx)? "outdated index" :
"invalid index");
if (np->uln_prev == NULL)
uu_panic("uu_list_nearest_prev(%p, %p): out-of-date "
"index\n", (void *)lp, (void *)idx);
"index\n", lp, idx);
}
if ((np = np->uln_prev) == &lp->ul_null_node)
@@ -411,11 +409,6 @@ list_walk_init(uu_list_walk_t *wp, uu_list_t *lp, uint32_t flags)
wp->ulw_next_result = lp->ul_null_node.uln_prev;
if (lp->ul_debug || robust) {
/*
* Add this walker to the list's list of walkers so
* uu_list_remove() can advance us if somebody tries to
* remove ulw_next_result.
*/
wp->ulw_next = next = &lp->ul_null_walk;
wp->ulw_prev = prev = next->ulw_prev;
next->ulw_prev = wp;
@@ -545,7 +538,7 @@ uu_list_remove(uu_list_t *lp, void *elem)
if (lp->ul_debug) {
if (np->uln_prev == NULL)
uu_panic("uu_list_remove(%p, %p): elem not on list\n",
(void *)lp, elem);
lp, elem);
/*
* invalidate outstanding uu_list_index_ts.
*/
@@ -563,7 +556,7 @@ uu_list_remove(uu_list_t *lp, void *elem)
(void) list_walk_advance(wp, lp);
} else if (wp->ulw_next_result != NULL) {
uu_panic("uu_list_remove(%p, %p): active non-robust "
"walker\n", (void *)lp, elem);
"walker\n", lp, elem);
}
}
@@ -585,8 +578,8 @@ uu_list_teardown(uu_list_t *lp, void **cookie)
* XXX: disable list modification until list is empty
*/
if (lp->ul_debug && *cookie != NULL)
uu_panic("uu_list_teardown(%p, %p): unexpected cookie\n",
(void *)lp, (void *)cookie);
uu_panic("uu_list_teardown(%p, %p): unexpected cookie\n", lp,
cookie);
ep = uu_list_first(lp);
if (ep)
@@ -606,12 +599,12 @@ uu_list_insert_before(uu_list_t *lp, void *target, void *elem)
if (np->uln_prev == NULL)
uu_panic("uu_list_insert_before(%p, %p, %p): %p is "
"not currently on a list\n",
(void *)lp, target, elem, target);
lp, target, elem, target);
}
if (lp->ul_sorted) {
if (lp->ul_debug)
uu_panic("uu_list_insert_before(%p, ...): list is "
"UU_LIST_SORTED\n", (void *)lp);
"UU_LIST_SORTED\n", lp);
uu_set_error(UU_ERROR_NOT_SUPPORTED);
return (-1);
}
@@ -632,12 +625,12 @@ uu_list_insert_after(uu_list_t *lp, void *target, void *elem)
if (np->uln_prev == NULL)
uu_panic("uu_list_insert_after(%p, %p, %p): %p is "
"not currently on a list\n",
(void *)lp, target, elem, target);
lp, target, elem, target);
}
if (lp->ul_sorted) {
if (lp->ul_debug)
uu_panic("uu_list_insert_after(%p, ...): list is "
"UU_LIST_SORTED\n", (void *)lp);
"UU_LIST_SORTED\n", lp);
uu_set_error(UU_ERROR_NOT_SUPPORTED);
return (-1);
}
@@ -20,20 +20,21 @@
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBZFS_H
#define _LIBZFS_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <assert.h>
#include <libnvpair.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/varargs.h>
#include <sys/fs/zfs.h>
#include <sys/avl.h>
#include <sys/zfs_ioctl.h>
#ifdef __cplusplus
@@ -46,7 +47,6 @@ extern "C" {
#define ZFS_MAXNAMELEN MAXNAMELEN
#define ZPOOL_MAXNAMELEN MAXNAMELEN
#define ZFS_MAXPROPLEN MAXPATHLEN
#define ZPOOL_MAXPROPLEN MAXPATHLEN
/*
* libzfs errors
@@ -99,61 +99,9 @@ enum {
EZFS_POOL_NOTSUP, /* ops not supported for this type of pool */
EZFS_POOL_INVALARG, /* invalid argument for this pool operation */
EZFS_NAMETOOLONG, /* dataset name is too long */
EZFS_OPENFAILED, /* open of device failed */
EZFS_NOCAP, /* couldn't get capacity */
EZFS_LABELFAILED, /* write of label failed */
EZFS_ISCSISVCUNAVAIL, /* iscsi service unavailable */
EZFS_BADWHO, /* invalid permission who */
EZFS_BADPERM, /* invalid permission */
EZFS_BADPERMSET, /* invalid permission set name */
EZFS_NODELEGATION, /* delegated administration is disabled */
EZFS_PERMRDONLY, /* pemissions are readonly */
EZFS_UNSHARESMBFAILED, /* failed to unshare over smb */
EZFS_SHARESMBFAILED, /* failed to share over smb */
EZFS_BADCACHE, /* bad cache file */
EZFS_ISL2CACHE, /* device is for the level 2 ARC */
EZFS_VDEVNOTSUP, /* unsupported vdev type */
EZFS_NOTSUP, /* ops not supported on this dataset */
EZFS_ACTIVE_SPARE, /* pool has active shared spare devices */
EZFS_UNKNOWN
};
/*
* The following data structures are all part
* of the zfs_allow_t data structure which is
* used for printing 'allow' permissions.
* It is a linked list of zfs_allow_t's which
* then contain avl tree's for user/group/sets/...
* and each one of the entries in those trees have
* avl tree's for the permissions they belong to and
* whether they are local,descendent or local+descendent
* permissions. The AVL trees are used primarily for
* sorting purposes, but also so that we can quickly find
* a given user and or permission.
*/
typedef struct zfs_perm_node {
avl_node_t z_node;
char z_pname[MAXPATHLEN];
} zfs_perm_node_t;
typedef struct zfs_allow_node {
avl_node_t z_node;
char z_key[MAXPATHLEN]; /* name, such as joe */
avl_tree_t z_localdescend; /* local+descendent perms */
avl_tree_t z_local; /* local permissions */
avl_tree_t z_descend; /* descendent permissions */
} zfs_allow_node_t;
typedef struct zfs_allow {
struct zfs_allow *z_next;
char z_setpoint[MAXPATHLEN];
avl_tree_t z_sets;
avl_tree_t z_crperms;
avl_tree_t z_user;
avl_tree_t z_group;
avl_tree_t z_everyone;
} zfs_allow_t;
/*
* Basic handle types
*/
@@ -183,9 +131,12 @@ extern zpool_handle_t *zpool_open(libzfs_handle_t *, const char *);
extern zpool_handle_t *zpool_open_canfail(libzfs_handle_t *, const char *);
extern void zpool_close(zpool_handle_t *);
extern const char *zpool_get_name(zpool_handle_t *);
extern uint64_t zpool_get_guid(zpool_handle_t *);
extern uint64_t zpool_get_space_used(zpool_handle_t *);
extern uint64_t zpool_get_space_total(zpool_handle_t *);
extern int zpool_get_root(zpool_handle_t *, char *, size_t);
extern int zpool_get_state(zpool_handle_t *);
extern char *zpool_state_to_name(vdev_state_t, vdev_aux_t);
extern void zpool_free_handles(libzfs_handle_t *);
extern uint64_t zpool_get_version(zpool_handle_t *);
/*
* Iterate over all active pools in the system.
@@ -197,7 +148,7 @@ extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
* Functions to create and destroy pools
*/
extern int zpool_create(libzfs_handle_t *, const char *, nvlist_t *,
nvlist_t *, nvlist_t *);
const char *);
extern int zpool_destroy(zpool_handle_t *);
extern int zpool_add(zpool_handle_t *, nvlist_t *);
@@ -205,33 +156,22 @@ extern int zpool_add(zpool_handle_t *, nvlist_t *);
* Functions to manipulate pool and vdev state
*/
extern int zpool_scrub(zpool_handle_t *, pool_scrub_type_t);
extern int zpool_clear(zpool_handle_t *, const char *);
extern int zpool_vdev_online(zpool_handle_t *, const char *, int,
vdev_state_t *);
extern int zpool_vdev_offline(zpool_handle_t *, const char *, boolean_t);
extern int zpool_vdev_attach(zpool_handle_t *, const char *,
const char *, nvlist_t *, int);
extern int zpool_vdev_online(zpool_handle_t *, const char *);
extern int zpool_vdev_offline(zpool_handle_t *, const char *, int);
extern int zpool_vdev_attach(zpool_handle_t *, const char *, const char *,
nvlist_t *, int);
extern int zpool_vdev_detach(zpool_handle_t *, const char *);
extern int zpool_vdev_remove(zpool_handle_t *, const char *);
extern int zpool_vdev_fault(zpool_handle_t *, uint64_t);
extern int zpool_vdev_degrade(zpool_handle_t *, uint64_t);
extern int zpool_vdev_clear(zpool_handle_t *, uint64_t);
extern nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *,
boolean_t *, boolean_t *);
extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, char *);
extern int zpool_clear(zpool_handle_t *, const char *);
extern nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *);
/*
* Functions to manage pool properties
*/
extern int zpool_set_prop(zpool_handle_t *, const char *, const char *);
extern int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *,
size_t proplen, zprop_source_t *);
extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t,
zprop_source_t *);
extern int zpool_get_prop(zpool_handle_t *, zfs_prop_t, char *,
size_t proplen, zfs_source_t *);
extern const char *zpool_prop_to_name(zpool_prop_t);
extern const char *zpool_prop_values(zpool_prop_t);
@@ -254,11 +194,6 @@ typedef enum {
ZPOOL_STATUS_FAILING_DEV, /* device experiencing errors */
ZPOOL_STATUS_VERSION_NEWER, /* newer on-disk version */
ZPOOL_STATUS_HOSTID_MISMATCH, /* last accessed by another system */
ZPOOL_STATUS_IO_FAILURE_WAIT, /* failed I/O, failmode 'wait' */
ZPOOL_STATUS_IO_FAILURE_CONTINUE, /* failed I/O, failmode 'continue' */
ZPOOL_STATUS_FAULTED_DEV_R, /* faulted device with replicas */
ZPOOL_STATUS_FAULTED_DEV_NR, /* faulted device with no replicas */
ZPOOL_STATUS_BAD_LOG, /* cannot read log chain(s) */
/*
* The following are not faults per se, but still an error possibly
@@ -288,39 +223,26 @@ extern int zpool_get_errlog(zpool_handle_t *, nvlist_t **);
/*
* Import and export functions
*/
extern int zpool_export(zpool_handle_t *, boolean_t);
extern int zpool_export(zpool_handle_t *);
extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *,
char *altroot);
extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *,
nvlist_t *, boolean_t);
const char *);
/*
* Search for pools to import
*/
extern nvlist_t *zpool_find_import(libzfs_handle_t *, int, char **);
extern nvlist_t *zpool_find_import_cached(libzfs_handle_t *, const char *,
char *, uint64_t);
extern nvlist_t *zpool_find_import_byname(libzfs_handle_t *, int, char **,
char *);
extern nvlist_t *zpool_find_import_byguid(libzfs_handle_t *, int, char **,
uint64_t);
extern nvlist_t *zpool_find_import_activeok(libzfs_handle_t *, int, char **);
/*
* Miscellaneous pool functions
*/
struct zfs_cmd;
extern char *zpool_vdev_name(libzfs_handle_t *, zpool_handle_t *, nvlist_t *);
extern int zpool_upgrade(zpool_handle_t *, uint64_t);
extern int zpool_upgrade(zpool_handle_t *);
extern int zpool_get_history(zpool_handle_t *, nvlist_t **);
extern void zpool_set_history_str(const char *subcommand, int argc,
char **argv, char *history_str);
extern int zpool_stage_history(libzfs_handle_t *, const char *);
extern void zpool_log_history(libzfs_handle_t *, int, char **, const char *,
boolean_t, boolean_t);
extern void zpool_obj_to_path(zpool_handle_t *, uint64_t, uint64_t, char *,
size_t len);
extern int zfs_ioctl(libzfs_handle_t *, unsigned long, struct zfs_cmd *);
extern int zpool_get_physpath(zpool_handle_t *, char *);
/*
* Basic handle manipulations. These functions do not create or destroy the
* underlying datasets, only the references to them.
@@ -329,84 +251,65 @@ extern zfs_handle_t *zfs_open(libzfs_handle_t *, const char *, int);
extern void zfs_close(zfs_handle_t *);
extern zfs_type_t zfs_get_type(const zfs_handle_t *);
extern const char *zfs_get_name(const zfs_handle_t *);
extern zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *);
/*
* Property management functions. Some functions are shared with the kernel,
* and are found in sys/fs/zfs.h.
*/
/*
* zfs dataset property management
*/
extern const char *zfs_prop_default_string(zfs_prop_t);
extern uint64_t zfs_prop_default_numeric(zfs_prop_t);
extern const char *zfs_prop_column_name(zfs_prop_t);
extern boolean_t zfs_prop_align_right(zfs_prop_t);
extern nvlist_t *zfs_valid_proplist(libzfs_handle_t *, zfs_type_t,
nvlist_t *, uint64_t, zfs_handle_t *, const char *);
extern const char *zfs_prop_to_name(zfs_prop_t);
extern int zfs_prop_set(zfs_handle_t *, const char *, const char *);
extern int zfs_prop_get(zfs_handle_t *, zfs_prop_t, char *, size_t,
zprop_source_t *, char *, size_t, boolean_t);
zfs_source_t *, char *, size_t, boolean_t);
extern int zfs_prop_get_numeric(zfs_handle_t *, zfs_prop_t, uint64_t *,
zprop_source_t *, char *, size_t);
zfs_source_t *, char *, size_t);
extern uint64_t zfs_prop_get_int(zfs_handle_t *, zfs_prop_t);
extern const char *zfs_prop_get_string(zfs_handle_t *, zfs_prop_t);
extern int zfs_prop_inherit(zfs_handle_t *, const char *);
extern const char *zfs_prop_values(zfs_prop_t);
extern int zfs_prop_valid_for_type(zfs_prop_t, int);
extern const char *zfs_prop_default_string(zfs_prop_t prop);
extern uint64_t zfs_prop_default_numeric(zfs_prop_t);
extern int zfs_prop_is_string(zfs_prop_t prop);
extern nvlist_t *zfs_get_user_props(zfs_handle_t *);
extern const char *zfs_prop_column_name(zfs_prop_t);
extern boolean_t zfs_prop_align_right(zfs_prop_t);
extern void nicebool(int value, char *buf, size_t buflen);
typedef struct zprop_list {
int pl_prop;
typedef struct zfs_proplist {
zfs_prop_t pl_prop;
char *pl_user_prop;
struct zprop_list *pl_next;
struct zfs_proplist *pl_next;
boolean_t pl_all;
size_t pl_width;
boolean_t pl_fixed;
} zprop_list_t;
} zfs_proplist_t;
extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **);
typedef zfs_proplist_t zpool_proplist_t;
extern int zfs_get_proplist(libzfs_handle_t *, char *, zfs_proplist_t **);
extern int zpool_get_proplist(libzfs_handle_t *, char *, zpool_proplist_t **);
extern int zfs_expand_proplist(zfs_handle_t *, zfs_proplist_t **);
extern int zpool_expand_proplist(zpool_handle_t *, zpool_proplist_t **);
extern void zfs_free_proplist(zfs_proplist_t *);
extern nvlist_t *zfs_get_user_props(zfs_handle_t *);
#define ZFS_MOUNTPOINT_NONE "none"
#define ZFS_MOUNTPOINT_LEGACY "legacy"
/*
* zpool property management
* Functions for printing properties from zfs/zpool
*/
extern int zpool_expand_proplist(zpool_handle_t *, zprop_list_t **);
extern const char *zpool_prop_default_string(zpool_prop_t);
extern uint64_t zpool_prop_default_numeric(zpool_prop_t);
extern const char *zpool_prop_column_name(zpool_prop_t);
extern boolean_t zpool_prop_align_right(zpool_prop_t);
/*
* Functions shared by zfs and zpool property management.
*/
extern int zprop_iter(zprop_func func, void *cb, boolean_t show_all,
boolean_t ordered, zfs_type_t type);
extern int zprop_get_list(libzfs_handle_t *, char *, zprop_list_t **,
zfs_type_t);
extern void zprop_free_list(zprop_list_t *);
/*
* Functions for printing zfs or zpool properties
*/
typedef struct zprop_get_cbdata {
typedef struct libzfs_get_cbdata {
int cb_sources;
int cb_columns[4];
int cb_colwidths[5];
boolean_t cb_scripted;
boolean_t cb_literal;
boolean_t cb_first;
zprop_list_t *cb_proplist;
zfs_type_t cb_type;
} zprop_get_cbdata_t;
zfs_proplist_t *cb_proplist;
} libzfs_get_cbdata_t;
void zprop_print_one_property(const char *, zprop_get_cbdata_t *,
const char *, const char *, zprop_source_t, const char *);
void libzfs_print_one_property(const char *, libzfs_get_cbdata_t *,
const char *, const char *, zfs_source_t, const char *);
#define GET_COL_NAME 1
#define GET_COL_PROPERTY 2
@@ -428,61 +331,26 @@ extern int zfs_iter_snapshots(zfs_handle_t *, zfs_iter_f, void *);
*/
extern int zfs_create(libzfs_handle_t *, const char *, zfs_type_t,
nvlist_t *);
extern int zfs_create_ancestors(libzfs_handle_t *, const char *);
extern int zfs_destroy(zfs_handle_t *);
extern int zfs_destroy_snaps(zfs_handle_t *, char *);
extern int zfs_clone(zfs_handle_t *, const char *, nvlist_t *);
extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *);
extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t);
extern int zfs_rename(zfs_handle_t *, const char *, boolean_t);
extern int zfs_send(zfs_handle_t *, const char *, const char *,
boolean_t, boolean_t, boolean_t, boolean_t, int);
extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t);
extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, int);
extern int zfs_rename(zfs_handle_t *, const char *, int);
extern int zfs_send(zfs_handle_t *, const char *, int);
extern int zfs_receive(libzfs_handle_t *, const char *, int, int, int,
boolean_t, int);
extern int zfs_promote(zfs_handle_t *);
typedef struct recvflags {
/* print informational messages (ie, -v was specified) */
int verbose : 1;
/* the destination is a prefix, not the exact fs (ie, -d) */
int isprefix : 1;
/* do not actually do the recv, just check if it would work (ie, -n) */
int dryrun : 1;
/* rollback/destroy filesystems as necessary (eg, -F) */
int force : 1;
/* set "canmount=off" on all modified filesystems */
int canmountoff : 1;
/* byteswap flag is used internally; callers need not specify */
int byteswap : 1;
} recvflags_t;
extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t,
int, avl_tree_t *);
/*
* Miscellaneous functions.
*/
extern const char *zfs_type_to_name(zfs_type_t);
extern void zfs_refresh_properties(zfs_handle_t *);
extern int zfs_name_valid(const char *, zfs_type_t);
extern int zfs_disable(zfs_handle_t *);
extern int zfs_enable(zfs_handle_t *);
extern zfs_handle_t *zfs_path_to_zhandle(libzfs_handle_t *, char *, zfs_type_t);
extern boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *,
zfs_type_t);
extern int zfs_spa_version(zfs_handle_t *, int *);
/*
* dataset permission functions.
*/
extern int zfs_perm_set(zfs_handle_t *, nvlist_t *);
extern int zfs_perm_remove(zfs_handle_t *, nvlist_t *);
extern int zfs_build_perms(zfs_handle_t *, char *, char *,
zfs_deleg_who_type_t, zfs_deleg_inherit_t, nvlist_t **nvlist_t);
extern int zfs_perm_get(zfs_handle_t *, zfs_allow_t **);
extern void zfs_free_allows(zfs_allow_t *);
extern void zfs_deleg_permissions(void);
/*
* Mount support functions.
@@ -501,27 +369,15 @@ extern int zfs_share(zfs_handle_t *);
extern int zfs_unshare(zfs_handle_t *);
/*
* Protocol-specific share support functions.
* Protocol-specifc share support functions.
*/
extern boolean_t zfs_is_shared_nfs(zfs_handle_t *, char **);
extern boolean_t zfs_is_shared_smb(zfs_handle_t *, char **);
extern int zfs_share_nfs(zfs_handle_t *);
extern int zfs_share_smb(zfs_handle_t *);
extern int zfs_shareall(zfs_handle_t *);
extern int zfs_unshare_nfs(zfs_handle_t *, const char *);
extern int zfs_unshare_smb(zfs_handle_t *, const char *);
extern int zfs_unshareall_nfs(zfs_handle_t *);
extern int zfs_unshareall_smb(zfs_handle_t *);
extern int zfs_unshareall_bypath(zfs_handle_t *, const char *);
extern int zfs_unshareall(zfs_handle_t *);
extern boolean_t zfs_is_shared_iscsi(zfs_handle_t *);
extern int zfs_share_iscsi(zfs_handle_t *);
extern int zfs_unshare_iscsi(zfs_handle_t *);
#ifdef TODO
extern int zfs_iscsi_perm_check(libzfs_handle_t *, char *, ucred_t *);
#endif
extern int zfs_deleg_share_nfs(libzfs_handle_t *, char *, char *,
void *, void *, int, zfs_share_op_t);
/*
* FreeBSD-specific jail support function.
@@ -545,6 +401,12 @@ extern int zfs_jail(zfs_handle_t *, int, int);
extern void zfs_nicenum(uint64_t, char *, size_t);
extern int zfs_nicestrtonum(libzfs_handle_t *, const char *, uint64_t *);
/*
* Pool destroy special. Remove the device information without destroying
* the underlying dataset.
*/
extern int zfs_remove_link(zfs_handle_t *);
/*
* Given a device or file, determine if it is part of a pool.
*/
@@ -562,9 +424,6 @@ extern int zpool_read_label(int, nvlist_t **);
extern int zpool_create_zvol_links(zpool_handle_t *);
extern int zpool_remove_zvol_links(zpool_handle_t *);
/* is this zvol valid for use as a dump device? */
extern int zvol_check_dump_config(char *);
/*
* Enable and disable datasets within a pool by mounting/unmounting and
* sharing/unsharing them.
@@ -20,12 +20,12 @@
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Portions Copyright 2007 Ramprakash Jelari
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <libintl.h>
#include <libuutil.h>
#include <stddef.h>
@@ -65,21 +65,18 @@ typedef struct prop_changenode {
int cn_shared;
int cn_mounted;
int cn_zoned;
boolean_t cn_needpost; /* is postfix() needed? */
uu_list_node_t cn_listnode;
} prop_changenode_t;
struct prop_changelist {
zfs_prop_t cl_prop;
zfs_prop_t cl_realprop;
zfs_prop_t cl_shareprop; /* used with sharenfs/sharesmb */
uu_list_pool_t *cl_pool;
uu_list_t *cl_list;
boolean_t cl_waslegacy;
boolean_t cl_allchildren;
boolean_t cl_alldependents;
int cl_mflags; /* Mount flags */
int cl_gflags; /* Gather request flags */
int cl_flags;
boolean_t cl_haszonedchild;
boolean_t cl_sorted;
};
@@ -87,8 +84,7 @@ struct prop_changelist {
/*
* If the property is 'mountpoint', go through and unmount filesystems as
* necessary. We don't do the same for 'sharenfs', because we can just re-share
* with different options without interrupting service. We do handle 'sharesmb'
* since there may be old resource names that need to be removed.
* with different options without interrupting service.
*/
int
changelist_prefix(prop_changelist_t *clp)
@@ -96,19 +92,11 @@ changelist_prefix(prop_changelist_t *clp)
prop_changenode_t *cn;
int ret = 0;
if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
clp->cl_prop != ZFS_PROP_SHARESMB)
if (clp->cl_prop != ZFS_PROP_MOUNTPOINT)
return (0);
for (cn = uu_list_first(clp->cl_list); cn != NULL;
cn = uu_list_next(clp->cl_list, cn)) {
/* if a previous loop failed, set the remaining to false */
if (ret == -1) {
cn->cn_needpost = B_FALSE;
continue;
}
/*
* If we are in the global zone, but this dataset is exported
* to a local zone, do nothing.
@@ -126,11 +114,8 @@ changelist_prefix(prop_changelist_t *clp)
(void) zfs_unshare_iscsi(cn->cn_handle);
if (zvol_remove_link(cn->cn_handle->zfs_hdl,
cn->cn_handle->zfs_name) != 0) {
cn->cn_handle->zfs_name) != 0)
ret = -1;
cn->cn_needpost = B_FALSE;
(void) zfs_share_iscsi(cn->cn_handle);
}
break;
case ZFS_PROP_VOLSIZE:
@@ -141,28 +126,10 @@ changelist_prefix(prop_changelist_t *clp)
(void) zfs_unshare_iscsi(cn->cn_handle);
break;
}
} else {
/*
* Do the property specific processing.
*/
switch (clp->cl_prop) {
case ZFS_PROP_MOUNTPOINT:
if (zfs_unmount(cn->cn_handle, NULL,
clp->cl_mflags) != 0) {
ret = -1;
cn->cn_needpost = B_FALSE;
}
break;
case ZFS_PROP_SHARESMB:
(void) zfs_unshare_smb(cn->cn_handle, NULL);
break;
}
}
} else if (zfs_unmount(cn->cn_handle, NULL, clp->cl_flags) != 0)
ret = -1;
}
if (ret == -1)
(void) changelist_postfix(clp);
return (ret);
}
@@ -180,8 +147,7 @@ changelist_postfix(prop_changelist_t *clp)
{
prop_changenode_t *cn;
char shareopts[ZFS_MAXPROPLEN];
int errors = 0;
libzfs_handle_t *hdl;
int ret = 0;
/*
* If we're changing the mountpoint, attempt to destroy the underlying
@@ -196,29 +162,12 @@ changelist_postfix(prop_changelist_t *clp)
if (clp->cl_prop == ZFS_PROP_MOUNTPOINT)
remove_mountpoint(cn->cn_handle);
/*
* It is possible that the changelist_prefix() used libshare
* to unshare some entries. Since libshare caches data, an
* attempt to reshare during postfix can fail unless libshare
* is uninitialized here so that it will reinitialize later.
*/
if (cn->cn_handle != NULL) {
hdl = cn->cn_handle->zfs_hdl;
assert(hdl != NULL);
zfs_uninit_libshare(hdl);
}
/*
* We walk the datasets in reverse, because we want to mount any parent
* datasets before mounting the children. We walk all datasets even if
* there are errors.
* datasets before mounting the children.
*/
for (cn = uu_list_last(clp->cl_list); cn != NULL;
cn = uu_list_prev(clp->cl_list, cn)) {
boolean_t sharenfs;
boolean_t sharesmb;
/*
* If we are in the global zone, but this dataset is exported
* to a local zone, do nothing.
@@ -226,11 +175,6 @@ changelist_postfix(prop_changelist_t *clp)
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
continue;
/* Only do post-processing if it's required */
if (!cn->cn_needpost)
continue;
cn->cn_needpost = B_FALSE;
zfs_refresh_properties(cn->cn_handle);
if (ZFS_IS_VOLUME(cn->cn_handle)) {
@@ -241,7 +185,7 @@ changelist_postfix(prop_changelist_t *clp)
if (clp->cl_realprop == ZFS_PROP_NAME &&
zvol_create_link(cn->cn_handle->zfs_hdl,
cn->cn_handle->zfs_name) != 0) {
errors++;
ret = -1;
} else if (cn->cn_shared ||
clp->cl_prop == ZFS_PROP_SHAREISCSI) {
if (zfs_prop_get(cn->cn_handle,
@@ -249,55 +193,43 @@ changelist_postfix(prop_changelist_t *clp)
sizeof (shareopts), NULL, NULL, 0,
B_FALSE) == 0 &&
strcmp(shareopts, "off") == 0) {
errors +=
zfs_unshare_iscsi(cn->cn_handle);
ret = zfs_unshare_iscsi(cn->cn_handle);
} else {
errors +=
zfs_share_iscsi(cn->cn_handle);
ret = zfs_share_iscsi(cn->cn_handle);
}
}
continue;
}
/*
* Remount if previously mounted or mountpoint was legacy,
* or sharenfs or sharesmb property is set.
*/
sharenfs = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARENFS,
shareopts, sizeof (shareopts), NULL, NULL, 0,
B_FALSE) == 0) && (strcmp(shareopts, "off") != 0));
sharesmb = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARESMB,
shareopts, sizeof (shareopts), NULL, NULL, 0,
B_FALSE) == 0) && (strcmp(shareopts, "off") != 0));
if ((cn->cn_mounted || clp->cl_waslegacy || sharenfs ||
sharesmb) && !zfs_is_mounted(cn->cn_handle, NULL) &&
if ((clp->cl_waslegacy || cn->cn_mounted) &&
!zfs_is_mounted(cn->cn_handle, NULL) &&
zfs_mount(cn->cn_handle, NULL, 0) != 0)
errors++;
ret = -1;
/*
* We always re-share even if the filesystem is currently
* shared, so that we can adopt any new options.
*/
if (sharenfs)
errors += zfs_share_nfs(cn->cn_handle);
else if (cn->cn_shared || clp->cl_waslegacy)
errors += zfs_unshare_nfs(cn->cn_handle, NULL);
if (sharesmb)
errors += zfs_share_smb(cn->cn_handle);
else if (cn->cn_shared || clp->cl_waslegacy)
errors += zfs_unshare_smb(cn->cn_handle, NULL);
if (cn->cn_shared ||
(clp->cl_prop == ZFS_PROP_SHARENFS && clp->cl_waslegacy)) {
if (zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARENFS,
shareopts, sizeof (shareopts), NULL, NULL, 0,
B_FALSE) == 0 && strcmp(shareopts, "off") == 0) {
ret = zfs_unshare_nfs(cn->cn_handle, NULL);
} else {
ret = zfs_share_nfs(cn->cn_handle);
}
}
}
return (errors ? -1 : 0);
return (ret);
}
/*
* Is this "dataset" a child of "parent"?
*/
boolean_t
static boolean_t
isa_child_of(const char *dataset, const char *parent)
{
int len;
@@ -348,22 +280,21 @@ changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
}
/*
* Given a gathered changelist for the 'sharenfs' or 'sharesmb' property,
* unshare all the datasets in the list.
* Given a gathered changelist for the 'sharenfs' property, unshare all the
* datasets in the list.
*/
int
changelist_unshare(prop_changelist_t *clp, zfs_share_proto_t *proto)
changelist_unshare(prop_changelist_t *clp)
{
prop_changenode_t *cn;
int ret = 0;
if (clp->cl_prop != ZFS_PROP_SHARENFS &&
clp->cl_prop != ZFS_PROP_SHARESMB)
if (clp->cl_prop != ZFS_PROP_SHARENFS)
return (0);
for (cn = uu_list_first(clp->cl_list); cn != NULL;
cn = uu_list_next(clp->cl_list, cn)) {
if (zfs_unshare_proto(cn->cn_handle, NULL, proto) != 0)
if (zfs_unshare_nfs(cn->cn_handle, NULL) != 0)
ret = -1;
}
@@ -385,14 +316,14 @@ changelist_haszonedchild(prop_changelist_t *clp)
* Remove a node from a gathered list.
*/
void
changelist_remove(prop_changelist_t *clp, const char *name)
changelist_remove(zfs_handle_t *zhp, prop_changelist_t *clp)
{
prop_changenode_t *cn;
for (cn = uu_list_first(clp->cl_list); cn != NULL;
cn = uu_list_next(clp->cl_list, cn)) {
if (strcmp(cn->cn_handle->zfs_name, name) == 0) {
if (strcmp(cn->cn_handle->zfs_name, zhp->zfs_name) == 0) {
uu_list_remove(clp->cl_list, cn);
zfs_close(cn->cn_handle);
free(cn);
@@ -432,8 +363,7 @@ change_one(zfs_handle_t *zhp, void *data)
char property[ZFS_MAXPROPLEN];
char where[64];
prop_changenode_t *cn;
zprop_source_t sourcetype;
zprop_source_t share_sourcetype;
zfs_source_t sourcetype;
/*
* We only want to unmount/unshare those filesystems that may inherit
@@ -453,25 +383,8 @@ change_one(zfs_handle_t *zhp, void *data)
return (0);
}
/*
* If we are "watching" sharenfs or sharesmb
* then check out the companion property which is tracked
* in cl_shareprop
*/
if (clp->cl_shareprop != ZPROP_INVAL &&
zfs_prop_get(zhp, clp->cl_shareprop, property,
sizeof (property), &share_sourcetype, where, sizeof (where),
B_FALSE) != 0) {
zfs_close(zhp);
return (0);
}
if (clp->cl_alldependents || clp->cl_allchildren ||
sourcetype == ZPROP_SRC_DEFAULT ||
sourcetype == ZPROP_SRC_INHERITED ||
(clp->cl_shareprop != ZPROP_INVAL &&
(share_sourcetype == ZPROP_SRC_DEFAULT ||
share_sourcetype == ZPROP_SRC_INHERITED))) {
sourcetype == ZFS_SRC_DEFAULT || sourcetype == ZFS_SRC_INHERITED) {
if ((cn = zfs_alloc(zfs_get_handle(zhp),
sizeof (prop_changenode_t))) == NULL) {
zfs_close(zhp);
@@ -479,11 +392,9 @@ change_one(zfs_handle_t *zhp, void *data)
}
cn->cn_handle = zhp;
cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) ||
zfs_is_mounted(zhp, NULL);
cn->cn_mounted = zfs_is_mounted(zhp, NULL);
cn->cn_shared = zfs_is_shared(zhp);
cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
cn->cn_needpost = B_TRUE;
/* Indicate if any child is exported to a local zone. */
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
@@ -556,8 +467,7 @@ compare_mountpoints(const void *a, const void *b, void *unused)
* mark whether it was shared beforehand.
*/
prop_changelist_t *
changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
int mnt_flags)
changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
{
prop_changelist_t *clp;
prop_changenode_t *cn;
@@ -574,8 +484,7 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
* order, regardless of their position in the hierarchy.
*/
if (prop == ZFS_PROP_NAME || prop == ZFS_PROP_ZONED ||
prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS ||
prop == ZFS_PROP_SHARESMB) {
prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS) {
compare = compare_mountpoints;
clp->cl_sorted = B_TRUE;
}
@@ -593,8 +502,7 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
clp->cl_list = uu_list_create(clp->cl_pool, NULL,
clp->cl_sorted ? UU_LIST_SORTED : 0);
clp->cl_gflags = gather_flags;
clp->cl_mflags = mnt_flags;
clp->cl_flags = flags;
if (clp->cl_list == NULL) {
assert(uu_error() == UU_ERROR_NO_MEMORY);
@@ -621,8 +529,6 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
clp->cl_prop = ZFS_PROP_MOUNTPOINT;
} else if (prop == ZFS_PROP_VOLSIZE) {
clp->cl_prop = ZFS_PROP_MOUNTPOINT;
} else if (prop == ZFS_PROP_VERSION) {
clp->cl_prop = ZFS_PROP_MOUNTPOINT;
} else {
clp->cl_prop = prop;
}
@@ -630,19 +536,9 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
clp->cl_prop != ZFS_PROP_SHARENFS &&
clp->cl_prop != ZFS_PROP_SHARESMB &&
clp->cl_prop != ZFS_PROP_SHAREISCSI)
return (clp);
/*
* If watching SHARENFS or SHARESMB then
* also watch its companion property.
*/
if (clp->cl_prop == ZFS_PROP_SHARENFS)
clp->cl_shareprop = ZFS_PROP_SHARESMB;
else if (clp->cl_prop == ZFS_PROP_SHARESMB)
clp->cl_shareprop = ZFS_PROP_SHARENFS;
if (clp->cl_alldependents) {
if (zfs_iter_dependents(zhp, B_TRUE, change_one, clp) != 0) {
changelist_free(clp);
@@ -658,7 +554,7 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
* and can't tell the difference.
*/
if ((temp = zfs_open(zhp->zfs_hdl, zfs_get_name(zhp),
ZFS_TYPE_DATASET)) == NULL) {
ZFS_TYPE_ANY)) == NULL) {
changelist_free(clp);
return (NULL);
}
@@ -675,11 +571,9 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
}
cn->cn_handle = temp;
cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) ||
zfs_is_mounted(temp, NULL);
cn->cn_mounted = zfs_is_mounted(temp, NULL);
cn->cn_shared = zfs_is_shared(temp);
cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
cn->cn_needpost = B_TRUE;
uu_list_node_init(cn, &cn->cn_listnode, clp->cl_pool);
if (clp->cl_sorted) {
@@ -692,22 +586,14 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
}
/*
* If the mountpoint property was previously 'legacy', or 'none',
* record it as the behavior of changelist_postfix() will be different.
* If the property was previously 'legacy' or 'none', record this fact,
* as the behavior of changelist_postfix() will be different.
*/
if ((clp->cl_prop == ZFS_PROP_MOUNTPOINT) &&
(zfs_prop_get(zhp, prop, property, sizeof (property),
if (zfs_prop_get(zhp, prop, property, sizeof (property),
NULL, NULL, 0, B_FALSE) == 0 &&
(strcmp(property, "legacy") == 0 ||
strcmp(property, "none") == 0))) {
/*
* do not automatically mount ex-legacy datasets if
* we specifically set canmount to noauto
*/
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) !=
ZFS_CANMOUNT_NOAUTO)
clp->cl_waslegacy = B_TRUE;
}
(strcmp(property, "legacy") == 0 || strcmp(property, "none") == 0 ||
strcmp(property, "off") == 0))
clp->cl_waslegacy = B_TRUE;
return (clp);
}
File diff suppressed because it is too large. Load diff
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -126,8 +126,6 @@ typedef struct zfs_graph {
zfs_vertex_t **zg_hash;
size_t zg_size;
size_t zg_nvertex;
const char *zg_root;
int zg_clone_count;
} zfs_graph_t;
/*
@@ -257,7 +255,7 @@ zfs_vertex_sort_edges(zfs_vertex_t *zvp)
* datasets in the pool.
*/
static zfs_graph_t *
zfs_graph_create(libzfs_handle_t *hdl, const char *dataset, size_t size)
zfs_graph_create(libzfs_handle_t *hdl, size_t size)
{
zfs_graph_t *zgp = zfs_alloc(hdl, sizeof (zfs_graph_t));
@@ -271,9 +269,6 @@ zfs_graph_create(libzfs_handle_t *hdl, const char *dataset, size_t size)
return (NULL);
}
zgp->zg_root = dataset;
zgp->zg_clone_count = 0;
return (zgp);
}
@@ -372,16 +367,17 @@ zfs_graph_add(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *source,
}
/*
* Iterate over all children of the given dataset, adding any vertices
* as necessary. Returns -1 if there was an error, or 0 otherwise.
* This is a simple recursive algorithm - the ZFS namespace typically
* is very flat. We manually invoke the necessary ioctl() calls to
* avoid the overhead and additional semantics of zfs_open().
* Iterate over all children of the given dataset, adding any vertices as
* necessary. Returns 0 if no cloned snapshots were seen, -1 if there was an
* error, or 1 otherwise. This is a simple recursive algorithm - the ZFS
* namespace typically is very flat. We manually invoke the necessary ioctl()
* calls to avoid the overhead and additional semantics of zfs_open().
*/
static int
iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
{
zfs_cmd_t zc = { 0 };
int ret = 0, err;
zfs_vertex_t *zvp;
/*
@@ -394,8 +390,18 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
return (0);
/*
* Iterate over all children
* We check the clone parent here instead of within the loop, so that if
* the root dataset has been promoted from a clone, we find its parent
* appropriately.
*/
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0 &&
zc.zc_objset_stats.dds_clone_of[0] != '\0') {
if (zfs_graph_add(hdl, zgp, zc.zc_objset_stats.dds_clone_of,
zc.zc_name, zc.zc_objset_stats.dds_creation_txg) != 0)
return (-1);
}
for ((void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
ioctl(hdl->libzfs_fd, ZFS_IOC_DATASET_LIST_NEXT, &zc) == 0;
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name))) {
@@ -411,23 +417,9 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
* dataset and clone statistics. If this fails, the dataset has
* since been removed, and we're pretty much screwed anyway.
*/
zc.zc_objset_stats.dds_origin[0] = '\0';
if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0)
continue;
if (zc.zc_objset_stats.dds_origin[0] != '\0') {
if (zfs_graph_add(hdl, zgp,
zc.zc_objset_stats.dds_origin, zc.zc_name,
zc.zc_objset_stats.dds_creation_txg) != 0)
return (-1);
/*
* Count origins only if they are contained in the graph
*/
if (isa_child_of(zc.zc_objset_stats.dds_origin,
zgp->zg_root))
zgp->zg_clone_count--;
}
/*
* Add an edge between the parent and the child.
*/
@@ -436,10 +428,19 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
return (-1);
/*
* Recursively visit child
* Iterate over all children
*/
if (iterate_children(hdl, zgp, zc.zc_name))
err = iterate_children(hdl, zgp, zc.zc_name);
if (err == -1)
return (-1);
else if (err == 1)
ret = 1;
/*
* Indicate if we found a dataset with a non-zero clone count.
*/
if (zc.zc_objset_stats.dds_num_clones != 0)
ret = 1;
}
/*
@@ -466,84 +467,67 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
zc.zc_objset_stats.dds_creation_txg) != 0)
return (-1);
zgp->zg_clone_count += zc.zc_objset_stats.dds_num_clones;
/*
* Indicate if we found a dataset with a non-zero clone count.
*/
if (zc.zc_objset_stats.dds_num_clones != 0)
ret = 1;
}
zvp->zv_visited = VISIT_SEEN;
return (0);
return (ret);
}
/*
* Returns false if there are no snapshots with dependent clones in this
* subtree or if all of those clones are also in this subtree. Returns
* true if there is an error or there are external dependents.
*/
static boolean_t
external_dependents(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
{
zfs_cmd_t zc = { 0 };
/*
* Check whether this dataset is a clone or has clones since
* iterate_children() only checks the children.
*/
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0)
return (B_TRUE);
if (zc.zc_objset_stats.dds_origin[0] != '\0') {
if (zfs_graph_add(hdl, zgp,
zc.zc_objset_stats.dds_origin, zc.zc_name,
zc.zc_objset_stats.dds_creation_txg) != 0)
return (B_TRUE);
if (isa_child_of(zc.zc_objset_stats.dds_origin, dataset))
zgp->zg_clone_count--;
}
if ((zc.zc_objset_stats.dds_num_clones) ||
iterate_children(hdl, zgp, dataset))
return (B_TRUE);
return (zgp->zg_clone_count != 0);
}
/*
* Construct a complete graph of all necessary vertices. First, iterate over
* only our object's children. If no cloned snapshots are found, or all of
* the cloned snapshots are in this subtree then return a graph of the subtree.
* Otherwise, start at the root of the pool and iterate over all datasets.
* Construct a complete graph of all necessary vertices. First, we iterate over
* only our object's children. If we don't find any cloned snapshots, then we
* simple return that. Otherwise, we have to start at the pool root and iterate
* over all datasets.
*/
static zfs_graph_t *
construct_graph(libzfs_handle_t *hdl, const char *dataset)
{
zfs_graph_t *zgp = zfs_graph_create(hdl, dataset, ZFS_GRAPH_SIZE);
zfs_graph_t *zgp = zfs_graph_create(hdl, ZFS_GRAPH_SIZE);
zfs_cmd_t zc = { 0 };
int ret = 0;
if (zgp == NULL)
return (zgp);
if ((strchr(dataset, '/') == NULL) ||
(external_dependents(hdl, zgp, dataset))) {
/*
* We need to explicitly check whether this dataset has clones or not,
* since iterate_children() only checks the children.
*/
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
(void) ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc);
if (zc.zc_objset_stats.dds_num_clones != 0 ||
(ret = iterate_children(hdl, zgp, dataset)) != 0) {
/*
* Determine pool name and try again.
*/
int len = strcspn(dataset, "/@") + 1;
char *pool = zfs_alloc(hdl, len);
char *pool, *slash;
if (pool == NULL) {
zfs_graph_destroy(zgp);
return (NULL);
}
(void) strlcpy(pool, dataset, len);
if ((slash = strchr(dataset, '/')) != NULL ||
(slash = strchr(dataset, '@')) != NULL) {
pool = zfs_alloc(hdl, slash - dataset + 1);
if (pool == NULL) {
zfs_graph_destroy(zgp);
return (NULL);
}
(void) strncpy(pool, dataset, slash - dataset);
pool[slash - dataset] = '\0';
if (iterate_children(hdl, zgp, pool) == -1 ||
zfs_graph_add(hdl, zgp, pool, NULL, 0) != 0) {
free(pool);
zfs_graph_destroy(zgp);
return (NULL);
}
if (iterate_children(hdl, zgp, pool) == -1 ||
zfs_graph_add(hdl, zgp, pool, NULL, 0) != 0) {
free(pool);
zfs_graph_destroy(zgp);
return (NULL);
}
free(pool);
}
if (ret == -1 || zfs_graph_add(hdl, zgp, dataset, NULL, 0) != 0) {
@@ -1,5 +1,5 @@
/*
* CDDL HEADER SART
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
@@ -20,21 +20,21 @@
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBFS_IMPL_H
#define _LIBFS_IMPL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/dmu.h>
#include <sys/fs/zfs.h>
#include <sys/zfs_ioctl.h>
#include <sys/zfs_acl.h>
#include <sys/spa.h>
#include <sys/nvpair.h>
#include <libshare.h>
#include <libuutil.h>
#include <libzfs.h>
@@ -42,33 +42,22 @@
extern "C" {
#endif
#ifdef VERIFY
#undef VERIFY
#endif
#define VERIFY verify
struct libzfs_handle {
int libzfs_error;
int libzfs_fd;
FILE *libzfs_mnttab;
FILE *libzfs_sharetab;
zpool_handle_t *libzfs_pool_handles;
uu_avl_pool_t *libzfs_ns_avlpool;
uu_avl_t *libzfs_ns_avl;
uint64_t libzfs_ns_gen;
int libzfs_desc_active;
char libzfs_action[1024];
char libzfs_desc[1024];
char *libzfs_log_str;
int libzfs_printerr;
void *libzfs_sharehdl; /* libshare handle */
uint_t libzfs_shareflags;
};
#define ZFSSHARE_MISS 0x01 /* Didn't find entry in cache */
struct zfs_handle {
libzfs_handle_t *zfs_hdl;
zpool_handle_t *zpool_hdl;
char zfs_name[ZFS_MAXNAMELEN];
zfs_type_t zfs_type; /* type including snapshot */
zfs_type_t zfs_head_type; /* type excluding snapshot */
@@ -77,6 +66,7 @@ struct zfs_handle {
nvlist_t *zfs_user_props;
boolean_t zfs_mntcheck;
char *zfs_mntopts;
char zfs_root[MAXPATHLEN];
};
/*
@@ -87,33 +77,14 @@ struct zfs_handle {
struct zpool_handle {
libzfs_handle_t *zpool_hdl;
zpool_handle_t *zpool_next;
char zpool_name[ZPOOL_MAXNAMELEN];
int zpool_state;
size_t zpool_config_size;
nvlist_t *zpool_config;
nvlist_t *zpool_old_config;
nvlist_t *zpool_props;
diskaddr_t zpool_start_block;
};
typedef enum {
PROTO_NFS = 0,
PROTO_SMB = 1,
PROTO_END = 2
} zfs_share_proto_t;
/*
* The following can be used as a bitmask and any new values
* added must preserve that capability.
*/
typedef enum {
SHARED_NOT_SHARED = 0x0,
SHARED_ISCSI = 0x1,
SHARED_NFS = 0x2,
SHARED_SMB = 0x4
} zfs_share_type_t;
int zfs_error(libzfs_handle_t *, int, const char *);
int zfs_error_fmt(libzfs_handle_t *, int, const char *, ...);
void zfs_error_aux(libzfs_handle_t *, const char *, ...);
@@ -130,24 +101,20 @@ int zpool_standard_error_fmt(libzfs_handle_t *, int, const char *, ...);
int get_dependents(libzfs_handle_t *, boolean_t, const char *, char ***,
size_t *);
int zfs_expand_proplist_common(libzfs_handle_t *, zfs_proplist_t **,
zfs_type_t);
int zfs_get_proplist_common(libzfs_handle_t *, char *, zfs_proplist_t **,
zfs_type_t);
zfs_prop_t zfs_prop_iter_common(zfs_prop_f, void *, zfs_type_t, boolean_t);
zfs_prop_t zfs_name_to_prop_common(const char *, zfs_type_t);
int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t,
nvlist_t *, char **, uint64_t *, const char *);
int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp,
zfs_type_t type);
/*
* Use this changelist_gather() flag to force attempting mounts
* on each change node regardless of whether or not it is currently
* mounted.
*/
#define CL_GATHER_MOUNT_ALWAYS 1
nvlist_t *zfs_validate_properties(libzfs_handle_t *, zfs_type_t, char *,
nvlist_t *, uint64_t, zfs_handle_t *zhp, const char *errbuf);
typedef struct prop_changelist prop_changelist_t;
int zcmd_alloc_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, size_t);
int zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
int zcmd_write_conf_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
int zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *, size_t *);
int zcmd_expand_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *);
int zcmd_read_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t **);
void zcmd_free_nvlists(zfs_cmd_t *);
@@ -155,15 +122,13 @@ void zcmd_free_nvlists(zfs_cmd_t *);
int changelist_prefix(prop_changelist_t *);
int changelist_postfix(prop_changelist_t *);
void changelist_rename(prop_changelist_t *, const char *, const char *);
void changelist_remove(prop_changelist_t *, const char *);
void changelist_remove(zfs_handle_t *, prop_changelist_t *);
void changelist_free(prop_changelist_t *);
prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int, int);
int changelist_unshare(prop_changelist_t *, zfs_share_proto_t *);
prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int);
int changelist_unshare(prop_changelist_t *);
int changelist_haszonedchild(prop_changelist_t *);
void remove_mountpoint(zfs_handle_t *);
int create_parents(libzfs_handle_t *, char *, int);
boolean_t isa_child_of(const char *dataset, const char *parent);
zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *);
@@ -172,23 +137,10 @@ int zpool_open_silent(libzfs_handle_t *, const char *, zpool_handle_t **);
int zvol_create_link(libzfs_handle_t *, const char *);
int zvol_remove_link(libzfs_handle_t *, const char *);
int zpool_iter_zvol(zpool_handle_t *, int (*)(const char *, void *), void *);
boolean_t zpool_name_valid(libzfs_handle_t *, boolean_t, const char *);
void namespace_clear(libzfs_handle_t *);
/*
* libshare (sharemgr) interfaces used internally.
*/
extern int zfs_init_libshare(libzfs_handle_t *, int);
extern void zfs_uninit_libshare(libzfs_handle_t *);
extern int zfs_parse_options(char *, zfs_share_proto_t);
extern int zfs_unshare_proto(zfs_handle_t *zhp,
const char *, zfs_share_proto_t *);
#ifdef __FreeBSD__
/*
* This is FreeBSD version of ioctl, because Solaris' ioctl() updates
* zc_nvlist_dst_size even if an error is returned, on FreeBSD if an
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -213,13 +213,11 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
name_entry_t *ne;
/*
* If this is a hot spare not currently in use or level 2 cache
* device, add it to the list of names to translate, but don't do
* anything else.
* If this is a hot spare not currently in use, add it to the list of
* names to translate, but don't do anything else.
*/
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
&state) == 0 &&
(state == POOL_STATE_SPARE || state == POOL_STATE_L2CACHE) &&
&state) == 0 && state == POOL_STATE_SPARE &&
nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, &vdev_guid) == 0) {
if ((ne = zfs_alloc(hdl, sizeof (name_entry_t))) == NULL)
return (-1);
@@ -363,46 +361,6 @@ pool_active(libzfs_handle_t *hdl, const char *name, uint64_t guid,
return (0);
}
static nvlist_t *
refresh_config(libzfs_handle_t *hdl, nvlist_t *config)
{
nvlist_t *nvl;
zfs_cmd_t zc = { 0 };
int err;
if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0)
return (NULL);
if (zcmd_alloc_dst_nvlist(hdl, &zc,
zc.zc_nvlist_conf_size * 2) != 0) {
zcmd_free_nvlists(&zc);
return (NULL);
}
while ((err = ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_TRYIMPORT,
&zc)) != 0 && errno == ENOMEM) {
if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
zcmd_free_nvlists(&zc);
return (NULL);
}
}
if (err) {
(void) zpool_standard_error(hdl, errno,
dgettext(TEXT_DOMAIN, "cannot discover pools"));
zcmd_free_nvlists(&zc);
return (NULL);
}
if (zcmd_read_dst_nvlist(hdl, &zc, &nvl) != 0) {
zcmd_free_nvlists(&zc);
return (NULL);
}
zcmd_free_nvlists(&zc);
return (nvl);
}
/*
* Convert our list of pools into the definitive set of configurations. We
* start by picking the best config for each toplevel vdev. Once that's done,
@@ -411,25 +369,26 @@ refresh_config(libzfs_handle_t *hdl, nvlist_t *config)
* return to the user.
*/
static nvlist_t *
get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
{
pool_entry_t *pe;
vdev_entry_t *ve;
config_entry_t *ce;
nvlist_t *ret = NULL, *config = NULL, *tmp, *nvtop, *nvroot;
nvlist_t **spares, **l2cache;
uint_t i, nspares, nl2cache;
nvlist_t **spares;
uint_t i, nspares;
boolean_t config_seen;
uint64_t best_txg;
char *name, *hostname;
zfs_cmd_t zc = { 0 };
uint64_t version, guid;
size_t len;
int err;
uint_t children = 0;
nvlist_t **child = NULL;
uint_t c;
boolean_t isactive;
uint64_t hostid;
nvlist_t *nvl;
boolean_t found_one = B_FALSE;
if (nvlist_alloc(&ret, 0, 0) != 0)
goto nomem;
@@ -611,13 +570,6 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
}
nvlist_free(nvroot);
/*
* zdb uses this path to report on active pools that were
* imported or created using -R.
*/
if (active_ok)
goto add_pool;
/*
* Determine if this pool is currently active, in which case we
* can't actually import it.
@@ -636,11 +588,41 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
continue;
}
if ((nvl = refresh_config(hdl, config)) == NULL)
/*
* Try to do the import in order to get vdev state.
*/
if (zcmd_write_src_nvlist(hdl, &zc, config, &len) != 0)
goto error;
nvlist_free(config);
config = nvl;
config = NULL;
if (zcmd_alloc_dst_nvlist(hdl, &zc, len * 2) != 0) {
zcmd_free_nvlists(&zc);
goto error;
}
while ((err = ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_TRYIMPORT,
&zc)) != 0 && errno == ENOMEM) {
if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
zcmd_free_nvlists(&zc);
goto error;
}
}
if (err) {
(void) zpool_standard_error(hdl, errno,
dgettext(TEXT_DOMAIN, "cannot discover pools"));
zcmd_free_nvlists(&zc);
goto error;
}
if (zcmd_read_dst_nvlist(hdl, &zc, &config) != 0) {
zcmd_free_nvlists(&zc);
goto error;
}
zcmd_free_nvlists(&zc);
/*
* Go through and update the paths for spares, now that we have
@@ -656,17 +638,6 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
}
}
/*
* Update the paths for l2cache devices.
*/
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
&l2cache, &nl2cache) == 0) {
for (i = 0; i < nl2cache; i++) {
if (fix_paths(l2cache[i], pl->names) != 0)
goto nomem;
}
}
/*
* Restore the original information read from the actual label.
*/
@@ -681,7 +652,6 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
hostname) == 0);
}
add_pool:
/*
* Add this pool to the list of configs.
*/
@@ -690,16 +660,10 @@ add_pool:
if (nvlist_add_nvlist(ret, name, config) != 0)
goto nomem;
found_one = B_TRUE;
nvlist_free(config);
config = NULL;
}
if (!found_one) {
nvlist_free(ret);
ret = NULL;
}
return (ret);
nomem:
@@ -718,9 +682,8 @@ error:
* Return the offset of the given label.
*/
static uint64_t
label_offset(uint64_t size, int l)
label_offset(size_t size, int l)
{
ASSERT(P2PHASE_TYPED(size, sizeof (vdev_label_t), uint64_t) == 0);
return (l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
0 : size - VDEV_LABELS * sizeof (vdev_label_t)));
}
@@ -735,20 +698,19 @@ zpool_read_label(int fd, nvlist_t **config)
struct stat64 statbuf;
int l;
vdev_label_t *label;
uint64_t state, txg, size;
uint64_t state, txg;
*config = NULL;
if (fstat64(fd, &statbuf) == -1)
return (0);
size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
if ((label = malloc(sizeof (vdev_label_t))) == NULL)
return (-1);
for (l = 0; l < VDEV_LABELS; l++) {
if (pread64(fd, label, sizeof (vdev_label_t),
label_offset(size, l)) != sizeof (vdev_label_t))
if (pread(fd, label, sizeof (vdev_label_t),
label_offset(statbuf.st_size, l)) != sizeof (vdev_label_t))
continue;
if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
@@ -756,12 +718,12 @@ zpool_read_label(int fd, nvlist_t **config)
continue;
if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE,
&state) != 0 || state > POOL_STATE_L2CACHE) {
&state) != 0 || state > POOL_STATE_SPARE) {
nvlist_free(*config);
continue;
}
if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
if (state != POOL_STATE_SPARE &&
(nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG,
&txg) != 0 || txg == 0)) {
nvlist_free(*config);
@@ -777,20 +739,31 @@ zpool_read_label(int fd, nvlist_t **config)
return (0);
}
static int
geom_find_import(libzfs_handle_t *hdl, pool_list_t *pools)
/*
* Given a list of directories to search, find all pools stored on disk. This
* includes partial pools which are not available to import. If no args are
* given (argc is 0), then the default directory (/dev) is searched.
*/
nvlist_t *
zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
{
int i;
char path[MAXPATHLEN];
nvlist_t *ret = NULL, *config;
int fd;
pool_list_t pools = { 0 };
pool_entry_t *pe, *penext;
vdev_entry_t *ve, *venext;
config_entry_t *ce, *cenext;
name_entry_t *ne, *nenext;
struct gmesh mesh;
struct gclass *mp;
struct ggeom *gp;
struct gprovider *pp;
nvlist_t *config;
int fd, ret = 0;
/*
* Go through and read the label configuration information from every
* GEOM provider, organizing the information according to pool GUID
* possible device, organizing the information according to pool GUID
* and toplevel GUID.
*/
@@ -800,183 +773,32 @@ geom_find_import(libzfs_handle_t *hdl, pool_list_t *pools)
LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
if ((fd = g_open(pp->lg_name, 0)) < 0)
continue;
(void) snprintf(path, sizeof (path), "%s%s",
_PATH_DEV, pp->lg_name);
if ((fd = open64(path, O_RDONLY)) < 0)
continue;
if ((zpool_read_label(fd, &config)) != 0) {
(void) g_close(fd);
(void) no_memory(hdl);
goto error;
}
(void) g_close(fd);
(void) close(fd);
if (config == NULL)
continue;
if (add_config(hdl, pools, path, config) != 0) {
ret = -1;
goto error;
}
}
}
}
error:
geom_deletetree(&mesh);
return (ret);
}
/*
* Given a list of directories to search, find all pools stored on disk. This
* includes partial pools which are not available to import. If no args are
* given (argc is 0), then the default directory (/dev/dsk) is searched.
* poolname or guid (but not both) are provided by the caller when trying
* to import a specific pool.
*/
static nvlist_t *
zpool_find_import_impl(libzfs_handle_t *hdl, int argc, char **argv,
boolean_t active_ok, char *poolname, uint64_t guid)
{
int i;
DIR *dirp = NULL;
struct dirent64 *dp;
char path[MAXPATHLEN];
char *end;
size_t pathleft;
struct stat64 statbuf;
nvlist_t *ret = NULL, *config;
static char *default_dir = "/dev/dsk";
int fd;
pool_list_t pools = { 0 };
pool_entry_t *pe, *penext;
vdev_entry_t *ve, *venext;
config_entry_t *ce, *cenext;
name_entry_t *ne, *nenext;
verify(poolname == NULL || guid == 0);
if (argc == 0) {
argc = 1;
argv = &default_dir;
}
/*
* Go through and read the label configuration information from every
* possible device, organizing the information according to pool GUID
* and toplevel GUID.
*/
for (i = 0; i < argc; i++) {
char *rdsk;
int dfd;
/* use realpath to normalize the path */
if (realpath(argv[i], path) == 0) {
(void) zfs_error_fmt(hdl, EZFS_BADPATH,
dgettext(TEXT_DOMAIN, "cannot open '%s'"),
argv[i]);
goto error;
}
end = &path[strlen(path)];
*end++ = '/';
*end = 0;
pathleft = &path[sizeof (path)] - end;
if (strcmp(argv[i], default_dir) == 0) {
geom_find_import(hdl, &pools);
continue;
}
/*
* Using raw devices instead of block devices when we're
* reading the labels skips a bunch of slow operations during
* close(2) processing, so we replace /dev/dsk with /dev/rdsk.
*/
if (strcmp(path, "/dev/dsk/") == 0)
rdsk = "/dev/rdsk/";
else
rdsk = path;
if ((dirp = opendir(rdsk)) == NULL) {
zfs_error_aux(hdl, strerror(errno));
(void) zfs_error_fmt(hdl, EZFS_BADPATH,
dgettext(TEXT_DOMAIN, "cannot open '%s'"),
rdsk);
goto error;
}
/*
* This is not MT-safe, but we have no MT consumers of libzfs
*/
while ((dp = readdir64(dirp)) != NULL) {
const char *name = dp->d_name;
if (name[0] == '.' &&
(name[1] == 0 || (name[1] == '.' && name[2] == 0)))
continue;
(void) snprintf(path, sizeof (path), "%s/%s", rdsk,
dp->d_name);
if ((fd = open64(path, O_RDONLY)) < 0)
continue;
/*
* Ignore failed stats. We only want regular
* files, character devs and block devs.
*/
if (fstat64(fd, &statbuf) != 0 ||
(!S_ISREG(statbuf.st_mode) &&
!S_ISCHR(statbuf.st_mode) &&
!S_ISBLK(statbuf.st_mode))) {
(void) close(fd);
continue;
}
if ((zpool_read_label(fd, &config)) != 0) {
(void) close(fd);
(void) no_memory(hdl);
goto error;
}
(void) close(fd);
if (config != NULL) {
boolean_t matched = B_TRUE;
if (poolname != NULL) {
char *pname;
matched = nvlist_lookup_string(config,
ZPOOL_CONFIG_POOL_NAME,
&pname) == 0 &&
strcmp(poolname, pname) == 0;
} else if (guid != 0) {
uint64_t this_guid;
matched = nvlist_lookup_uint64(config,
ZPOOL_CONFIG_POOL_GUID,
&this_guid) == 0 &&
guid == this_guid;
}
if (!matched) {
nvlist_free(config);
config = NULL;
continue;
}
/* use the non-raw path for the config */
(void) strlcpy(end, name, pathleft);
if (add_config(hdl, &pools, path, config) != 0)
goto error;
}
}
(void) closedir(dirp);
dirp = NULL;
}
ret = get_configs(hdl, &pools, active_ok);
geom_deletetree(&mesh);
ret = get_configs(hdl, &pools);
error:
for (pe = pools.pools; pe != NULL; pe = penext) {
@@ -1001,158 +823,9 @@ error:
free(ne);
}
if (dirp)
(void) closedir(dirp);
return (ret);
}
nvlist_t *
zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
{
return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, 0));
}
nvlist_t *
zpool_find_import_byname(libzfs_handle_t *hdl, int argc, char **argv,
char *pool)
{
return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, pool, 0));
}
nvlist_t *
zpool_find_import_byguid(libzfs_handle_t *hdl, int argc, char **argv,
uint64_t guid)
{
return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, guid));
}
nvlist_t *
zpool_find_import_activeok(libzfs_handle_t *hdl, int argc, char **argv)
{
return (zpool_find_import_impl(hdl, argc, argv, B_TRUE, NULL, 0));
}
/*
* Given a cache file, return the contents as a list of importable pools.
* poolname or guid (but not both) are provided by the caller when trying
* to import a specific pool.
*/
nvlist_t *
zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile,
char *poolname, uint64_t guid)
{
char *buf;
int fd;
struct stat64 statbuf;
nvlist_t *raw, *src, *dst;
nvlist_t *pools;
nvpair_t *elem;
char *name;
uint64_t this_guid;
boolean_t active;
verify(poolname == NULL || guid == 0);
if ((fd = open(cachefile, O_RDONLY)) < 0) {
zfs_error_aux(hdl, "%s", strerror(errno));
(void) zfs_error(hdl, EZFS_BADCACHE,
dgettext(TEXT_DOMAIN, "failed to open cache file"));
return (NULL);
}
if (fstat64(fd, &statbuf) != 0) {
zfs_error_aux(hdl, "%s", strerror(errno));
(void) close(fd);
(void) zfs_error(hdl, EZFS_BADCACHE,
dgettext(TEXT_DOMAIN, "failed to get size of cache file"));
return (NULL);
}
if ((buf = zfs_alloc(hdl, statbuf.st_size)) == NULL) {
(void) close(fd);
return (NULL);
}
if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
(void) close(fd);
free(buf);
(void) zfs_error(hdl, EZFS_BADCACHE,
dgettext(TEXT_DOMAIN,
"failed to read cache file contents"));
return (NULL);
}
(void) close(fd);
if (nvlist_unpack(buf, statbuf.st_size, &raw, 0) != 0) {
free(buf);
(void) zfs_error(hdl, EZFS_BADCACHE,
dgettext(TEXT_DOMAIN,
"invalid or corrupt cache file contents"));
return (NULL);
}
free(buf);
/*
* Go through and get the current state of the pools and refresh their
* state.
*/
if (nvlist_alloc(&pools, 0, 0) != 0) {
(void) no_memory(hdl);
nvlist_free(raw);
return (NULL);
}
elem = NULL;
while ((elem = nvlist_next_nvpair(raw, elem)) != NULL) {
verify(nvpair_value_nvlist(elem, &src) == 0);
verify(nvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME,
&name) == 0);
if (poolname != NULL && strcmp(poolname, name) != 0)
continue;
verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
&this_guid) == 0);
if (guid != 0) {
verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
&this_guid) == 0);
if (guid != this_guid)
continue;
}
if (pool_active(hdl, name, this_guid, &active) != 0) {
nvlist_free(raw);
nvlist_free(pools);
return (NULL);
}
if (active)
continue;
if ((dst = refresh_config(hdl, src)) == NULL) {
nvlist_free(raw);
nvlist_free(pools);
return (NULL);
}
if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) != 0) {
(void) no_memory(hdl);
nvlist_free(dst);
nvlist_free(raw);
nvlist_free(pools);
return (NULL);
}
nvlist_free(dst);
}
nvlist_free(raw);
return (pools);
}
boolean_t
find_guid(nvlist_t *nv, uint64_t guid)
{
@@ -1174,28 +847,27 @@ find_guid(nvlist_t *nv, uint64_t guid)
return (B_FALSE);
}
typedef struct aux_cbdata {
const char *cb_type;
typedef struct spare_cbdata {
uint64_t cb_guid;
zpool_handle_t *cb_zhp;
} aux_cbdata_t;
} spare_cbdata_t;
static int
find_aux(zpool_handle_t *zhp, void *data)
find_spare(zpool_handle_t *zhp, void *data)
{
aux_cbdata_t *cbp = data;
nvlist_t **list;
uint_t i, count;
spare_cbdata_t *cbp = data;
nvlist_t **spares;
uint_t i, nspares;
uint64_t guid;
nvlist_t *nvroot;
verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
&nvroot) == 0);
if (nvlist_lookup_nvlist_array(nvroot, cbp->cb_type,
&list, &count) == 0) {
for (i = 0; i < count; i++) {
verify(nvlist_lookup_uint64(list[i],
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
&spares, &nspares) == 0) {
for (i = 0; i < nspares; i++) {
verify(nvlist_lookup_uint64(spares[i],
ZPOOL_CONFIG_GUID, &guid) == 0);
if (guid == cbp->cb_guid) {
cbp->cb_zhp = zhp;
@@ -1224,7 +896,7 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
zpool_handle_t *zhp;
nvlist_t *pool_config;
uint64_t stateval, isspare;
aux_cbdata_t cb = { 0 };
spare_cbdata_t cb = { 0 };
boolean_t isactive;
*inuse = B_FALSE;
@@ -1242,7 +914,7 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID,
&vdev_guid) == 0);
if (stateval != POOL_STATE_SPARE && stateval != POOL_STATE_L2CACHE) {
if (stateval != POOL_STATE_SPARE) {
verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
&name) == 0);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
@@ -1321,24 +993,7 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
*/
cb.cb_zhp = NULL;
cb.cb_guid = vdev_guid;
cb.cb_type = ZPOOL_CONFIG_SPARES;
if (zpool_iter(hdl, find_aux, &cb) == 1) {
name = (char *)zpool_get_name(cb.cb_zhp);
ret = TRUE;
} else {
ret = FALSE;
}
break;
case POOL_STATE_L2CACHE:
/*
* Check if any pool is currently using this l2cache device.
*/
cb.cb_zhp = NULL;
cb.cb_guid = vdev_guid;
cb.cb_type = ZPOOL_CONFIG_L2CACHE;
if (zpool_iter(hdl, find_aux, &cb) == 1) {
if (zpool_iter(hdl, find_spare, &cb) == 1) {
name = (char *)zpool_get_name(cb.cb_zhp);
ret = TRUE;
} else {
@@ -1353,8 +1008,6 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
if (ret) {
if ((*namestr = zfs_strdup(hdl, name)) == NULL) {
if (cb.cb_zhp)
zpool_close(cb.cb_zhp);
nvlist_free(config);
return (-1);
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -19,16 +19,18 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This file contains the functions which analyze the status of a pool. This
* include both the status of an active pool, as well as the status exported
* pools. Returns one of the ZPOOL_STATUS_* defines describing the status of
* the pool. This status is independent (to a certain degree) from the state of
* the pool. A pool's state describes only whether or not it is capable of
* the pool. A pool's state descsribes only whether or not it is capable of
* providing the necessary fault tolerance for data. The status describes the
* overall status of devices. A pool that is online can still have a device
* that is experiencing errors.
@@ -45,7 +47,7 @@
#include "libzfs_impl.h"
/*
* Message ID table. This must be kept in sync with the ZPOOL_STATUS_* defines
* Message ID table. This must be kep in sync with the ZPOOL_STATUS_* defines
* in libzfs.h. Note that there are some status results which go past the end
* of this table, and hence have no associated message ID.
*/
@@ -60,10 +62,26 @@ static char *zfs_msgid_table[] = {
"ZFS-8000-8A",
"ZFS-8000-9P",
"ZFS-8000-A5",
"ZFS-8000-EY",
"ZFS-8000-HC",
"ZFS-8000-JQ",
"ZFS-8000-K4",
"ZFS-8000-EY"
};
/*
* If the pool is active, a certain class of static errors is overridden by the
* faults as analayzed by FMA. These faults have separate knowledge articles,
* and the article referred to by 'zpool status' must match that indicated by
* the syslog error message. We override missing data as well as corrupt pool.
*/
static char *zfs_msgid_table_active[] = {
"ZFS-8000-14",
"ZFS-8000-D3", /* overridden */
"ZFS-8000-D3", /* overridden */
"ZFS-8000-4J",
"ZFS-8000-5E",
"ZFS-8000-6X",
"ZFS-8000-CS", /* overridden */
"ZFS-8000-8A",
"ZFS-8000-9P",
"ZFS-8000-CS", /* overridden */
};
#define NMSGID (sizeof (zfs_msgid_table) / sizeof (zfs_msgid_table[0]))
@@ -76,18 +94,11 @@ vdev_missing(uint64_t state, uint64_t aux, uint64_t errs)
aux == VDEV_AUX_OPEN_FAILED);
}
/* ARGSUSED */
static int
vdev_faulted(uint64_t state, uint64_t aux, uint64_t errs)
{
return (state == VDEV_STATE_FAULTED);
}
/* ARGSUSED */
static int
vdev_errors(uint64_t state, uint64_t aux, uint64_t errs)
{
return (state == VDEV_STATE_DEGRADED || errs != 0);
return (errs != 0);
}
/* ARGSUSED */
@@ -152,9 +163,9 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(uint64_t, uint64_t, uint64_t))
* following:
*
* - Check for a complete and valid configuration
* - Look for any faulted or missing devices in a non-replicated config
* - Look for any missing devices in a non-replicated config
* - Check for any data errors
* - Check for any faulted or missing devices in a replicated config
* - Check for any missing devices in a replicated config
* - Look for any devices showing errors
* - Check for any resilvering devices
*
@@ -170,7 +181,6 @@ check_status(nvlist_t *config, boolean_t isimport)
uint64_t nerr;
uint64_t version;
uint64_t stateval;
uint64_t suspended;
uint64_t hostid = 0;
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
@@ -205,30 +215,8 @@ check_status(nvlist_t *config, boolean_t isimport)
return (ZPOOL_STATUS_BAD_GUID_SUM);
/*
* Check whether the pool has suspended due to failed I/O.
* Missing devices in non-replicated config.
*/
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_SUSPENDED,
&suspended) == 0) {
if (suspended == ZIO_FAILURE_MODE_CONTINUE)
return (ZPOOL_STATUS_IO_FAILURE_CONTINUE);
return (ZPOOL_STATUS_IO_FAILURE_WAIT);
}
/*
* Could not read a log.
*/
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
vs->vs_aux == VDEV_AUX_BAD_LOG) {
return (ZPOOL_STATUS_BAD_LOG);
}
/*
* Bad devices in non-replicated config.
*/
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
find_vdev_problem(nvroot, vdev_faulted))
return (ZPOOL_STATUS_FAULTED_DEV_NR);
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
find_vdev_problem(nvroot, vdev_missing))
return (ZPOOL_STATUS_MISSING_DEV_NR);
@@ -256,8 +244,6 @@ check_status(nvlist_t *config, boolean_t isimport)
/*
* Missing devices in a replicated config.
*/
if (find_vdev_problem(nvroot, vdev_faulted))
return (ZPOOL_STATUS_FAULTED_DEV_R);
if (find_vdev_problem(nvroot, vdev_missing))
return (ZPOOL_STATUS_MISSING_DEV_R);
if (find_vdev_problem(nvroot, vdev_broken))
@@ -284,7 +270,7 @@ check_status(nvlist_t *config, boolean_t isimport)
/*
* Outdated, but usable, version
*/
if (version < SPA_VERSION)
if (version < ZFS_VERSION)
return (ZPOOL_STATUS_VERSION_OLDER);
return (ZPOOL_STATUS_OK);
@@ -298,7 +284,7 @@ zpool_get_status(zpool_handle_t *zhp, char **msgid)
if (ret >= NMSGID)
*msgid = NULL;
else
*msgid = zfs_msgid_table[ret];
*msgid = zfs_msgid_table_active[ret];
return (ret);
}
@@ -19,10 +19,12 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Internal utility routines for the ZFS library.
*/
@@ -35,8 +37,6 @@
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <ctype.h>
#include <math.h>
#include <sys/mnttab.h>
#include <sys/mntent.h>
#include <sys/types.h>
@@ -44,7 +44,6 @@
#include <libzfs.h>
#include "libzfs_impl.h"
#include "zfs_prop.h"
int
libzfs_errno(libzfs_handle_t *hdl)
@@ -134,14 +133,6 @@ libzfs_error_description(libzfs_handle_t *hdl)
return (dgettext(TEXT_DOMAIN, "unshare(1M) failed"));
case EZFS_SHARENFSFAILED:
return (dgettext(TEXT_DOMAIN, "share(1M) failed"));
case EZFS_UNSHARESMBFAILED:
return (dgettext(TEXT_DOMAIN, "smb remove share failed"));
case EZFS_SHARESMBFAILED:
return (dgettext(TEXT_DOMAIN, "smb add share failed"));
case EZFS_ISCSISVCUNAVAIL:
return (dgettext(TEXT_DOMAIN,
"iscsitgt service need to be enabled by "
"a privileged user"));
case EZFS_DEVLINKS:
return (dgettext(TEXT_DOMAIN, "failed to create /dev links"));
case EZFS_PERM:
@@ -178,38 +169,6 @@ libzfs_error_description(libzfs_handle_t *hdl)
"this pool operation"));
case EZFS_NAMETOOLONG:
return (dgettext(TEXT_DOMAIN, "dataset name is too long"));
case EZFS_OPENFAILED:
return (dgettext(TEXT_DOMAIN, "open failed"));
case EZFS_NOCAP:
return (dgettext(TEXT_DOMAIN,
"disk capacity information could not be retrieved"));
case EZFS_LABELFAILED:
return (dgettext(TEXT_DOMAIN, "write of label failed"));
case EZFS_BADWHO:
return (dgettext(TEXT_DOMAIN, "invalid user/group"));
case EZFS_BADPERM:
return (dgettext(TEXT_DOMAIN, "invalid permission"));
case EZFS_BADPERMSET:
return (dgettext(TEXT_DOMAIN, "invalid permission set name"));
case EZFS_NODELEGATION:
return (dgettext(TEXT_DOMAIN, "delegated administration is "
"disabled on pool"));
case EZFS_PERMRDONLY:
return (dgettext(TEXT_DOMAIN, "snapshot permissions cannot be"
" modified"));
case EZFS_BADCACHE:
return (dgettext(TEXT_DOMAIN, "invalid or missing cache file"));
case EZFS_ISL2CACHE:
return (dgettext(TEXT_DOMAIN, "device is in use as a cache"));
case EZFS_VDEVNOTSUP:
return (dgettext(TEXT_DOMAIN, "vdev specification is not "
"supported"));
case EZFS_NOTSUP:
return (dgettext(TEXT_DOMAIN, "operation not supported "
"on this dataset"));
case EZFS_ACTIVE_SPARE:
return (dgettext(TEXT_DOMAIN, "pool has active shared spare "
"device"));
case EZFS_UNKNOWN:
return (dgettext(TEXT_DOMAIN, "unknown error"));
default:
@@ -290,10 +249,6 @@ zfs_common_error(libzfs_handle_t *hdl, int error, const char *fmt,
zfs_verror(hdl, EZFS_PERM, fmt, ap);
return (-1);
case ECANCELED:
zfs_verror(hdl, EZFS_NODELEGATION, fmt, ap);
return (-1);
case EIO:
zfs_verror(hdl, EZFS_IO, fmt, ap);
return (-1);
@@ -325,9 +280,9 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
return (-1);
}
switch (error) {
case ENXIO:
case ENODEV:
zfs_verror(hdl, EZFS_IO, fmt, ap);
break;
@@ -353,17 +308,11 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
"dataset is busy"));
zfs_verror(hdl, EZFS_BUSY, fmt, ap);
break;
case EROFS:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"snapshot permissions cannot be modified"));
zfs_verror(hdl, EZFS_PERMRDONLY, fmt, ap);
break;
case ENAMETOOLONG:
zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap);
break;
case ENOTSUP:
zfs_verror(hdl, EZFS_BADVERSION, fmt, ap);
break;
default:
zfs_error_aux(hdl, strerror(errno));
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
@@ -412,7 +361,7 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
case EBUSY:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy"));
zfs_verror(hdl, EZFS_BUSY, fmt, ap);
zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
break;
case ENXIO:
@@ -433,11 +382,6 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
zfs_verror(hdl, EZFS_POOL_INVALARG, fmt, ap);
break;
case ENOSPC:
case EDQUOT:
zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
return (-1);
default:
zfs_error_aux(hdl, strerror(error));
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
@@ -539,8 +483,9 @@ zfs_nicenum(uint64_t num, char *buf, size_t buflen)
*/
int i;
for (i = 2; i >= 0; i--) {
if (snprintf(buf, buflen, "%.*f%c", i,
(double)num / (1ULL << 10 * index), u) <= 5)
(void) snprintf(buf, buflen, "%.*f%c", i,
(double)num / (1ULL << 10 * index), u);
if (strlen(buf) <= 5)
break;
}
}
@@ -593,9 +538,6 @@ libzfs_init(void)
hdl->libzfs_sharetab = fopen(ZFS_EXPORTS_PATH, "r");
zfs_prop_init();
zpool_prop_init();
return (hdl);
}
@@ -607,10 +549,6 @@ libzfs_fini(libzfs_handle_t *hdl)
(void) fclose(hdl->libzfs_mnttab);
if (hdl->libzfs_sharetab)
(void) fclose(hdl->libzfs_sharetab);
zfs_uninit_libshare(hdl);
if (hdl->libzfs_log_str)
(void) free(hdl->libzfs_log_str);
zpool_free_handles(hdl);
namespace_clear(hdl);
free(hdl);
}
@@ -627,12 +565,6 @@ zfs_get_handle(zfs_handle_t *zhp)
return (zhp->zfs_hdl);
}
zpool_handle_t *
zfs_get_pool_handle(const zfs_handle_t *zhp)
{
return (zhp->zpool_hdl);
}
/*
* Given a name, determine whether or not it's a valid path
* (starts with '/' or "./"). If so, walk the mnttab trying
@@ -705,14 +637,13 @@ zcmd_expand_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc)
void
zcmd_free_nvlists(zfs_cmd_t *zc)
{
free((void *)(uintptr_t)zc->zc_nvlist_conf);
free((void *)(uintptr_t)zc->zc_nvlist_src);
free((void *)(uintptr_t)zc->zc_nvlist_dst);
}
static int
zcmd_write_nvlist_com(libzfs_handle_t *hdl, uint64_t *outnv, uint64_t *outlen,
nvlist_t *nvl)
int
zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl,
size_t *size)
{
char *packed;
size_t len;
@@ -724,26 +655,14 @@ zcmd_write_nvlist_com(libzfs_handle_t *hdl, uint64_t *outnv, uint64_t *outlen,
verify(nvlist_pack(nvl, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
*outnv = (uint64_t)(uintptr_t)packed;
*outlen = len;
zc->zc_nvlist_src = (uint64_t)(uintptr_t)packed;
zc->zc_nvlist_src_size = len;
if (size)
*size = len;
return (0);
}
int
zcmd_write_conf_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
{
return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_conf,
&zc->zc_nvlist_conf_size, nvl));
}
int
zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
{
return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_src,
&zc->zc_nvlist_src_size, nvl));
}
/*
* Unpacks an nvlist from the ZFS ioctl command structure.
*/
@@ -757,32 +676,10 @@ zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp)
return (0);
}
int
zfs_ioctl(libzfs_handle_t *hdl, unsigned long request, zfs_cmd_t *zc)
{
int error;
zc->zc_history = (uint64_t)(uintptr_t)hdl->libzfs_log_str;
error = ioctl(hdl->libzfs_fd, request, zc);
if (hdl->libzfs_log_str) {
free(hdl->libzfs_log_str);
hdl->libzfs_log_str = NULL;
}
zc->zc_history = 0;
return (error);
}
/*
* ================================================================
* API shared by zfs and zpool property management
* ================================================================
*/
static void
zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
zfs_print_prop_headers(libzfs_get_cbdata_t *cbp)
{
zprop_list_t *pl = cbp->cb_proplist;
zfs_proplist_t *pl = cbp->cb_proplist;
int i;
char *title;
size_t len;
@@ -814,12 +711,8 @@ zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
/*
* 'PROPERTY' column
*/
if (pl->pl_prop != ZPROP_INVAL) {
const char *propname = (type == ZFS_TYPE_POOL) ?
zpool_prop_to_name(pl->pl_prop) :
zfs_prop_to_name(pl->pl_prop);
len = strlen(propname);
if (pl->pl_prop != ZFS_PROP_INVAL) {
len = strlen(zfs_prop_to_name(pl->pl_prop));
if (len > cbp->cb_colwidths[GET_COL_PROPERTY])
cbp->cb_colwidths[GET_COL_PROPERTY] = len;
} else {
@@ -838,8 +731,7 @@ zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
/*
* 'NAME' and 'SOURCE' columns
*/
if (pl->pl_prop == (type == ZFS_TYPE_POOL ? ZPOOL_PROP_NAME :
ZFS_PROP_NAME) &&
if (pl->pl_prop == ZFS_PROP_NAME &&
pl->pl_width > cbp->cb_colwidths[GET_COL_NAME]) {
cbp->cb_colwidths[GET_COL_NAME] = pl->pl_width;
cbp->cb_colwidths[GET_COL_SOURCE] = pl->pl_width +
@@ -885,8 +777,8 @@ zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
* structure.
*/
void
zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp,
const char *propname, const char *value, zprop_source_t sourcetype,
libzfs_print_one_property(const char *name, libzfs_get_cbdata_t *cbp,
const char *propname, const char *value, zfs_source_t sourcetype,
const char *source)
{
int i;
@@ -900,7 +792,7 @@ zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp,
return;
if (cbp->cb_first)
zprop_print_headers(cbp, cbp->cb_type);
zfs_print_prop_headers(cbp);
for (i = 0; i < 4; i++) {
switch (cbp->cb_columns[i]) {
@@ -918,23 +810,23 @@ zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp,
case GET_COL_SOURCE:
switch (sourcetype) {
case ZPROP_SRC_NONE:
case ZFS_SRC_NONE:
str = "-";
break;
case ZPROP_SRC_DEFAULT:
case ZFS_SRC_DEFAULT:
str = "default";
break;
case ZPROP_SRC_LOCAL:
case ZFS_SRC_LOCAL:
str = "local";
break;
case ZPROP_SRC_TEMPORARY:
case ZFS_SRC_TEMPORARY:
str = "temporary";
break;
case ZPROP_SRC_INHERITED:
case ZFS_SRC_INHERITED:
(void) snprintf(buf, sizeof (buf),
"inherited from %s", source);
str = buf;
@@ -959,451 +851,3 @@ zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp,
(void) printf("\n");
}
/*
* Given a numeric suffix, convert the value into a number of bits that the
* resulting value must be shifted.
*/
static int
str2shift(libzfs_handle_t *hdl, const char *buf)
{
const char *ends = "BKMGTPEZ";
int i;
if (buf[0] == '\0')
return (0);
for (i = 0; i < strlen(ends); i++) {
if (toupper(buf[0]) == ends[i])
break;
}
if (i == strlen(ends)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid numeric suffix '%s'"), buf);
return (-1);
}
/*
* We want to allow trailing 'b' characters for 'GB' or 'Mb'. But don't
* allow 'BB' - that's just weird.
*/
if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' &&
toupper(buf[0]) != 'B'))
return (10*i);
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid numeric suffix '%s'"), buf);
return (-1);
}
/*
* Convert a string of the form '100G' into a real number. Used when setting
* properties or creating a volume. 'buf' is used to place an extended error
* message for the caller to use.
*/
int
zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
{
char *end;
int shift;
*num = 0;
/* Check to see if this looks like a number. */
if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
if (hdl)
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"bad numeric value '%s'"), value);
return (-1);
}
/* Rely on stroll() to process the numeric portion. */
errno = 0;
*num = strtoll(value, &end, 10);
/*
* Check for ERANGE, which indicates that the value is too large to fit
* in a 64-bit value.
*/
if (errno == ERANGE) {
if (hdl)
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"numeric value is too large"));
return (-1);
}
/*
* If we have a decimal value, then do the computation with floating
* point arithmetic. Otherwise, use standard arithmetic.
*/
if (*end == '.') {
double fval = strtod(value, &end);
if ((shift = str2shift(hdl, end)) == -1)
return (-1);
fval *= pow(2, shift);
if (fval > UINT64_MAX) {
if (hdl)
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"numeric value is too large"));
return (-1);
}
*num = (uint64_t)fval;
} else {
if ((shift = str2shift(hdl, end)) == -1)
return (-1);
/* Check for overflow */
if (shift >= 64 || (*num << shift) >> shift != *num) {
if (hdl)
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"numeric value is too large"));
return (-1);
}
*num <<= shift;
}
return (0);
}
/*
* Given a propname=value nvpair to set, parse any numeric properties
* (index, boolean, etc) if they are specified as strings and add the
* resulting nvpair to the returned nvlist.
*
* At the DSL layer, all properties are either 64-bit numbers or strings.
* We want the user to be able to ignore this fact and specify properties
* as native values (numbers, for example) or as strings (to simplify
* command line utilities). This also handles converting index types
* (compression, checksum, etc) from strings to their on-disk index.
*/
int
zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
zfs_type_t type, nvlist_t *ret, char **svalp, uint64_t *ivalp,
const char *errbuf)
{
data_type_t datatype = nvpair_type(elem);
zprop_type_t proptype;
const char *propname;
char *value;
boolean_t isnone = B_FALSE;
if (type == ZFS_TYPE_POOL) {
proptype = zpool_prop_get_type(prop);
propname = zpool_prop_to_name(prop);
} else {
proptype = zfs_prop_get_type(prop);
propname = zfs_prop_to_name(prop);
}
/*
* Convert any properties to the internal DSL value types.
*/
*svalp = NULL;
*ivalp = 0;
switch (proptype) {
case PROP_TYPE_STRING:
if (datatype != DATA_TYPE_STRING) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' must be a string"), nvpair_name(elem));
goto error;
}
(void) nvpair_value_string(elem, svalp);
if (strlen(*svalp) >= ZFS_MAXPROPLEN) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' is too long"), nvpair_name(elem));
goto error;
}
break;
case PROP_TYPE_NUMBER:
if (datatype == DATA_TYPE_STRING) {
(void) nvpair_value_string(elem, &value);
if (strcmp(value, "none") == 0) {
isnone = B_TRUE;
} else if (zfs_nicestrtonum(hdl, value, ivalp)
!= 0) {
goto error;
}
} else if (datatype == DATA_TYPE_UINT64) {
(void) nvpair_value_uint64(elem, ivalp);
} else {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' must be a number"), nvpair_name(elem));
goto error;
}
/*
* Quota special: force 'none' and don't allow 0.
*/
if ((type & ZFS_TYPE_DATASET) && *ivalp == 0 && !isnone &&
(prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_REFQUOTA)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"use 'none' to disable quota/refquota"));
goto error;
}
break;
case PROP_TYPE_INDEX:
if (datatype != DATA_TYPE_STRING) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' must be a string"), nvpair_name(elem));
goto error;
}
(void) nvpair_value_string(elem, &value);
if (zprop_string_to_index(prop, value, ivalp, type) != 0) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' must be one of '%s'"), propname,
zprop_values(prop, type));
goto error;
}
break;
default:
abort();
}
/*
* Add the result to our return set of properties.
*/
if (*svalp != NULL) {
if (nvlist_add_string(ret, propname, *svalp) != 0) {
(void) no_memory(hdl);
return (-1);
}
} else {
if (nvlist_add_uint64(ret, propname, *ivalp) != 0) {
(void) no_memory(hdl);
return (-1);
}
}
return (0);
error:
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
return (-1);
}
static int
addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
zfs_type_t type)
{
int prop;
zprop_list_t *entry;
prop = zprop_name_to_prop(propname, type);
if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type))
prop = ZPROP_INVAL;
/*
* When no property table entry can be found, return failure if
* this is a pool property or if this isn't a user-defined
* dataset property,
*/
if (prop == ZPROP_INVAL && (type == ZFS_TYPE_POOL ||
!zfs_prop_user(propname))) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid property '%s'"), propname);
return (zfs_error(hdl, EZFS_BADPROP,
dgettext(TEXT_DOMAIN, "bad property list")));
}
if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
return (-1);
entry->pl_prop = prop;
if (prop == ZPROP_INVAL) {
if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) == NULL) {
free(entry);
return (-1);
}
entry->pl_width = strlen(propname);
} else {
entry->pl_width = zprop_width(prop, &entry->pl_fixed,
type);
}
*listp = entry;
return (0);
}
/*
* Given a comma-separated list of properties, construct a property list
* containing both user-defined and native properties. This function will
* return a NULL list if 'all' is specified, which can later be expanded
* by zprop_expand_list().
*/
int
zprop_get_list(libzfs_handle_t *hdl, char *props, zprop_list_t **listp,
zfs_type_t type)
{
*listp = NULL;
/*
* If 'all' is specified, return a NULL list.
*/
if (strcmp(props, "all") == 0)
return (0);
/*
* If no props were specified, return an error.
*/
if (props[0] == '\0') {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"no properties specified"));
return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN,
"bad property list")));
}
/*
* It would be nice to use getsubopt() here, but the inclusion of column
* aliases makes this more effort than it's worth.
*/
while (*props != '\0') {
size_t len;
char *p;
char c;
if ((p = strchr(props, ',')) == NULL) {
len = strlen(props);
p = props + len;
} else {
len = p - props;
}
/*
* Check for empty options.
*/
if (len == 0) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"empty property name"));
return (zfs_error(hdl, EZFS_BADPROP,
dgettext(TEXT_DOMAIN, "bad property list")));
}
/*
* Check all regular property names.
*/
c = props[len];
props[len] = '\0';
if (strcmp(props, "space") == 0) {
static char *spaceprops[] = {
"name", "avail", "used", "usedbysnapshots",
"usedbydataset", "usedbyrefreservation",
"usedbychildren", NULL
};
int i;
for (i = 0; spaceprops[i]; i++) {
if (addlist(hdl, spaceprops[i], listp, type))
return (-1);
listp = &(*listp)->pl_next;
}
} else {
if (addlist(hdl, props, listp, type))
return (-1);
listp = &(*listp)->pl_next;
}
props = p;
if (c == ',')
props++;
}
return (0);
}
void
zprop_free_list(zprop_list_t *pl)
{
zprop_list_t *next;
while (pl != NULL) {
next = pl->pl_next;
free(pl->pl_user_prop);
free(pl);
pl = next;
}
}
typedef struct expand_data {
zprop_list_t **last;
libzfs_handle_t *hdl;
zfs_type_t type;
} expand_data_t;
int
zprop_expand_list_cb(int prop, void *cb)
{
zprop_list_t *entry;
expand_data_t *edp = cb;
if ((entry = zfs_alloc(edp->hdl, sizeof (zprop_list_t))) == NULL)
return (ZPROP_INVAL);
entry->pl_prop = prop;
entry->pl_width = zprop_width(prop, &entry->pl_fixed, edp->type);
entry->pl_all = B_TRUE;
*(edp->last) = entry;
edp->last = &entry->pl_next;
return (ZPROP_CONT);
}
int
zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp, zfs_type_t type)
{
zprop_list_t *entry;
zprop_list_t **last;
expand_data_t exp;
if (*plp == NULL) {
/*
* If this is the very first time we've been called for an 'all'
* specification, expand the list to include all native
* properties.
*/
last = plp;
exp.last = last;
exp.hdl = hdl;
exp.type = type;
if (zprop_iter_common(zprop_expand_list_cb, &exp, B_FALSE,
B_FALSE, type) == ZPROP_INVAL)
return (-1);
/*
* Add 'name' to the beginning of the list, which is handled
* specially.
*/
if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
return (-1);
entry->pl_prop = (type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME :
ZFS_PROP_NAME;
entry->pl_width = zprop_width(entry->pl_prop,
&entry->pl_fixed, type);
entry->pl_all = B_TRUE;
entry->pl_next = *plp;
*plp = entry;
}
return (0);
}
int
zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered,
zfs_type_t type)
{
return (zprop_iter_common(func, cb, show_all, ordered, type));
}
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -101,24 +101,20 @@ void
zmutex_init(kmutex_t *mp)
{
mp->m_owner = NULL;
mp->initialized = B_TRUE;
(void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
}
void
zmutex_destroy(kmutex_t *mp)
{
ASSERT(mp->initialized == B_TRUE);
ASSERT(mp->m_owner == NULL);
(void) _mutex_destroy(&(mp)->m_lock);
mp->m_owner = (void *)-1UL;
mp->initialized = B_FALSE;
}
void
mutex_enter(kmutex_t *mp)
{
ASSERT(mp->initialized == B_TRUE);
ASSERT(mp->m_owner != (void *)-1UL);
ASSERT(mp->m_owner != curthread);
VERIFY(mutex_lock(&mp->m_lock) == 0);
@@ -129,7 +125,6 @@ mutex_enter(kmutex_t *mp)
int
mutex_tryenter(kmutex_t *mp)
{
ASSERT(mp->initialized == B_TRUE);
ASSERT(mp->m_owner != (void *)-1UL);
if (mutex_trylock(&mp->m_lock) == 0) {
ASSERT(mp->m_owner == NULL);
@@ -143,7 +138,6 @@ mutex_tryenter(kmutex_t *mp)
void
mutex_exit(kmutex_t *mp)
{
ASSERT(mp->initialized == B_TRUE);
ASSERT(mp->m_owner == curthread);
mp->m_owner = NULL;
VERIFY(mutex_unlock(&mp->m_lock) == 0);
@@ -152,7 +146,6 @@ mutex_exit(kmutex_t *mp)
void *
mutex_owner(kmutex_t *mp)
{
ASSERT(mp->initialized == B_TRUE);
return (mp->m_owner);
}
@@ -167,7 +160,7 @@ rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
{
rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
rwlp->rw_owner = NULL;
rwlp->initialized = B_TRUE;
rwlp->rw_count = 0;
}
void
@@ -175,23 +168,22 @@ rw_destroy(krwlock_t *rwlp)
{
rwlock_destroy(&rwlp->rw_lock);
rwlp->rw_owner = (void *)-1UL;
rwlp->initialized = B_FALSE;
rwlp->rw_count = -2;
}
void
rw_enter(krwlock_t *rwlp, krw_t rw)
{
//ASSERT(!RW_LOCK_HELD(rwlp));
ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
ASSERT(rwlp->rw_owner != curthread);
if (rw == RW_READER) {
VERIFY(rw_rdlock(&rwlp->rw_lock) == 0);
(void) rw_rdlock(&rwlp->rw_lock);
ASSERT(rwlp->rw_count >= 0);
atomic_add_int(&rwlp->rw_count, 1);
} else {
VERIFY(rw_wrlock(&rwlp->rw_lock) == 0);
(void) rw_wrlock(&rwlp->rw_lock);
ASSERT(rwlp->rw_count == 0);
rwlp->rw_count = -1;
rwlp->rw_owner = curthread;
@@ -201,7 +193,6 @@ rw_enter(krwlock_t *rwlp, krw_t rw)
void
rw_exit(krwlock_t *rwlp)
{
ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
if (rwlp->rw_owner == curthread) {
@@ -214,7 +205,7 @@ rw_exit(krwlock_t *rwlp)
ASSERT(rwlp->rw_count > 0);
atomic_add_int(&rwlp->rw_count, -1);
}
VERIFY(rw_unlock(&rwlp->rw_lock) == 0);
(void) rw_unlock(&rwlp->rw_lock);
}
int
@@ -222,7 +213,6 @@ rw_tryenter(krwlock_t *rwlp, krw_t rw)
{
int rv;
ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
ASSERT(rwlp->rw_owner != curthread);
@@ -251,7 +241,6 @@ rw_tryenter(krwlock_t *rwlp, krw_t rw)
int
rw_tryupgrade(krwlock_t *rwlp)
{
ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
return (0);
@@ -433,10 +422,9 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
return (0);
}
/*ARGSUSED*/
int
vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
int x3, vnode_t *startvp, int fd)
int x3, vnode_t *startvp)
{
char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
int ret;
@@ -444,7 +432,6 @@ vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
ASSERT(startvp == rootdir);
(void) sprintf(realpath, "/%s", path);
/* fd ignored for now, need if want to simulate nbmand support */
ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
umem_free(realpath, strlen(path) + 2);
@@ -482,7 +469,7 @@ vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
}
void
vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td)
vn_close(vnode_t *vp)
{
close(vp->v_fd);
spa_strfree(vp->v_path);
@@ -670,8 +657,7 @@ kobj_open_file(char *name)
vnode_t *vp;
/* set vp as the _fd field of the file */
if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
-1) != 0)
if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir) != 0)
return ((void *)-1UL);
file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
@@ -693,7 +679,7 @@ kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
void
kobj_close_file(struct _buf *file)
{
vn_close((vnode_t *)file->_fd, 0, NULL, NULL);
vn_close((vnode_t *)file->_fd);
umem_free(file, sizeof (struct _buf));
}
@@ -704,7 +690,7 @@ kobj_get_filesize(struct _buf *file, uint64_t *size)
vnode_t *vp = (vnode_t *)file->_fd;
if (fstat64(vp->v_fd, &st) == -1) {
vn_close(vp, 0, NULL, NULL);
vn_close(vp);
return (errno);
}
*size = st.st_size;
@@ -760,11 +746,10 @@ highbit(ulong_t i)
}
#endif
static int random_fd = -1, urandom_fd = -1;
static int
random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
random_get_bytes_common(uint8_t *ptr, size_t len, char *devname)
{
int fd = open(devname, O_RDONLY);
size_t resid = len;
ssize_t bytes;
@@ -772,24 +757,26 @@ random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
while (resid != 0) {
bytes = read(fd, ptr, resid);
ASSERT3S(bytes, >=, 0);
ASSERT(bytes >= 0);
ptr += bytes;
resid -= bytes;
}
close(fd);
return (0);
}
int
random_get_bytes(uint8_t *ptr, size_t len)
{
return (random_get_bytes_common(ptr, len, random_fd));
return (random_get_bytes_common(ptr, len, "/dev/random"));
}
int
random_get_pseudo_bytes(uint8_t *ptr, size_t len)
{
return (random_get_bytes_common(ptr, len, urandom_fd));
return (random_get_bytes_common(ptr, len, "/dev/urandom"));
}
int
@@ -828,11 +815,7 @@ kernel_init(int mode)
dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
(double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
snprintf(hw_serial, sizeof (hw_serial), "%lu",
(unsigned long)gethostid());
VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
snprintf(hw_serial, sizeof (hw_serial), "%ld", gethostid());
spa_init(mode);
}
@@ -841,12 +824,6 @@ void
kernel_fini(void)
{
spa_fini();
close(random_fd);
close(urandom_fd);
random_fd = -1;
urandom_fd = -1;
}
int
@@ -873,62 +850,3 @@ z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen,
return (ret);
}
uid_t
crgetuid(cred_t *cr)
{
return (0);
}
gid_t
crgetgid(cred_t *cr)
{
return (0);
}
int
crgetngroups(cred_t *cr)
{
return (0);
}
gid_t *
crgetgroups(cred_t *cr)
{
return (NULL);
}
int
zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
{
return (0);
}
int
zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
{
return (0);
}
int
zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
{
return (0);
}
ksiddomain_t *
ksid_lookupdomain(const char *dom)
{
ksiddomain_t *kd;
kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
kd->kd_name = spa_strdup(dom);
return (kd);
}
void
ksiddomain_rele(ksiddomain_t *ksid)
{
spa_strfree(ksid->kd_name);
umem_free(ksid, sizeof (ksiddomain_t));
}
@@ -19,13 +19,15 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_ZFS_CONTEXT_H
#define _SYS_ZFS_CONTEXT_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
@@ -62,7 +64,6 @@ extern "C" {
#include <fsshare.h>
#include <sys/note.h>
#include <sys/types.h>
#include <sys/cred.h>
#include <sys/atomic.h>
#include <sys/sysmacros.h>
#include <sys/bitmap.h>
@@ -77,10 +78,8 @@ extern "C" {
#include <sys/debug.h>
#include <sys/sdt.h>
#include <sys/kstat.h>
#include <sys/u8_textprep.h>
#include <sys/kernel.h>
#include <sys/disk.h>
#include <sys/sysevent/eventdefs.h>
#include <machine/atomic.h>
#define ZFS_EXPORTS_PATH "/etc/zfs/exports"
@@ -117,12 +116,11 @@ extern void vcmn_err(int, const char *, __va_list);
extern void panic(const char *, ...);
extern void vpanic(const char *, __va_list);
#define fm_panic panic
/* This definition is copied from assert.h. */
#if defined(__STDC__)
#if __STDC_VERSION__ - 0 >= 199901L
#define verify(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
#define verify(EX) (void)((EX) || \
(__assert_c99(#EX, __FILE__, __LINE__, __func__), 0))
#else
#define verify(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
#endif /* __STDC_VERSION__ - 0 >= 199901L */
@@ -169,16 +167,11 @@ _NOTE(CONSTCOND) } while (0)
#endif
/*
* DTrace SDT probes have different signatures in userland than they do in
* Dtrace SDT probes have different signatures in userland than they do in
* kernel. If they're being used in kernel code, re-define them out of
* existence for their counterparts in libzpool.
*/
#ifdef DTRACE_PROBE
#undef DTRACE_PROBE
#define DTRACE_PROBE(a) ((void)0)
#endif /* DTRACE_PROBE */
#ifdef DTRACE_PROBE1
#undef DTRACE_PROBE1
#define DTRACE_PROBE1(a, b, c) ((void)0)
@@ -219,9 +212,8 @@ extern kthread_t *zk_thread_create(void (*func)(), void *arg);
* Mutexes
*/
typedef struct kmutex {
void *m_owner;
boolean_t initialized;
mutex_t m_lock;
void *m_owner;
mutex_t m_lock;
} kmutex_t;
#define MUTEX_DEFAULT USYNC_THREAD
@@ -251,7 +243,6 @@ extern void *mutex_owner(kmutex_t *mp);
typedef struct krwlock {
int rw_count;
void *rw_owner;
boolean_t initialized;
rwlock_t rw_lock;
} krwlock_t;
@@ -262,7 +253,6 @@ typedef int krw_t;
#define RW_DEFAULT USYNC_THREAD
#undef RW_READ_HELD
#define RW_READ_HELD(x) ((x)->rw_owner == NULL && (x)->rw_count > 0)
#undef RW_WRITE_HELD
#define RW_WRITE_HELD(x) ((x)->rw_owner == curthread)
@@ -277,11 +267,6 @@ extern void rw_exit(krwlock_t *rwlp);
extern int rw_lock_held(krwlock_t *rwlp);
#define rw_downgrade(rwlp) do { } while (0)
extern uid_t crgetuid(cred_t *cr);
extern gid_t crgetgid(cred_t *cr);
extern int crgetngroups(cred_t *cr);
extern gid_t *crgetgroups(cred_t *cr);
/*
* Condition variables
*/
@@ -300,8 +285,6 @@ extern void cv_broadcast(kcondvar_t *cv);
* Kernel memory
*/
#define KM_SLEEP UMEM_NOFAIL
#define KM_PUSHPAGE KM_SLEEP
#define KM_ZERO 0
#define KM_NOSLEEP UMEM_DEFAULT
#define KMC_NODEBUG UMC_NODEBUG
#define kmem_alloc(_s, _f) umem_alloc(_s, _f)
@@ -339,9 +322,6 @@ extern void taskq_destroy(taskq_t *);
extern void taskq_wait(taskq_t *);
extern int taskq_member(taskq_t *, void *);
#define XVA_MAPSIZE 3
#define XVA_MAGIC 0x78766174
/*
* vnodes
*/
@@ -351,94 +331,44 @@ typedef struct vnode {
char *v_path;
} vnode_t;
typedef struct xoptattr {
timestruc_t xoa_createtime; /* Create time of file */
uint8_t xoa_archive;
uint8_t xoa_system;
uint8_t xoa_readonly;
uint8_t xoa_hidden;
uint8_t xoa_nounlink;
uint8_t xoa_immutable;
uint8_t xoa_appendonly;
uint8_t xoa_nodump;
uint8_t xoa_settable;
uint8_t xoa_opaque;
uint8_t xoa_av_quarantined;
uint8_t xoa_av_modified;
} xoptattr_t;
typedef struct vattr {
uint_t va_mask; /* bit-mask of attributes */
u_offset_t va_size; /* file size in bytes */
} vattr_t;
typedef struct xvattr {
vattr_t xva_vattr; /* Embedded vattr structure */
uint32_t xva_magic; /* Magic Number */
uint32_t xva_mapsize; /* Size of attr bitmap (32-bit words) */
uint32_t *xva_rtnattrmapp; /* Ptr to xva_rtnattrmap[] */
uint32_t xva_reqattrmap[XVA_MAPSIZE]; /* Requested attrs */
uint32_t xva_rtnattrmap[XVA_MAPSIZE]; /* Returned attrs */
xoptattr_t xva_xoptattrs; /* Optional attributes */
} xvattr_t;
typedef struct vsecattr {
uint_t vsa_mask; /* See below */
int vsa_aclcnt; /* ACL entry count */
void *vsa_aclentp; /* pointer to ACL entries */
int vsa_dfaclcnt; /* default ACL entry count */
void *vsa_dfaclentp; /* pointer to default ACL entries */
size_t vsa_aclentsz; /* ACE size in bytes of vsa_aclentp */
} vsecattr_t;
#define AT_TYPE 0x00001
#define AT_MODE 0x00002
#define AT_UID 0x00004
#define AT_GID 0x00008
#define AT_FSID 0x00010
#define AT_NODEID 0x00020
#define AT_NLINK 0x00040
#define AT_SIZE 0x00080
#define AT_ATIME 0x00100
#define AT_MTIME 0x00200
#define AT_CTIME 0x00400
#define AT_RDEV 0x00800
#define AT_BLKSIZE 0x01000
#define AT_NBLOCKS 0x02000
#define AT_SEQ 0x08000
#define AT_XVATTR 0x10000
#define AT_TYPE 0x0001
#define AT_MODE 0x0002
#define AT_UID 0x0004
#define AT_GID 0x0008
#define AT_FSID 0x0010
#define AT_NODEID 0x0020
#define AT_NLINK 0x0040
#define AT_SIZE 0x0080
#define AT_ATIME 0x0100
#define AT_MTIME 0x0200
#define AT_CTIME 0x0400
#define AT_RDEV 0x0800
#define AT_BLKSIZE 0x1000
#define AT_NBLOCKS 0x2000
#define AT_SEQ 0x8000
#define CRCREAT 0
#define VOP_CLOSE(vp, f, c, o, cr, ct) 0
#define VOP_PUTPAGE(vp, of, sz, fl, cr, ct) 0
#define VOP_GETATTR(vp, vap, cr, td) ((vap)->va_size = (vp)->v_size, 0)
#define VOP_CLOSE(vp, f, c, o, cr) 0
#define VOP_PUTPAGE(vp, of, sz, fl, cr) 0
#define VOP_GETATTR(vp, vap, fl, cr) ((vap)->va_size = (vp)->v_size, 0)
#define VOP_FSYNC(vp, f, cr, ct) fsync((vp)->v_fd)
#define VOP_FSYNC(vp, f, cr) fsync((vp)->v_fd)
#define VN_RELE(vp) vn_close(vp, 0, NULL, NULL)
#define VN_RELE_ASYNC(vp, taskq) vn_close(vp, 0, NULL, NULL)
#define vn_lock(vp, type, td)
#define VOP_UNLOCK(vp, type, td)
#ifdef VFS_LOCK_GIANT
#undef VFS_LOCK_GIANT
#endif
#define VFS_LOCK_GIANT(mp) 0
#ifdef VFS_UNLOCK_GIANT
#undef VFS_UNLOCK_GIANT
#endif
#define VFS_UNLOCK_GIANT(vfslocked)
#define VN_RELE(vp) vn_close(vp)
extern int vn_open(char *path, int x1, int oflags, int mode, vnode_t **vpp,
int x2, int x3);
extern int vn_openat(char *path, int x1, int oflags, int mode, vnode_t **vpp,
int x2, int x3, vnode_t *vp, int fd);
int x2, int x3, vnode_t *vp);
extern int vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len,
offset_t offset, int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp);
extern void vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td);
extern void vn_close(vnode_t *vp);
#define vn_remove(path, x1, x2) remove(path)
#define vn_rename(from, to, seg) rename((from), (to))
@@ -467,9 +397,8 @@ extern void delay(clock_t ticks);
#define CPU_SEQID (thr_self() & (max_ncpus - 1))
#ifndef ptob
#define ptob(x) ((x) * PAGESIZE)
#endif
#define kcred NULL
#define CRED() NULL
extern uint64_t physmem;
@@ -526,31 +455,11 @@ struct bootstat {
uint64_t st_size;
};
typedef struct ace_object {
uid_t a_who;
uint32_t a_access_mask;
uint16_t a_flags;
uint16_t a_type;
uint8_t a_obj_type[16];
uint8_t a_inherit_obj_type[16];
} ace_object_t;
#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05
#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06
#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07
#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08
extern struct _buf *kobj_open_file(char *name);
extern int kobj_read_file(struct _buf *file, char *buf, unsigned size,
unsigned off);
extern void kobj_close_file(struct _buf *file);
extern int kobj_get_filesize(struct _buf *file, uint64_t *size);
extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr);
extern int zfs_secpolicy_rename_perms(const char *from, const char *to,
cred_t *cr);
extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
extern zoneid_t getzoneid(void);
/* Random compatibility stuff. */
#define lbolt (gethrtime() >> 23)
#define lbolt64 (gethrtime() >> 23)
@@ -573,32 +482,18 @@ struct file {
#define FCREAT O_CREAT
#define FOFFMAX 0x0
/* SID stuff */
typedef struct ksiddomain {
uint_t kd_ref;
uint_t kd_len;
char *kd_name;
} ksiddomain_t;
ksiddomain_t *ksid_lookupdomain(const char *);
void ksiddomain_rele(ksiddomain_t *);
#define SX_SYSINIT(name, lock, desc)
#define SYSCTL_DECL(...)
#define SYSCTL_NODE(...)
#define SYSCTL_INT(...)
#define SYSCTL_UINT(...)
#define SYSCTL_ULONG(...)
#define SYSCTL_QUAD(...)
#ifdef TUNABLE_INT
#undef TUNABLE_INT
#undef TUNABLE_ULONG
#undef TUNABLE_QUAD
#endif
#define TUNABLE_INT(...)
#define TUNABLE_ULONG(...)
#define TUNABLE_QUAD(...)
/* Errors */
@@ -2,8 +2,9 @@
* 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.
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,7 +20,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -176,9 +177,6 @@ taskq_create(const char *name, int nthreads, pri_t pri,
int t;
rw_init(&tq->tq_threadlock, NULL, RW_DEFAULT, NULL);
mutex_init(&tq->tq_lock, NULL, MUTEX_DEFAULT, NULL);
cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL);
cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL);
tq->tq_flags = flags | TASKQ_ACTIVE;
tq->tq_active = nthreads;
tq->tq_nthreads = nthreads;
@@ -232,9 +230,6 @@ taskq_destroy(taskq_t *tq)
kmem_free(tq->tq_threadlist, nthreads * sizeof (thread_t));
rw_destroy(&tq->tq_threadlock);
mutex_destroy(&tq->tq_lock);
cv_destroy(&tq->tq_dispatch_cv);
cv_destroy(&tq->tq_wait_cv);
kmem_free(tq, sizeof (taskq_t));
}
@@ -19,10 +19,12 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <assert.h>
#include <sys/zfs_context.h>
#include <sys/avl.h>
@@ -65,58 +67,46 @@ nicenum(uint64_t num, char *buf)
}
static void
show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent)
show_vdev_stats(const char *desc, nvlist_t *nv, int indent)
{
vdev_stat_t *vs;
vdev_stat_t v0 = { 0 };
uint64_t sec;
uint64_t is_log = 0;
nvlist_t **child;
uint_t c, children;
vdev_stat_t *vs;
uint64_t sec;
char used[6], avail[6];
char rops[6], wops[6], rbytes[6], wbytes[6], rerr[6], werr[6], cerr[6];
char *prefix = "";
if (indent == 0 && desc != NULL) {
(void) printf(" "
if (indent == 0) {
(void) printf(" "
" capacity operations bandwidth ---- errors ----\n");
(void) printf("description "
(void) printf("description "
"used avail read write read write read write cksum\n");
}
if (desc != NULL) {
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
VERIFY(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
(uint64_t **)&vs, &c) == 0);
if (is_log)
prefix = "log ";
sec = MAX(1, vs->vs_timestamp / NANOSEC);
if (nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
(uint64_t **)&vs, &c) != 0)
vs = &v0;
nicenum(vs->vs_alloc, used);
nicenum(vs->vs_space - vs->vs_alloc, avail);
nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops);
nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops);
nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes);
nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes);
nicenum(vs->vs_read_errors, rerr);
nicenum(vs->vs_write_errors, werr);
nicenum(vs->vs_checksum_errors, cerr);
sec = MAX(1, vs->vs_timestamp / NANOSEC);
(void) printf("%*s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n",
indent, "",
indent - 19 - (vs->vs_space ? 0 : 12), desc,
vs->vs_space ? 6 : 0, vs->vs_space ? used : "",
vs->vs_space ? 6 : 0, vs->vs_space ? avail : "",
rops, wops, rbytes, wbytes, rerr, werr, cerr);
nicenum(vs->vs_alloc, used);
nicenum(vs->vs_space - vs->vs_alloc, avail);
nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops);
nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops);
nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes);
nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes);
nicenum(vs->vs_read_errors, rerr);
nicenum(vs->vs_write_errors, werr);
nicenum(vs->vs_checksum_errors, cerr);
(void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n",
indent, "",
prefix,
indent + strlen(prefix) - 25 - (vs->vs_space ? 0 : 12),
desc,
vs->vs_space ? 6 : 0, vs->vs_space ? used : "",
vs->vs_space ? 6 : 0, vs->vs_space ? avail : "",
rops, wops, rbytes, wbytes, rerr, werr, cerr);
}
if (nvlist_lookup_nvlist_array(nv, ctype, &child, &children) != 0)
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
&child, &children) != 0)
return;
for (c = 0; c < children; c++) {
@@ -130,7 +120,7 @@ show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent)
(void) strcpy(tname, cname);
if (nvlist_lookup_uint64(cnv, ZPOOL_CONFIG_NPARITY, &np) == 0)
tname[strlen(tname)] = '0' + np;
show_vdev_stats(tname, ctype, cnv, indent + 2);
show_vdev_stats(tname, cnv, indent + 2);
free(tname);
}
}
@@ -141,16 +131,14 @@ show_pool_stats(spa_t *spa)
nvlist_t *config, *nvroot;
char *name;
VERIFY(spa_get_stats(spa_name(spa), &config, NULL, 0) == 0);
spa_config_enter(spa, RW_READER, FTAG);
config = spa_config_generate(spa, NULL, -1ULL, B_TRUE);
spa_config_exit(spa, FTAG);
VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
&nvroot) == 0);
VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
&name) == 0);
show_vdev_stats(name, ZPOOL_CONFIG_CHILDREN, nvroot, 0);
show_vdev_stats(NULL, ZPOOL_CONFIG_L2CACHE, nvroot, 0);
show_vdev_stats(NULL, ZPOOL_CONFIG_SPARES, nvroot, 0);
nvlist_free(config);
show_vdev_stats(name, nvroot, 0);
}
+1 -1
View File
@@ -14,7 +14,7 @@ SUBDIR= drti \
.if ${MK_ZFS} != "no"
_libzfs= libzfs
.if ${MK_LIBTHR} != "no"
.if ${MK_LIBTHR} != "no" || ${MK_LIBKSE} != "no"
_libzpool= libzpool
.endif
.endif
+1 -1
View File
@@ -10,8 +10,8 @@ SRCS= libnvpair.c \
nvpair_alloc_fixed.c \
nvpair.c
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../../include # XXX
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
.include <bsd.lib.mk>
+3 -7
View File
@@ -10,17 +10,14 @@ DPADD= ${LIBUTIL}
LDADD= -lutil
SRCS= deviceid.c \
fsshare.c \
mkdirp.c \
mnttab.c \
mkdirp.c \
zmount.c \
fsshare.c \
zone.c
SRCS+= zfs_deleg.c \
zfs_namecheck.c \
SRCS+= zfs_namecheck.c \
zfs_prop.c \
zpool_prop.c \
zprop_common.c \
libzfs_dataset.c \
libzfs_util.c \
libzfs_graph.c \
@@ -29,7 +26,6 @@ SRCS+= zfs_deleg.c \
libzfs_changelist.c \
libzfs_config.c \
libzfs_import.c \
libzfs_sendrecv.c \
libzfs_status.c
CFLAGS+= -DZFS_NO_ACL
+2 -15
View File
@@ -13,13 +13,11 @@
# ATOMIC_SRCS
.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "ia64"
.PATH: ${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/atomic/${MACHINE_ARCH}
ATOMIC_SRCS= opensolaris_atomic.S
ATOMIC_SRCS= atomic.S
.else
.PATH: ${.CURDIR}/../../../sys/cddl/compat/opensolaris/kern
ATOMIC_SRCS= opensolaris_atomic.c
.endif
# UNICODE_SRCS
.PATH: ${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/unicode
LIB= zpool
@@ -27,11 +25,9 @@ ZFS_COMMON_SRCS= ${ZFS_COMMON_OBJS:C/.o$/.c/} vdev_file.c
ZFS_SHARED_SRCS= ${ZFS_SHARED_OBJS:C/.o$/.c/}
KERNEL_SRCS= kernel.c taskq.c util.c
LIST_SRCS= list.c
UNICODE_SRCS= u8_textprep.c
SRCS= ${ZFS_COMMON_SRCS} ${ZFS_SHARED_SRCS} \
${KERNEL_SRCS} ${LIST_SRCS} ${ATOMIC_SRCS} \
${UNICODE_SRCS}
${KERNEL_SRCS} ${LIST_SRCS} ${ATOMIC_SRCS}
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
@@ -44,13 +40,6 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../../cddl/lib/libumem
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
# XXX: pthread doesn't have mutex_owned() equivalent, so we need to look
# into libthr private structures. That's sooo evil, but it's only for
# ZFS debugging tools needs.
CFLAGS+= -DWANTS_MUTEX_OWNED
CFLAGS+= -I${.CURDIR}/../../../lib/libpthread/thread
CFLAGS+= -I${.CURDIR}/../../../lib/libpthread/sys
CFLAGS+= -I${.CURDIR}/../../../lib/libthr/arch/${MACHINE_ARCH}/include
DPADD= ${LIBPTHREAD} ${LIBZ}
LDADD= -lpthread -lz
@@ -58,6 +47,4 @@ LDADD= -lpthread -lz
# atomic.S doesn't like profiling.
NO_PROFILE=
CSTD= c99
.include <bsd.lib.mk>
+2 -4
View File
@@ -1,11 +1,10 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/zpool \
${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/zpool
PROG= zpool
MAN= zpool.8
SRCS= zpool_main.c zpool_vdev.c zpool_iter.c zpool_util.c zfs_comutil.c
SRCS= zpool_main.c zpool_vdev.c zpool_iter.c zpool_util.c
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
@@ -16,7 +15,6 @@ CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libuutil/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libumem/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
+1 -3
View File
@@ -7,12 +7,10 @@ SUBDIR= \
ctfdump \
ctfmerge \
sgsmsg \
${_zinject} \
${_ztest}
.if ${MK_ZFS} != "no"
_zinject= zinject
.if ${MK_LIBTHR} != "no"
.if ${MK_LIBTHR} != "no" || ${MK_LIBKSE} != "no"
_ztest= ztest
.endif
.endif
-25
View File
@@ -1,25 +0,0 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../contrib/opensolaris/cmd/zinject
PROG= zinject
SRCS= zinject.c translate.c
NO_MAN=
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/lib/libumem
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libzfs/common
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../lib/libumem
DPADD= ${LIBAVL} ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBUMEM} ${LIBUUTIL} \
${LIBZFS} ${LIBZPOOL} ${LIBUUTIL}
LDADD= -lavl -lgeom -lm -lnvpair -lumem -luutil -lzfs -lzpool
.include <bsd.prog.mk>
+5 -7
View File
@@ -1,24 +1,22 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../..//contrib/opensolaris/cmd/ztest
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/ztest
PROG= ztest
NO_MAN=
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/lib/libumem
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../lib/libumem
DPADD= ${LIBM} ${LIBNVPAIR} ${LIBUMEM} ${LIBZPOOL} \
${LIBPTHREAD} ${LIBZ} ${LIBAVL}
LDADD= -lm -lnvpair -lumem -lzpool -lpthread -lz -lavl
CSTD= c99
.include <bsd.prog.mk>
+1 -1
View File
@@ -6,7 +6,7 @@ SUBDIR= dtrace \
${_zdb}
.if ${MK_ZFS} != "no"
.if ${MK_LIBTHR} != "no"
.if ${MK_LIBTHR} != "no" || ${MK_LIBKSE} != "no"
_zdb= zdb
.endif
.endif
+3 -8
View File
@@ -9,9 +9,6 @@ SRCS= zdb.c zdb_il.c
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libuutil/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
@@ -19,10 +16,8 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../lib/libumem
DPADD= ${LIBAVL} ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBPTHREAD} ${LIBUMEM} \
${LIBUUTIL} ${LIBZ} ${LIBZFS} ${LIBZPOOL}
LDADD= -lavl -lgeom -lm -lnvpair -lpthread -lumem -luutil -lz -lzfs -lzpool
CSTD= c99
DPADD= ${LIBM} ${LIBNVPAIR} ${LIBUMEM} ${LIBZPOOL} \
${LIBPTHREAD} ${LIBZ} ${LIBAVL}
LDADD= -lm -lnvpair -lumem -lzpool -lpthread -lz -lavl
.include <bsd.prog.mk>
+6 -289
View File
@@ -1,295 +1,17 @@
--- 9.4-ESV released ---
2831. [security] Do not attempt to validate or cache
out-of-bailiwick data returned with a secure
answer; it must be re-fetched from its original
source and validated in that context. [RT #20819]
2828. [security] Cached CNAME or DNAME RR could be returned to clients
without DNSSEC validation. [RT #20737]
2827. [security] Bogus NXDOMAIN could be cached as if valid. [RT #20712]
2797. [bug] Don't decrement the dispatch manager's maxbuffers.
[RT #20613]
2790. [bug] Handle DS queries to stub zones. [RT #20440]
2772. [security] When validating, track whether pending data was from
the additional section or not and only return it if
validates as secure. [RT #20438]
--- 9.4-ESVb1 released ---
2698. [cleanup] configure --enable-libbind is deprecated. [RT #20090]
2697. [port] win32: ensure that S_IFMT, S_IFDIR, S_IFCHR and
S_IFREG are defined after including <isc/stat.h>.
[RT #20309]
2690. [bug] win32: fix isc_thread_key_getspecific() prototype.
[RT #20315]
2689. [bug] Correctly handle snprintf result. [RT #20306]
2688. [bug] Use INTERFACE_F_POINTTOPOINT, not IFF_POINTOPOINT,
to decide to fetch the destination address. [RT #20305]
2681. [bug] IPSECKEY RR of gateway type 3 was not correctly
decoded. [RT #20269]
2672. [bug] Don't enable searching in 'host' when doing reverse
lookups. [RT #20218]
2525. [experimental] New logging category "query-errors" to provide detailed
internal information about query failures, especially
about server failures. (backported as a special
exception to the general policy) [RT #19027]
2670. [bug] Unexpected connect failures failed to log enough
information to be useful. [RT #20205]
2649. [bug] Set the domain for forward only zones. [RT #19944]
2648. [port] win32: isc_time_seconds() was broken. [RT #19900]
2646. [bug] Incorrect cleanup on error in socket.c. [RT #19987]
2642. [bug] nsupdate could dump core on solaris when reading
improperly formatted key files. [RT #20015]
2640. [security] A specially crafted update packet will cause named
to exit. [RT #20000]
2637. [func] Rationalize dnssec-signzone's signwithkey() calling.
[RT #19959]
2635. [bug] isc_inet_ntop() incorrectly handled 0.0/16 addresses.
[RT #19716]
2633. [bug] Handle 15 bit rand() functions. [RT #19783]
2632. [func] util/kit.sh: warn if documentation appears to be out of
date. [RT #19922]
2623. [bug] Named started seaches for DS non-optimally. [RT #19915]
2621. [doc] Made copyright boilterplate consistent. [RT #19833]
2920. [bug] Delay thawing the zone until the reload of it has
completed successfully. [RT #19750]
2618. [bug] The sdb and sdlz db_interator_seek() methods could
loop infinitely. [RT #19847]
2617. [bug] ifconfig.sh failed to emit an error message when
run from the wrong location. [RT #19375]
2616. [bug] 'host' used the nameservers from resolv.conf even
when a explicit nameserver was specified. [RT #19852]
2615. [bug] "__attribute__((unused))" was in the wrong place
for ia64 gcc builds. [RT #19854]
2614. [port] win32: 'named -v' should automatically be executed
in the foreground. [RT #19844]
2610. [port] sunos: Change #2363 was not complete. [RT #19796]
2606. [bug] "delegation-only" was not being accepted in
delegation-only type zones. [RT #19717]
2605. [bug] Accept DS responses from delegation only zones.
[RT # 19296]
2603. [port] win32: handle .exe extension of named-checkzone and
named-comilezone argv[0] names under windows.
[RT #19767]
2602. [port] win32: fix debugging command line build of libisccfg.
[RT #19767]
2599. [bug] Address rapid memory growth when validation fails.
[RT #19654]
2595. [bug] Fix unknown extended rcodes in dig. [RT #19625]
2592. [bug] Treat "any" as a type in nsupdate. [RT #19455]
2591. [bug] named could die when processing a update in
removed_orphaned_ds(). [RT #19507]
2589. [bug] dns_db_unregister() failed to clear '*dbimp'.
[RT #19626]
2586. [bug] Missing cleanup of SIG rdataset in searching a DLZ DB
or SDB. [RT #19577]
2584. [bug] alpha: gcc optimization could break atomic operations.
[RT #19227]
2583. [port] netbsd: provide a control to not add the compile
date to the version string, -DNO_VERSION_DATE.
2582. [bug] Don't emit warning log message when we attempt to
remove non-existant journal. [RT #19516]
2581. [contrib] dlz/mysql set MYSQL_OPT_RECONNECT option on connection.
Requires MySQL 5.0.19 or later. [RT #19084]
--- 9.4.3-P2 released ---
2579. [bug] DNSSEC lookaside validation failed to handle unknown
algorithms. [RT #19479]
2573. [bug] Replacing a non-CNAME record with a CNAME record in a
single transaction in a signed zone failed. [RT #19397]
2568. [bug] Report when the write to indicate a otherwise
successful start fails. [RT #19360]
2567. [bug] dst__privstruct_writefile() could miss write errors.
write_public_key() could miss write errors.
[RT #19360]
2564. [bug] Only take EDNS fallback steps when processing timeouts.
[RT #19405]
2563. [bug] Dig could leak a socket causing it to wait forever
to exit. [RT #19359]
2562. [doc] ARM: miscellaneous improvements, reorganization,
and some new content.
2561. [doc] Add isc-config.sh(1) man page. [RT #16378]
2557. [cleanup] PCI compliance:
* new libisc log module file
* isc_dir_chroot() now also changes the working
directory to "/".
* additional INSISTs
* additional logging when files can't be removed.
2553. [bug] Reference leak on DNSSEC validation errors. [RT #19291]
2552. [bug] zero-no-soa-ttl-cache was not being honoured.
[RT #19340]
2551. [bug] Potential Reference leak on return. [RT #19341]
2550. [bug] Check --with-openssl=<path> finds <openssl/opensslv.h>.
[RT #19343]
2549. [port] linux: define NR_OPEN if not currently defined.
[RT #19344]
2547. [bug] openssl_link.c:mem_realloc() could reference an
out-of-range area of the source buffer. New public
function isc_mem_reallocate() was introduced to address
this bug. [RT #19313]
2545. [doc] ARM: Legal hostname checking (check-names) is
for SRV RDATA too. [RT #19304]
2544. [cleanup] Removed unused structure members in adb.c. [RT #19225]
2542. [doc] Update the description of dig +adflag. [RT #19290]
2539. [security] Update the interaction between recursion, allow-query,
allow-query-cache and allow-recursion. [RT #19198]
2536. [cleanup] Silence some warnings when -Werror=format-security is
specified. [RT #19083]
2535. [bug] dig +showsearch and +trace interacted badly. [RT #19091]
2532. [bug] dig: check the question section of the response to
see if it matches the asked question. [RT #18495]
2531. [bug] Change #2207 was incomplete. [RT #19098]
2529. [cleanup] Upgrade libtool to silence complaints from recent
version of autoconf. [RT #18657]
2528. [cleanup] Silence spurious configure warning about
--datarootdir [RT #19096]
2527. [bug] named could reuse cache on reload with
enabling/disabling validation. [RT #19119]
2523. [bug] Random type rdata freed by dns_nsec_typepresent().
[RT #19112]
--- 9.4.3-P1 released ---
2522. [security] Handle -1 from DSA_do_verify().
2521. [bug] Improve epoll cross compilation support. [RT #19047]
2519. [bug] dig/host with -4 or -6 didn't work if more than two
nameserver addresses of the excluded address family
preceded in resolv.conf. [RT #19081]
2517. [bug] dig +trace with -4 or -6 failed when it chose a
nameserver address of the excluded address type.
[RT #18843]
2516. [bug] glue sort for responses was performed even when not
needed. [RT #19039]
2514. [bug] dig/host failed with -4 or -6 when resolv.conf contains
a nameserver of the excluded address family.
[RT #18848]
2511. [cleanup] dns_rdata_tofmttext() add const to linebreak.
[RT #18885]
2510. [bug] "dig +sigchase" could trigger REQUIRE failures.
[RT #19033]
2509. [bug] Specifying a fixed query source port was broken.
[RT #19051]
2506. [port] solaris: Check at configure time if
hack_shutup_pthreadonceinit is needed. [RT #19037]
2505. [port] Treat amd64 similarly to x86_64 when determining
atomic operation support. [RT #19031]
2504. [bug] Address race condition in the socket code. [RT #18899]
2503. [port] linux: improve compatibility with Linux Standard
Base. [RT #18793]
2500. [contrib] contrib/sdb/pgsql/zonetodb.c called non-existent
function. [RT #18582]
2499. [port] solaris: lib/lwres/getaddrinfo.c namespace clash.
[RT #18837]
2498. [bug] Removed a bogus function argument used with
ISC_SOCKET_USE_POLLWATCH: it could cause compiler
warning or crash named with the debug 1 level
of logging. [RT #18917]
2495. [bug] Tighten RRSIG checks. [RT #18795]
2494. [bug] dns/sdlz.h and dns/dlz.h were not being installed.
[RT #18826]
2487. [bug] Give TCP connections longer to complete. [RT #18675]
2485. [bug] Change update's the handling of obscured RRSIG
records. Not all orphand DS records were being
removed. [RT #18828]
2479. [bug] xfrout:covers was not properly initalized. [RT #18801]
2478. [bug] 'addresses' could be used uninitalized in
configure_forward(). [RT #18800]
2476. [doc] ARM: improve documentation for max-journal-size and
ixfr-from-differences. [RT #15909] [RT #18541]
2400. [bug] Log if kqueue()/epoll_create()/open(/dev/poll) fails.
[RT #18297]
--- 9.4.3 released ---
2490. [port] aix: work around a kernel bug where IPV6_RECVPKTINFO
@@ -305,7 +27,7 @@
2473. [port] linux: raise the limit on open files to the possible
maximum value before spawning threads; 'files'
specified in named.conf doesn't seem to work with
specified in named.conf doesn't seem to work with
threads as expected. [RT #18784]
2472. [port] linux: check the number of available cpu's before
@@ -328,11 +50,10 @@
2465. [bug] Adb's handling of lame addresses was different
for IPv4 and IPv6. [RT #18738]
2463. [port] linux: POSIX doesn't include the IPv6 Advanced Socket
2463. [port] linux: POSIX doesn't include the IPv6 Advanced Socket
API and glibc hides parts of the IPv6 Advanced Socket
API as a result. This is stupid as it breaks how the
two halves (Basic and Advanced) of the IPv6 Socket API
were designed to be used but we have to live with it.
two halves (Basic and Advanced) of the IPv6 Socket API were designed to be used but we have to live with it.
Define _GNU_SOURCE to pull in the IPv6 Advanced Socket
API. [RT #18388]
@@ -438,10 +159,6 @@
for select(). To enable this, set ISC_SOCKET_MAXSOCKETS
at compilation time. [RT #18433]
Note: with changes #2469 and #2421 above, there is no
need to tweak ISC_SOCKET_MAXSOCKETS at compilation time
any more.
2410. [bug] Correctly delete m_versionInfo. [RT #18432]
2408. [bug] A duplicate TCP dispatch event could be sent, which
@@ -513,7 +230,7 @@
2380. [bug] dns_view_find() was not returning NXDOMAIN/NXRRSET
proofs which, in turn, caused validation failures
for insecure zones immediately below a secure zone
the server was authoritative for. [RT #18112]
the server was authoritative for. [RT #18112]
2379. [contrib] queryperf/gen-data-queryperf.py: removed redundant
TLDs and supported RRs with TTLs [RT #17972]
+2 -2
View File
@@ -1,4 +1,4 @@
Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
Copyright (C) 1996-2003 Internet Software Consortium.
Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
$Id: COPYRIGHT,v 1.9.18.7 2010/01/07 23:46:07 tbox Exp $
$Id: COPYRIGHT,v 1.9.18.5 2008/01/02 23:46:02 tbox Exp $
Portions Copyright (C) 1996-2001 Nominum, Inc.
+13 -17
View File
@@ -1,6 +1,6 @@
Frequently Asked Questions about BIND 9
Copyright © 2004-2009 Internet Systems Consortium, Inc. ("ISC")
Copyright © 2004-2008 Internet Systems Consortium, Inc. ("ISC")
Copyright © 2000-2003 Internet Software Consortium.
@@ -153,29 +153,24 @@ A: BIND 9.3 and later: Use TSIG to select the appropriate view.
Master 10.0.1.1:
key "external" {
algorithm hmac-sha256;
secret "xxxxxxxxxxxxxxxxxxxxxxxx";
algorithm hmac-md5;
secret "xxxxxxxx";
};
view "internal" {
match-clients { !key external; // reject message ment for the
// external view.
10.0.1/24; }; // accept from these addresses.
match-clients { !key external; 10.0.1/24; };
...
};
view "external" {
match-clients { key external; any; };
server 10.0.1.2 { keys external; }; // tag messages from the
// external view to the
// other servers for the
// view.
server 10.0.1.2 { keys external; };
recursion no;
...
};
Slave 10.0.1.2:
key "external" {
algorithm hmac-sha256;
secret "xxxxxxxxxxxxxxxxxxxxxxxx";
algorithm hmac-md5;
secret "xxxxxxxx";
};
view "internal" {
match-clients { !key external; 10.0.1/24; };
@@ -225,13 +220,13 @@ A: You choose one view to be master and the second a slave and transfer
Master 10.0.1.1:
key "external" {
algorithm hmac-sha256;
secret "xxxxxxxxxxxxxxxxxxxxxxxx";
algorithm hmac-md5;
secret "xxxxxxxx";
};
key "mykey" {
algorithm hmac-sha256;
secret "yyyyyyyyyyyyyyyyyyyyyyyy";
algorithm hmac-md5;
secret "yyyyyyyy";
};
view "internal" {
@@ -605,7 +600,7 @@ Q: Why do queries for NSEC3 records fail to return the NSEC3 record?
A: NSEC3 records are strictly meta data and can only be returned in the
authority section. This is done so that signing the zone using NSEC3
records does not bring names into existence that do not exist in the
records does not bring names into existance that do not exist in the
unsigned version of the zone.
5. Operating-System Specific Questions
@@ -830,6 +825,7 @@ A: /dev/random is not configured. Use rndcontrol(8) to tell the kernel to
use certain interrupts as a source of random events. You can make this
permanent by setting rand_irqs in /etc/rc.conf.
/etc/rc.conf
rand_irqs="3 14 15"
See also <http://people.freebsd.org/~dougb/randomness.html>.
+14 -19
View File
@@ -1,7 +1,7 @@
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []>
<!--
- Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- $Id: FAQ.xml,v 1.4.4.29 2009/10/06 01:33:54 tbox Exp $ -->
<!-- $Id: FAQ.xml,v 1.4.4.24 2008/09/10 01:32:25 tbox Exp $ -->
<article class="faq">
<title>Frequently Asked Questions about BIND 9</title>
@@ -28,7 +28,6 @@
<year>2006</year>
<year>2007</year>
<year>2008</year>
<year>2009</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
@@ -319,29 +318,24 @@ Slave: 10.0.1.3 (internal), 10.0.1.4 (external, IP alias)
<programlisting>
Master 10.0.1.1:
key "external" {
algorithm hmac-sha256;
secret "xxxxxxxxxxxxxxxxxxxxxxxx";
algorithm hmac-md5;
secret "xxxxxxxx";
};
view "internal" {
match-clients { !key external; // reject message ment for the
// external view.
10.0.1/24; }; // accept from these addresses.
match-clients { !key external; 10.0.1/24; };
...
};
view "external" {
match-clients { key external; any; };
server 10.0.1.2 { keys external; }; // tag messages from the
// external view to the
// other servers for the
// view.
server 10.0.1.2 { keys external; };
recursion no;
...
};
Slave 10.0.1.2:
key "external" {
algorithm hmac-sha256;
secret "xxxxxxxxxxxxxxxxxxxxxxxx";
algorithm hmac-md5;
secret "xxxxxxxx";
};
view "internal" {
match-clients { !key external; 10.0.1/24; };
@@ -429,13 +423,13 @@ named-checkzone example.com tmp</programlisting>
<programlisting>
Master 10.0.1.1:
key "external" {
algorithm hmac-sha256;
secret "xxxxxxxxxxxxxxxxxxxxxxxx";
algorithm hmac-md5;
secret "xxxxxxxx";
};
key "mykey" {
algorithm hmac-sha256;
secret "yyyyyyyyyyyyyyyyyyyyyyyy";
algorithm hmac-md5;
secret "yyyyyyyy";
};
view "internal" {
@@ -1073,7 +1067,7 @@ empty:
NSEC3 records are strictly meta data and can only be
returned in the authority section. This is done so that
signing the zone using NSEC3 records does not bring names
into existence that do not exist in the unsigned version
into existance that do not exist in the unsigned version
of the zone.
</para>
</answer>
@@ -1476,6 +1470,7 @@ options {
</para>
<informalexample>
<programlisting>
/etc/rc.conf
rand_irqs="3 14 15"</programlisting>
</informalexample>
<para>
+120
View File
@@ -0,0 +1,120 @@
FreeBSD maintainer's guide to updating BIND 9
=============================================
1) Obtain the latest source distribution from the ISC's FTP server
(ftp://ftp.isc.org/isc/bind9/)
2) Unpack the tarball in a suitable directory, and cd into the new
source directory.
3) Remove unwanted files and directories:
$ while read pattern ; do rm -rf $pattern ; done \
</usr/src/contrib/bind9/FREEBSD-Xlist
Make sure that took care of everything, and if it didn't, make sure
to update FREEBSD-Xlist so you won't miss it the next time. A good
way to do this is to run a test import and see if any new files
show up:
$ cvs -q -n import src/contrib/bind9 ISC x | grep \^N
4) Import the sources:
$ cvs import -m "Vendor import of BIND 9.X.Y" \
src/contrib/bind9 ISC BIND_9_X_Y
5) Resolve conflicts.
As of 2 June 2007, we have no local patches against BIND 9; thus
there are no conflicts to merge. This may change at a later date.
5a) Remove any files that are no longer in the tarball from the vendor branch.
6) Remove any references to the {bin,lib}/tests and docutil
directories from the configure and Makefile templates:
$ sed -i.orig -e '/\/tests/d; /docutil/d; /\/xsl/d;' \
configure.in Makefile.in */Makefile.in
Please do not commit this change, as it would unnecessarily take
files off the vendor branch. You only need this to generate
config.h.
7) Generate and run configure:
$ aclocal
$ autoheader
$ autoconf
$ ./configure --prefix=/usr \
--infodir=/usr/share/info --mandir=/usr/share/man \
--enable-threads --enable-libbind --disable-ipv6 \
--enable-getifaddrs --disable-linux-caps \
--with-openssl=/usr --with-randomdev=/dev/random
Note that we intentionally disable IPv6 support on the configure
command line; src/lib/bind/config.mk will re-enable it at compile
time if WITHOUT_INET6 is not defined.
8) Copy the following generated files to src/lib/bind and commit them:
Path in src/contrib/bind9 Path in src/lib/bind
------------------------------------------------------------
s=/usr/src/lib/bind
cp config.h ${s}/config.h
cp lib/bind/config.h ${s}/bind/config.h
cp lib/bind/port_after.h ${s}/bind/port_after.h
cp lib/bind/port_before.h ${s}/bind/port_before.h
cp lib/isc/include/isc/platform.h ${s}/isc/isc/platform.h
cp lib/lwres/include/lwres/netdb.h ${s}/lwres/lwres/netdb.h
cp lib/lwres/include/lwres/platform.h ${s}/lwres/lwres/platform.h
Do not commit any other file that was modified or created in
steps 6) or 7).
9) cd src/lib/bind/dns && make -DMAINTAINER_MODE generate && rm gen
Commit the new versions of the files generated.
The following directories contain Makefiles for bits and pieces of
BIND 9:
FreeBSD directory ISC directory
========================================================
src/lib/bind bind9/lib
src/lib/bind/bind bind9/lib/bind
src/lib/bind/bind9 bind9/lib/bind9
src/lib/bind/dns bind9/lib/dns
src/lib/bind/isc bind9/lib/isc
src/lib/bind/isccc bind9/lib/isccc
src/lib/bind/isccfg bind9/lib/isccfg
src/lib/bind/lwres bind9/lib/lwres
src/share/doc/bind9 bind9/doc/{arm,misc}
src/usr.bin/dig bind9/bin/dig
src/usr.bin/host bind9/bin/dig
src/usr.bin/nslookup bind9/bin/dig
src/usr.bin/nsupdate bind9/bin/nsupdate
src/usr.sbin/dnssec-keygen bind9/bin/dnssec
src/usr.sbin/dnssec-signzone bind9/bin/dnssec
src/usr.sbin/named bind9/bin/named
src/usr.sbin/named-checkconf bind9/bin/check
src/usr.sbin/named-checkzone bind9/bin/check
src/usr.sbin/rndc bind9/bin/rndc
src/usr.sbin/rndc-confgen bind9/bin/rndc
Make sure that the lists of sources, headers and man pages in each
FreeBSD Makefile accurately reflects those in the corresponding ISC
Makefile. Please strive to keep those lists in the same order and
with line breaks in the same places to ease future comparisons.
A) Build and test.
B) Lather, rinse, repeat.
C) Commit when everything builds cleanly and works properly.
-- [email protected]
-- [email protected]
$FreeBSD$
+67
View File
@@ -0,0 +1,67 @@
# $FreeBSD$
# Misc. stuff
.cvsignore
aclocal.m4
config.h.in
configure
contrib
docutil
# Tests
bin/tests
lib/tests
# Doc stuff
doc/arm/latex-fixup.pl
doc/xsl
# Windows directories
bin/check/win32
bin/dig/win32
bin/dnssec/win32
bin/named/win32
bin/nsupdate/win32
bin/rndc/win32
bin/win32
config.h.win32
lib/bind9/win32
lib/dns/gen-win32.h
lib/dns/win32
lib/isc/win32
lib/isccc/win32
lib/isccfg/win32
lib/lwres/win32
lib/win32
win32utils
# Various ports to other OSs
lib/bind/port/aix*
lib/bind/port/aux3
lib/bind/port/bsdos
lib/bind/port/bsdos2
lib/bind/port/cygwin
lib/bind/port/darwin
lib/bind/port/decunix
lib/bind/port/hpux
lib/bind/port/hpux10
lib/bind/port/hpux9
lib/bind/port/irix
lib/bind/port/linux
lib/bind/port/lynxos
lib/bind/port/mpe
lib/bind/port/netbsd
lib/bind/port/next
lib/bind/port/openbsd
lib/bind/port/prand_conf
lib/bind/port/qnx
lib/bind/port/rhapsody
lib/bind/port/sco42
lib/bind/port/sco50
lib/bind/port/solaris
lib/bind/port/sunos
lib/bind/port/ultrix
lib/bind/port/unixware20
lib/bind/port/unixware212
lib/bind/port/unixware7
lib/bind/port/unknown
+2 -15
View File
@@ -1,4 +1,4 @@
# Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.43.18.8 2009/02/20 23:46:01 tbox Exp $
# $Id: Makefile.in,v 1.43.18.6 2007/09/03 23:46:21 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -24,12 +24,6 @@ top_srcdir = @top_srcdir@
SUBDIRS = make lib bin doc @LIBBIND@
TARGETS =
MANPAGES = isc-config.sh.1
HTMLPAGES = isc-config.sh.html
MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
distclean::
@@ -49,19 +43,12 @@ distclean::
maintainer-clean::
rm -f configure
docclean manclean maintainer-clean::
rm -f ${MANOBJS}
doc man:: ${MANOBJS}
installdirs:
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir} \
${DESTDIR}${localstatedir}/run ${DESTDIR}${sysconfdir}
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man1
install:: isc-config.sh installdirs
${INSTALL_SCRIPT} isc-config.sh ${DESTDIR}${bindir}
${INSTALL_DATA} ${srcdir}/isc-config.sh.1 ${DESTDIR}${mandir}/man1
tags:
rm -f TAGS
+12 -23
View File
@@ -27,8 +27,8 @@ BIND 9
- Improved Portability Architecture
BIND version 9 development has been under written by the following
organisations:
BIND version 9 development has been underwritten by the following
organizations:
Sun Microsystems, Inc.
Hewlett Packard
@@ -42,16 +42,6 @@ BIND 9
Stichting NLnet - NLnet Foundation
Nominum, Inc.
BIND 9.4-ESV (Extended Support Version)
BIND 9.4-ESV is the Extended Support Version of BIND 9.4
and incorporates the final maintenance release fixing bugs
in BIND 9.4.3.
BIND 9.4-ESV will be supported until December 31, 2010, at
which time you will need to upgrade to the current release
of BIND.
BIND 9.4.3
BIND 9.4.3 is a maintenance release, fixing bugs in 9.4.2.
@@ -77,7 +67,7 @@ BIND 9.4.0
Implemented "additional section caching" (or "acache"), an
internal cache framework for additional section content to
improve response performance. Several configuration options
were provided to control the behaviour.
were provided to control the behavior.
New notify type 'master-only'. Enable notify for master
zones only.
@@ -86,14 +76,13 @@ BIND 9.4.0
rndc now allows addresses to be set in the server clauses.
New option "allow-query-cache". This lets "allow-query"
be used to specify the default zone access level rather
than having to have every zone override the global value.
"allow-query-cache" can be set at both the options and view
levels. If "allow-query-cache" is not set then "allow-recursion"
is used if set, otherwise "allow-query" is used if set
unless "recursion no;" is set in which case "none;" is used,
otherwise the default (localhost; localnets;) is used.
New option "allow-query-cache". This lets allow-query be
used to specify the default zone access level rather than
having to have every zone override the global value.
allow-query-cache can be set at both the options and view
levels. If allow-query-cache is not set then allow-recursion
is used if set, otherwise allow-query is used if set, otherwise
the default (localhost; localnets;) is used.
rndc: the source address can now be specified.
@@ -161,12 +150,12 @@ BIND 9.4.0
options for dnssec-signzone specify the input and output
formats.
dnssec-signzone can now randomise signature end times
dnssec-signzone can now randomize signature end times
(dnssec-signzone -j jitter).
Add support for CH A record.
Add additional zone data consistency checks. named-checkzone
Add additional zone data consistancy checks. named-checkzone
has extended checking of NS, MX and SRV record and the hosts
they reference. named has extended post zone load checks.
New zone options: check-mx and integrity-check.
+4 -4
View File
@@ -55,7 +55,7 @@ at least specify `--with-idn' option to enable IDN support.
`--with-libiconv' assumes that your C compiler has `-R'
option, and that the option adds the specified run-time path
to an executable binary. If `-R' option of your compiler has
to an exacutable binary. If `-R' option of your compiler has
different meaning, or your compiler lacks the option, you
should use `--with-iconv' option instead. Binary command
without run-time path information might be unexecutable.
@@ -68,7 +68,7 @@ at least specify `--with-idn' option to enable IDN support.
specified, `--with-iconv' is prior to `--with-libiconv'.
--with-iconv=ICONV_LIBSPEC
If your libc doesn't provide iconv(), you need to specify the
If your libc doens't provide iconv(), you need to specify the
library containing iconv() with this option. `ICONV_LIBSPEC'
is the argument(s) to `cc' or `ld' to link the library, for
example, `--with-iconv="-L/usr/local/lib -liconv"'.
@@ -82,7 +82,7 @@ at least specify `--with-idn' option to enable IDN support.
this option is not specified, `-L${PREFIX}/lib -lidnkit' is
assumed, where ${PREFIX} is the installation prefix specified
with `--with-idn' option above. You may need to use this
option to specify extra arguments, for example,
option to specify extra argments, for example,
`--with-idnlib="-L/usr/local/lib -R/usr/local/lib -lidnkit"'.
Please consult `README' for other configuration options.
@@ -109,4 +109,4 @@ about idnkit and this patch.
Bug reports and comments on this kit should be sent to
[email protected] and [email protected], respectively.
; $Id: README.idnkit,v 1.2.2.3 2009/01/19 00:36:25 marka Exp $
; $Id: README.idnkit,v 1.2.2.2 2005/09/12 02:12:08 marka Exp $
Loaded 100 of 2443 files, more files were not shown because too many files have changed in this diff. Show more