This commit is contained in:
attilio 2011-12-02 21:45:46 +00:00
commit b2701fb716
284 changed files with 14679 additions and 4150 deletions

View File

@ -59,8 +59,6 @@ SUBDIR+=games
.endif
.if ${MK_CDDL} != "no"
SUBDIR+=cddl
.else
NO_CTF=1
.endif
SUBDIR+=gnu include
.if ${MK_KERBEROS} != "no"
@ -239,7 +237,7 @@ BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \
BOOTSTRAPPING=${OSRELDATE} \
SSP_CFLAGS= \
-DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT -DWITHOUT_MAN \
-DNO_PIC -DWITHOUT_PROFILE -DNO_SHARED \
-DNO_PIC -DNO_PROFILE -DNO_SHARED \
-DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF
# build-tools stage
@ -438,7 +436,7 @@ _libraries:
@echo "--------------------------------------------------------------"
${_+_}cd ${.CURDIR}; \
${WMAKE} -DNO_FSCHG -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT \
-DWITHOUT_MAN -DWITHOUT_PROFILE libraries
-DWITHOUT_MAN -DNO_PROFILE libraries
_depend:
@echo
@echo "--------------------------------------------------------------"
@ -1321,8 +1319,8 @@ ${_lib}__PL: .PHONY
cd ${.CURDIR}/${_lib}; \
${MAKE} DIRPRFX=${_lib}/ obj; \
${MAKE} DIRPRFX=${_lib}/ depend; \
${MAKE} -DWITHOUT_PROFILE -DNO_PIC DIRPRFX=${_lib}/ all; \
${MAKE} -DWITHOUT_PROFILE -DNO_PIC DIRPRFX=${_lib}/ install
${MAKE} -DNO_PROFILE -DNO_PIC DIRPRFX=${_lib}/ all; \
${MAKE} -DNO_PROFILE -DNO_PIC DIRPRFX=${_lib}/ install
.endif
.endfor
@ -1555,7 +1553,7 @@ XDEV_CPUTYPE?=${TARGET_CPUTYPE}
.endif
NOFUN=-DNO_FSCHG -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT \
-DWITHOUT_MAN -DWITHOUT_NLS -DWITHOUT_PROFILE \
-DWITHOUT_MAN -DWITHOUT_NLS -DNO_PROFILE \
-DWITHOUT_KERBEROS -DWITHOUT_RESCUE -DNO_WARNS \
TARGET=${XDEV} TARGET_ARCH=${XDEV_ARCH} \
CPUTYPE=${XDEV_CPUTYPE}

View File

@ -22,6 +22,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
machines to maximize performance. (To disable malloc debugging, run
ln -s aj /etc/malloc.conf.)
20111122:
The acpi_wmi(4) status device /dev/wmistat has been renamed to
/dev/wmistat0.
20111108:
The option VFS_ALLOW_NONMPSAFE option has been added in order to
explicitely support non-MPSAFE filesystems.

View File

@ -48,12 +48,16 @@
.Ar size volume
.Nm
.Cm destroy
.Op Fl rRf
.Op Fl fnpRrv
.Ar filesystem Ns | Ns Ar volume
.Nm
.Cm destroy
.Op Fl rRd
.Op Fl dnpRrv
.Sm off
.Ar snapshot
.Ns Op % Ns Ar snapname
.Ns Op , Ns Ar ...
.Sm on
.Nm
.Cm snapshot
.Op Fl r
@ -160,7 +164,7 @@
.Fl a | Ar filesystem Ns | Ns Ar mountpoint
.Nm
.Cm send
.Op Fl DvRp
.Op Fl DnPpRrv
.Op Fl i Ar snapshot | Fl I Ar snapshot
.Ar snapshot
.Nm
@ -487,6 +491,17 @@ The default value is
.Cm off .
.It Sy creation
The time this dataset was created.
.It Sy clones
For snapshots, this property is a comma-separated list of filesystems or
volumes which are clones of this snapshot. The clones'
.Sy origin
property is this snapshot. If the
.Sy clones
property is not empty, then this snapshot can not be destroyed (even with the
.Fl r
or
.Fl f
options).
.It Sy defer_destroy
This property is
.Cm on
@ -644,6 +659,28 @@ power of 2 from 512 bytes to 128 Kbytes is valid.
.Pp
This property can also be referred to by its shortened column name,
.Sy volblock .
.It Sy written
The amount of
.Sy referenced
space written to this dataset since the previous snapshot.
.It Sy written@ Ns Ar snapshot
The amount of
.Sy referenced
space written to this dataset since the specified snapshot. This is the space
that is referenced by this dataset but was not referenced by the specified
snapshot.
.Pp
The
.Ar snapshot
may be specified as a short snapshot name (just the part after the
.Sy @ Ns ),
in which case it will be interpreted as a snapshot in the same filesystem as
this dataset. The
.Ar snapshot
may be a full snapshot name
.Pq Em filesystem@snapshot ,
which for clones may be a snapshot in the origin's filesystem (or the origin of
the origin's filesystem, etc).
.El
.Pp
The following native properties can be used to change the behavior of a
@ -1403,7 +1440,7 @@ options.
.It Xo
.Nm
.Cm destroy
.Op Fl rRf
.Op Fl fnpRrv
.Ar filesystem Ns | Ns Ar volume
.Xc
.Pp
@ -1422,6 +1459,17 @@ Force an unmount of any file systems using the
.Qq Nm Cm unmount Fl f
command. This option has no effect on non-file systems or unmounted file
systems.
.It Fl n
Do a dry-run ("No-op") deletion. No data will be deleted. This is useful in
conjunction with the
.Fl v
or
.Fl p
flags to determine what data would be deleted.
.It Fl p
Print machine-parsable verbose information about the deleted data.
.It Fl v
Print verbose information about the deleted data.
.El
.Pp
Extreme care should be taken when applying either the
@ -1433,11 +1481,15 @@ behavior for mounted file systems in use.
.It Xo
.Nm
.Cm destroy
.Op Fl rRd
.Op Fl dnpRrv
.Sm off
.Ar snapshot
.Ns Op % Ns Ar snapname
.Ns Op , Ns Ar ...
.Sm on
.Xc
.Pp
The given snapshot is destroyed immediately if and only if the
The given snapshots are destroyed immediately if and only if the
.Qq Nm Cm destroy
command without the
.Fl d
@ -1445,15 +1497,41 @@ option would have destroyed it. Such immediate destruction would occur, for
example, if the snapshot had no clones and the user-initiated reference count
were zero.
.Pp
If the snapshot does not qualify for immediate destruction, it is marked for
If a snapshot does not qualify for immediate destruction, it is marked for
deferred deletion. In this state, it exists as a usable, visible snapshot until
both of the preconditions listed above are met, at which point it is destroyed.
.Pp
An inclusive range of snapshots may be specified by separating the
first and last snapshots with a percent sign
.Pq Sy % .
The first and/or last snapshots may be left blank, in which case the
filesystem's oldest or newest snapshot will be implied.
.Pp
Multiple snapshots
(or ranges of snapshots) of the same filesystem or volume may be specified
in a comma-separated list of snapshots.
Only the snapshot's short name (the
part after the
.Sy @ )
should be specified when using a range or comma-separated list to identify
multiple snapshots.
.Bl -tag -width indent
.It Fl r
Destroy (or mark for deferred deletion) all snapshots with this name in
descendent file systems.
.It Fl R
Recursively destroy all dependents.
.It Fl n
Do a dry-run ("No-op") deletion. No data will be deleted. This is useful in
conjunction with the
.Fl v
or
.Fl p
flags to determine what data would be deleted.
.It Fl p
Print machine-parsable verbose information about the deleted data.
.It Fl v
Print verbose information about the deleted data.
.It Fl d
Defer snapshot deletion.
.El
@ -2080,7 +2158,7 @@ file system shared on the system.
.It Xo
.Nm
.Cm send
.Op Fl DvRp
.Op Fl DnPpRrv
.Op Fl i Ar snapshot | Fl I Ar snapshot
.Ar snapshot
.Xc
@ -2120,7 +2198,7 @@ Generate a stream package that sends all intermediary snapshots from the
.Ar snapshot . For example,
.Ic -I @a fs@d
is similar to
.Ic -i @a fs@b; -i @b fs@c; -i @c fs@d Ns .
.Ic -i @a fs@b; -i @b fs@c; -i @c fs@d .
The incremental source snapshot may be specified as with the
.Fl i
option.
@ -2151,10 +2229,26 @@ be used regardless of the dataset's
property, but performance will be much better if the filesystem uses a
dedup-capable checksum (eg.
.Sy sha256 Ns ).
.It Fl r
Recursively send all descendant snapshots. This is similar to the
.Fl R
flag, but information about deleted and renamed datasets is not included, and
property information is only included if the
.Fl p
flag is specified.
.It Fl p
Include the dataset's properties in the stream. This flag is implicit when
.Fl R
is specified. The receiving system must also support this feature.
.It Fl n
Do a dry-run ("No-op") send. Do not generate any actual send data. This is
useful in conjunction with the
.Fl v
or
.Fl P
flags to determine what data will be sent.
.It Fl P
Print machine-parsable verbose information about the stream package generated.
.It Fl v
Print verbose information about the stream package generated.
.El
@ -2320,7 +2414,7 @@ may be specified as a comma-separated list. Permission names are the same as
.Tn ZFS
subcommand and property names. See the property list below. Property set names,
which begin with an at sign
.Pq Sy @ Ns ,
.Pq Sy @ ,
may be specified. See the
.Fl s
form below for details.
@ -2442,7 +2536,7 @@ commands for the specified file system and its descendents. Sets are evaluated
dynamically, so changes to a set are immediately reflected. Permission sets
follow the same naming restrictions as ZFS file systems, but the name must
begin with an "at sign"
.Pq Sy @ Ns ,
.Pq Sy @ ,
and can be no more than 64 characters long.
.It Xo
.Nm

View File

@ -22,8 +22,9 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Copyright (c) 2011 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
#include <assert.h>
@ -145,7 +146,7 @@ typedef enum {
HELP_HOLD,
HELP_HOLDS,
HELP_RELEASE,
HELP_DIFF
HELP_DIFF,
} zfs_help_t;
typedef struct zfs_command {
@ -220,8 +221,9 @@ get_usage(zfs_help_t idx)
"\tcreate [-ps] [-b blocksize] [-o property=value] ... "
"-V <size> <volume>\n"));
case HELP_DESTROY:
return (gettext("\tdestroy [-rRf] <filesystem|volume>\n"
"\tdestroy [-rRd] <snapshot>\n"));
return (gettext("\tdestroy [-fnpRrv] <filesystem|volume>\n"
"\tdestroy [-dnpRrv] "
"<snapshot>[%<snapname>][,...]\n"));
case HELP_GET:
return (gettext("\tget [-rHp] [-d max] "
"[-o \"all\" | field[,...]] [-s source[,...]]\n"
@ -260,7 +262,7 @@ get_usage(zfs_help_t idx)
case HELP_ROLLBACK:
return (gettext("\trollback [-rRf] <snapshot>\n"));
case HELP_SEND:
return (gettext("\tsend [-DvRp] "
return (gettext("\tsend [-DnPpRrv] "
"[-i snapshot | -I snapshot] <snapshot>\n"));
case HELP_SET:
return (gettext("\tset <property=value> "
@ -440,6 +442,8 @@ usage(boolean_t requested)
(void) fprintf(fp, "YES NO <size> | none\n");
(void) fprintf(fp, "\t%-15s ", "groupquota@...");
(void) fprintf(fp, "YES NO <size> | none\n");
(void) fprintf(fp, "\t%-15s ", "written@<snap>");
(void) fprintf(fp, " NO NO <size>\n");
(void) fprintf(fp, gettext("\nSizes are specified in bytes "
"with standard units such as K, M, G, etc.\n"));
@ -885,15 +889,23 @@ badusage:
*/
typedef struct destroy_cbdata {
boolean_t cb_first;
int cb_force;
int cb_recurse;
int cb_error;
int cb_needforce;
int cb_doclones;
boolean_t cb_closezhp;
boolean_t cb_force;
boolean_t cb_recurse;
boolean_t cb_error;
boolean_t cb_doclones;
zfs_handle_t *cb_target;
char *cb_snapname;
boolean_t cb_defer_destroy;
boolean_t cb_verbose;
boolean_t cb_parsable;
boolean_t cb_dryrun;
nvlist_t *cb_nvl;
/* first snap in contiguous run */
zfs_handle_t *cb_firstsnap;
/* previous snap in contiguous run */
zfs_handle_t *cb_prevsnap;
int64_t cb_snapused;
char *cb_snapspec;
} destroy_cbdata_t;
/*
@ -923,7 +935,7 @@ destroy_check_dependent(zfs_handle_t *zhp, void *data)
(void) fprintf(stderr, gettext("use '-r' to destroy "
"the following datasets:\n"));
cbp->cb_first = B_FALSE;
cbp->cb_error = 1;
cbp->cb_error = B_TRUE;
}
(void) fprintf(stderr, "%s\n", zfs_get_name(zhp));
@ -944,7 +956,8 @@ destroy_check_dependent(zfs_handle_t *zhp, void *data)
(void) fprintf(stderr, gettext("use '-R' to destroy "
"the following datasets:\n"));
cbp->cb_first = B_FALSE;
cbp->cb_error = 1;
cbp->cb_error = B_TRUE;
cbp->cb_dryrun = B_TRUE;
}
(void) fprintf(stderr, "%s\n", zfs_get_name(zhp));
@ -958,7 +971,20 @@ out:
static int
destroy_callback(zfs_handle_t *zhp, void *data)
{
destroy_cbdata_t *cbp = data;
destroy_cbdata_t *cb = data;
const char *name = zfs_get_name(zhp);
if (cb->cb_verbose) {
if (cb->cb_parsable) {
(void) printf("destroy\t%s\n", name);
} else if (cb->cb_dryrun) {
(void) printf(gettext("would destroy %s\n"),
name);
} else {
(void) printf(gettext("will destroy %s\n"),
name);
}
}
/*
* Ignore pools (which we've already flagged as an error before getting
@ -970,13 +996,12 @@ destroy_callback(zfs_handle_t *zhp, void *data)
return (0);
}
/*
* Bail out on the first error.
*/
if (zfs_unmount(zhp, NULL, cbp->cb_force ? MS_FORCE : 0) != 0 ||
zfs_destroy(zhp, cbp->cb_defer_destroy) != 0) {
zfs_close(zhp);
return (-1);
if (!cb->cb_dryrun) {
if (zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 ||
zfs_destroy(zhp, cb->cb_defer_destroy) != 0) {
zfs_close(zhp);
return (-1);
}
}
zfs_close(zhp);
@ -984,39 +1009,142 @@ destroy_callback(zfs_handle_t *zhp, void *data)
}
static int
destroy_snap_clones(zfs_handle_t *zhp, void *arg)
destroy_print_cb(zfs_handle_t *zhp, void *arg)
{
destroy_cbdata_t *cbp = arg;
char thissnap[MAXPATHLEN];
zfs_handle_t *szhp;
boolean_t closezhp = cbp->cb_closezhp;
int rv;
destroy_cbdata_t *cb = arg;
const char *name = zfs_get_name(zhp);
int err = 0;
(void) snprintf(thissnap, sizeof (thissnap),
"%s@%s", zfs_get_name(zhp), cbp->cb_snapname);
libzfs_print_on_error(g_zfs, B_FALSE);
szhp = zfs_open(g_zfs, thissnap, ZFS_TYPE_SNAPSHOT);
libzfs_print_on_error(g_zfs, B_TRUE);
if (szhp) {
/*
* Destroy any clones of this snapshot
*/
if (zfs_iter_dependents(szhp, B_FALSE, destroy_callback,
cbp) != 0) {
zfs_close(szhp);
if (closezhp)
zfs_close(zhp);
return (-1);
if (nvlist_exists(cb->cb_nvl, name)) {
if (cb->cb_firstsnap == NULL)
cb->cb_firstsnap = zfs_handle_dup(zhp);
if (cb->cb_prevsnap != NULL)
zfs_close(cb->cb_prevsnap);
/* this snap continues the current range */
cb->cb_prevsnap = zfs_handle_dup(zhp);
if (cb->cb_verbose) {
if (cb->cb_parsable) {
(void) printf("destroy\t%s\n", name);
} else if (cb->cb_dryrun) {
(void) printf(gettext("would destroy %s\n"),
name);
} else {
(void) printf(gettext("will destroy %s\n"),
name);
}
}
zfs_close(szhp);
} else if (cb->cb_firstsnap != NULL) {
/* end of this range */
uint64_t used = 0;
err = zfs_get_snapused_int(cb->cb_firstsnap,
cb->cb_prevsnap, &used);
cb->cb_snapused += used;
zfs_close(cb->cb_firstsnap);
cb->cb_firstsnap = NULL;
zfs_close(cb->cb_prevsnap);
cb->cb_prevsnap = NULL;
}
zfs_close(zhp);
return (err);
}
static int
destroy_print_snapshots(zfs_handle_t *fs_zhp, destroy_cbdata_t *cb)
{
int err;
assert(cb->cb_firstsnap == NULL);
assert(cb->cb_prevsnap == NULL);
err = zfs_iter_snapshots_sorted(fs_zhp, destroy_print_cb, cb);
if (cb->cb_firstsnap != NULL) {
uint64_t used = 0;
if (err == 0) {
err = zfs_get_snapused_int(cb->cb_firstsnap,
cb->cb_prevsnap, &used);
}
cb->cb_snapused += used;
zfs_close(cb->cb_firstsnap);
cb->cb_firstsnap = NULL;
zfs_close(cb->cb_prevsnap);
cb->cb_prevsnap = NULL;
}
return (err);
}
static int
snapshot_to_nvl_cb(zfs_handle_t *zhp, void *arg)
{
destroy_cbdata_t *cb = arg;
int err = 0;
/* Check for clones. */
if (!cb->cb_doclones) {
cb->cb_target = zhp;
cb->cb_first = B_TRUE;
err = zfs_iter_dependents(zhp, B_TRUE,
destroy_check_dependent, cb);
}
cbp->cb_closezhp = B_TRUE;
rv = zfs_iter_filesystems(zhp, destroy_snap_clones, arg);
if (closezhp)
zfs_close(zhp);
return (rv);
if (err == 0) {
if (nvlist_add_boolean(cb->cb_nvl, zfs_get_name(zhp)))
nomem();
}
zfs_close(zhp);
return (err);
}
static int
gather_snapshots(zfs_handle_t *zhp, void *arg)
{
destroy_cbdata_t *cb = arg;
int err = 0;
err = zfs_iter_snapspec(zhp, cb->cb_snapspec, snapshot_to_nvl_cb, cb);
if (err == ENOENT)
err = 0;
if (err != 0)
goto out;
if (cb->cb_verbose) {
err = destroy_print_snapshots(zhp, cb);
if (err != 0)
goto out;
}
if (cb->cb_recurse)
err = zfs_iter_filesystems(zhp, gather_snapshots, cb);
out:
zfs_close(zhp);
return (err);
}
static int
destroy_clones(destroy_cbdata_t *cb)
{
nvpair_t *pair;
for (pair = nvlist_next_nvpair(cb->cb_nvl, NULL);
pair != NULL;
pair = nvlist_next_nvpair(cb->cb_nvl, pair)) {
zfs_handle_t *zhp = zfs_open(g_zfs, nvpair_name(pair),
ZFS_TYPE_SNAPSHOT);
if (zhp != NULL) {
boolean_t defer = cb->cb_defer_destroy;
int err;
/*
* We can't defer destroy non-snapshots, so set it to
* false while destroying the clones.
*/
cb->cb_defer_destroy = B_FALSE;
err = zfs_iter_dependents(zhp, B_FALSE,
destroy_callback, cb);
cb->cb_defer_destroy = defer;
zfs_close(zhp);
if (err != 0)
return (err);
}
}
return (0);
}
static int
@ -1025,25 +1153,35 @@ zfs_do_destroy(int argc, char **argv)
destroy_cbdata_t cb = { 0 };
int c;
zfs_handle_t *zhp;
char *cp;
char *at;
zfs_type_t type = ZFS_TYPE_DATASET;
/* check options */
while ((c = getopt(argc, argv, "dfrR")) != -1) {
while ((c = getopt(argc, argv, "vpndfrR")) != -1) {
switch (c) {
case 'v':
cb.cb_verbose = B_TRUE;
break;
case 'p':
cb.cb_verbose = B_TRUE;
cb.cb_parsable = B_TRUE;
break;
case 'n':
cb.cb_dryrun = B_TRUE;
break;
case 'd':
cb.cb_defer_destroy = B_TRUE;
type = ZFS_TYPE_SNAPSHOT;
break;
case 'f':
cb.cb_force = 1;
cb.cb_force = B_TRUE;
break;
case 'r':
cb.cb_recurse = 1;
cb.cb_recurse = B_TRUE;
break;
case 'R':
cb.cb_recurse = 1;
cb.cb_doclones = 1;
cb.cb_recurse = B_TRUE;
cb.cb_doclones = B_TRUE;
break;
case '?':
default:
@ -1058,7 +1196,7 @@ zfs_do_destroy(int argc, char **argv)
/* check number of arguments */
if (argc == 0) {
(void) fprintf(stderr, gettext("missing path argument\n"));
(void) fprintf(stderr, gettext("missing dataset argument\n"));
usage(B_FALSE);
}
if (argc > 1) {
@ -1066,92 +1204,118 @@ zfs_do_destroy(int argc, char **argv)
usage(B_FALSE);
}
/*
* If we are doing recursive destroy of a snapshot, then the
* named snapshot may not exist. Go straight to libzfs.
*/
if (cb.cb_recurse && (cp = strchr(argv[0], '@'))) {
int ret;
at = strchr(argv[0], '@');
if (at != NULL) {
int err;
*cp = '\0';
if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET)) == NULL)
/* Build the list of snaps to destroy in cb_nvl. */
if (nvlist_alloc(&cb.cb_nvl, NV_UNIQUE_NAME, 0) != 0)
nomem();
*at = '\0';
zhp = zfs_open(g_zfs, argv[0],
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
if (zhp == NULL)
return (1);
*cp = '@';
cp++;
if (cb.cb_doclones) {
boolean_t defer = cb.cb_defer_destroy;
cb.cb_snapspec = at + 1;
if (gather_snapshots(zfs_handle_dup(zhp), &cb) != 0 ||
cb.cb_error) {
zfs_close(zhp);
nvlist_free(cb.cb_nvl);
return (1);
}
/*
* Temporarily ignore the defer_destroy setting since
* it's not supported for clones.
*/
cb.cb_defer_destroy = B_FALSE;
cb.cb_snapname = cp;
if (destroy_snap_clones(zhp, &cb) != 0) {
zfs_close(zhp);
return (1);
if (nvlist_empty(cb.cb_nvl)) {
(void) fprintf(stderr, gettext("could not find any "
"snapshots to destroy; check snapshot names.\n"));
zfs_close(zhp);
nvlist_free(cb.cb_nvl);
return (1);
}
if (cb.cb_verbose) {
char buf[16];
zfs_nicenum(cb.cb_snapused, buf, sizeof (buf));
if (cb.cb_parsable) {
(void) printf("reclaim\t%llu\n",
cb.cb_snapused);
} else if (cb.cb_dryrun) {
(void) printf(gettext("would reclaim %s\n"),
buf);
} else {
(void) printf(gettext("will reclaim %s\n"),
buf);
}
cb.cb_defer_destroy = defer;
}
ret = zfs_destroy_snaps(zhp, cp, cb.cb_defer_destroy);
zfs_close(zhp);
if (ret) {
(void) fprintf(stderr,
gettext("no snapshots destroyed\n"));
if (!cb.cb_dryrun) {
if (cb.cb_doclones)
err = destroy_clones(&cb);
if (err == 0) {
err = zfs_destroy_snaps_nvl(zhp, cb.cb_nvl,
cb.cb_defer_destroy);
}
}
return (ret != 0);
}
/* Open the given dataset */
if ((zhp = zfs_open(g_zfs, argv[0], type)) == NULL)
return (1);
cb.cb_target = zhp;
/*
* Perform an explicit check for pools before going any further.
*/
if (!cb.cb_recurse && strchr(zfs_get_name(zhp), '/') == NULL &&
zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
(void) fprintf(stderr, gettext("cannot destroy '%s': "
"operation does not apply to pools\n"),
zfs_get_name(zhp));
(void) fprintf(stderr, gettext("use 'zfs destroy -r "
"%s' to destroy all datasets in the pool\n"),
zfs_get_name(zhp));
(void) fprintf(stderr, gettext("use 'zpool destroy %s' "
"to destroy the pool itself\n"), zfs_get_name(zhp));
zfs_close(zhp);
return (1);
nvlist_free(cb.cb_nvl);
if (err != 0)
return (1);
} else {
/* Open the given dataset */
if ((zhp = zfs_open(g_zfs, argv[0], type)) == NULL)
return (1);
cb.cb_target = zhp;
/*
* Perform an explicit check for pools before going any further.
*/
if (!cb.cb_recurse && strchr(zfs_get_name(zhp), '/') == NULL &&
zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
(void) fprintf(stderr, gettext("cannot destroy '%s': "
"operation does not apply to pools\n"),
zfs_get_name(zhp));
(void) fprintf(stderr, gettext("use 'zfs destroy -r "
"%s' to destroy all datasets in the pool\n"),
zfs_get_name(zhp));
(void) fprintf(stderr, gettext("use 'zpool destroy %s' "
"to destroy the pool itself\n"), zfs_get_name(zhp));
zfs_close(zhp);
return (1);
}
/*
* Check for any dependents and/or clones.
*/
cb.cb_first = B_TRUE;
if (!cb.cb_doclones &&
zfs_iter_dependents(zhp, B_TRUE, destroy_check_dependent,
&cb) != 0) {
zfs_close(zhp);
return (1);
}
if (cb.cb_error) {
zfs_close(zhp);
return (1);
}
if (zfs_iter_dependents(zhp, B_FALSE, destroy_callback,
&cb) != 0) {
zfs_close(zhp);
return (1);
}
/*
* Do the real thing. The callback will close the
* handle regardless of whether it succeeds or not.
*/
if (destroy_callback(zhp, &cb) != 0)
return (1);
}
/*
* Check for any dependents and/or clones.
*/
cb.cb_first = B_TRUE;
if (!cb.cb_doclones && !cb.cb_defer_destroy &&
zfs_iter_dependents(zhp, B_TRUE, destroy_check_dependent,
&cb) != 0) {
zfs_close(zhp);
return (1);
}
if (cb.cb_error || (!cb.cb_defer_destroy &&
(zfs_iter_dependents(zhp, B_FALSE, destroy_callback, &cb) != 0))) {
zfs_close(zhp);
return (1);
}
/*
* Do the real thing. The callback will close the handle regardless of
* whether it succeeds or not.
*/
if (destroy_callback(zhp, &cb) != 0)
return (1);
return (0);
}
@ -1250,6 +1414,17 @@ get_callback(zfs_handle_t *zhp, void *data)
(void) strlcpy(buf, "-", sizeof (buf));
}
zprop_print_one_property(zfs_get_name(zhp), cbp,
pl->pl_user_prop, buf, sourcetype, source, NULL);
} else if (zfs_prop_written(pl->pl_user_prop)) {
sourcetype = ZPROP_SRC_LOCAL;
if (zfs_prop_get_written(zhp, pl->pl_user_prop,
buf, sizeof (buf), cbp->cb_literal) != 0) {
sourcetype = ZPROP_SRC_NONE;
(void) strlcpy(buf, "-", sizeof (buf));
}
zprop_print_one_property(zfs_get_name(zhp), cbp,
pl->pl_user_prop, buf, sourcetype, source, NULL);
} else {
@ -1796,8 +1971,8 @@ zfs_do_upgrade(int argc, char **argv)
"---------------\n");
(void) printf(gettext(" 1 Initial ZFS filesystem version\n"));
(void) printf(gettext(" 2 Enhanced directory entries\n"));
(void) printf(gettext(" 3 Case insensitive and File system "
"unique identifier (FUID)\n"));
(void) printf(gettext(" 3 Case insensitive and filesystem "
"user identifier (FUID)\n"));
(void) printf(gettext(" 4 userquota, groupquota "
"properties\n"));
(void) printf(gettext(" 5 System attributes\n"));
@ -2677,6 +2852,13 @@ print_dataset(zfs_handle_t *zhp, zprop_list_t *pl, boolean_t scripted)
else
propstr = property;
right_justify = B_TRUE;
} else if (zfs_prop_written(pl->pl_user_prop)) {
if (zfs_prop_get_written(zhp, pl->pl_user_prop,
property, sizeof (property), B_FALSE) != 0)
propstr = "-";
else
propstr = property;
right_justify = B_TRUE;
} else {
if (nvlist_lookup_nvlist(userprops,
pl->pl_user_prop, &propval) != 0)
@ -3303,9 +3485,6 @@ usage:
}
/*
* zfs send [-vDp] -R [-i|-I <@snap>] <fs@snap>
* zfs send [-vDp] [-i|-I <@snap>] <fs@snap>
*
* Send a backup stream to stdout.
*/
static int
@ -3317,11 +3496,11 @@ zfs_do_send(int argc, char **argv)
zfs_handle_t *zhp;
sendflags_t flags = { 0 };
int c, err;
nvlist_t *dbgnv;
nvlist_t *dbgnv = NULL;
boolean_t extraverbose = B_FALSE;
/* check options */
while ((c = getopt(argc, argv, ":i:I:RDpv")) != -1) {
while ((c = getopt(argc, argv, ":i:I:RDpvnP")) != -1) {
switch (c) {
case 'i':
if (fromname)
@ -3340,6 +3519,10 @@ zfs_do_send(int argc, char **argv)
case 'p':
flags.props = B_TRUE;
break;
case 'P':
flags.parsable = B_TRUE;
flags.verbose = B_TRUE;
break;
case 'v':
if (flags.verbose)
extraverbose = B_TRUE;
@ -3348,6 +3531,9 @@ zfs_do_send(int argc, char **argv)
case 'D':
flags.dedup = B_TRUE;
break;
case 'n':
flags.dryrun = B_TRUE;
break;
case ':':
(void) fprintf(stderr, gettext("missing argument for "
"'%c' option\n"), optopt);
@ -3373,7 +3559,7 @@ zfs_do_send(int argc, char **argv)
usage(B_FALSE);
}
if (isatty(STDOUT_FILENO)) {
if (!flags.dryrun && isatty(STDOUT_FILENO)) {
(void) fprintf(stderr,
gettext("Error: Stream can not be written to a terminal.\n"
"You must redirect standard output.\n"));
@ -3427,10 +3613,10 @@ zfs_do_send(int argc, char **argv)
if (flags.replicate && fromname == NULL)
flags.doall = B_TRUE;
err = zfs_send(zhp, fromname, toname, flags, STDOUT_FILENO, NULL, 0,
err = zfs_send(zhp, fromname, toname, &flags, STDOUT_FILENO, NULL, 0,
extraverbose ? &dbgnv : NULL);
if (extraverbose) {
if (extraverbose && dbgnv != NULL) {
/*
* dump_nvlist prints to stdout, but that's been
* redirected to a file. Make it print to stderr
@ -3511,7 +3697,7 @@ zfs_do_receive(int argc, char **argv)
return (1);
}
err = zfs_receive(g_zfs, argv[0], flags, STDIN_FILENO, NULL);
err = zfs_receive(g_zfs, argv[0], &flags, STDIN_FILENO, NULL);
return (err != 0);
}

View File

@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd November 26, 2011
.Dd November 28, 2011
.Dt ZPOOL 8
.Os
.Sh NAME
@ -133,6 +133,9 @@
.Op Fl e
.Ar pool device ...
.Nm
.Cm reguid
.Ar pool
.Nm
.Cm remove
.Ar pool device ...
.Nm
@ -192,7 +195,7 @@ are supported:
.Bl -tag
.It Sy disk
A block device, typically located under
.Pa /dev Ns .
.Pa /dev .
.Tn ZFS
can use individual slices or partitions, though the recommended mode of
operation is to use whole disks. A disk can be specified by a full path to the
@ -218,13 +221,14 @@ bytes and can withstand
.Pq Em N-1
devices failing before data integrity is compromised.
.It Sy raidz
.No ( or Sy raidz1 raidz2 raidz3 Ns ).
(or
.Sy raidz1 raidz2 raidz3 ) .
A variation on
.Sy RAID-5
that allows for better distribution of parity and eliminates the
.Qq Sy RAID-5 No write hole
(in which data and parity become inconsistent after a power loss). Data and
parity is striped across all disks within a
.Qq Sy RAID-5
write hole (in which data and parity become inconsistent after a power loss).
Data and parity is striped across all disks within a
.No raidz
group.
.Pp
@ -248,7 +252,7 @@ type specifies a triple-parity
group. The
.Sy raidz No vdev
type is an alias for
.Sy raidz1 Ns .
.Sy raidz1 .
.Pp
A
.No raidz
@ -319,6 +323,9 @@ are used to distinguish where a group ends and another begins. For example, the
following creates two root
.No vdev Ns s,
each a mirror of two disks:
.Bd -literal -offset 2n
.Li # Ic zpool create mypool mirror da0 da1 mirror da2 da3
.Ed
.Ss Device Failure and Recovery
.Tn ZFS
supports a rich set of mechanisms for handling device failure and data
@ -418,7 +425,7 @@ hardware-dependent and might not be supported on all platforms.
.Ss Hot Spares
.Tn ZFS
allows devices to be associated with pools as
.Qq hot spares Ns .
.Qq hot spares .
These devices are not actively used in the pool, but when an active device
fails, it is automatically replaced by a hot spare. To create a pool with hot
spares, specify a
@ -534,12 +541,13 @@ Number of blocks within the pool that are not allocated.
A unique identifier for the pool.
.It Sy health
The current health of the pool. Health can be
.Qq Sy ONLINE Ns ,
.Qq Sy DEGRADED Ns ,
.Qq Sy FAULTED Ns ,
.Qq Sy OFFLINE Ns ,
.Qq Sy REMOVED Ns , or
.Qq Sy UNAVAIL Ns .
.Qq Sy ONLINE ,
.Qq Sy DEGRADED ,
.Qq Sy FAULTED ,
.Qq Sy OFFLINE ,
.Qq Sy REMOVED ,
or
.Qq Sy UNAVAIL .
.It Sy size
Total size of the storage pool.
.It Sy used
@ -574,7 +582,7 @@ is not a persistent property. It is valid only while the system is up.
Setting
.Sy altroot
defaults to using
.Cm cachefile=none Ns ,
.Cm cachefile=none ,
though this may be overridden using an explicit setting.
.El
.Pp
@ -582,7 +590,7 @@ The following property can only be set at import time:
.Bl -tag -width 2n
.It Sy readonly Ns = Ns Cm on No | Cm off
If set to
.Cm on Ns ,
.Cm on ,
pool will be imported in read-only mode with the following restrictions:
.Bl -bullet -offset 2n
.It
@ -603,7 +611,7 @@ command:
.Bl -tag -width 2n
.It Sy autoexpand Ns = Ns Cm on No | Cm off
Controls automatic pool expansion when the underlying LUN is grown. If set to
.Qq Cm on Ns ,
.Qq Cm on ,
the pool will be resized according to the size of the expanded
device. If the device is part of a mirror or
.No raidz
@ -611,20 +619,20 @@ then all devices within that
.No mirror/ Ns No raidz
group must be expanded before the new space is made available to
the pool. The default behavior is
.Qq off Ns .
.Qq off .
This property can also be referred to by its shortened column name,
.Sy expand Ns .
.Sy expand .
.It Sy autoreplace Ns = Ns Cm on No | Cm off
Controls automatic device replacement. If set to
.Qq Cm off Ns ,
.Qq Cm off ,
device replacement must be initiated by the administrator by using the
.Qq Nm Cm replace
command. If set to
.Qq Cm on Ns ,
.Qq Cm on ,
any new device, found in the same
physical location as a device that previously belonged to the pool, is
automatically formatted and replaced. The default behavior is
.Qq Cm off Ns .
.Qq Cm off .
This property can also be referred to by its shortened column name, "replace".
.It Sy bootfs Ns = Ns Ar pool Ns / Ns Ar dataset
Identifies the default bootable dataset for the root pool. This property is
@ -647,7 +655,7 @@ creates a temporary pool that is never cached, and the special value
Threshold for the number of block ditto copies. If the reference count for a
deduplicated block increases above this number, a new ditto copy of this block
is automatically stored. Deafult setting is
.Cm 0 Ns .
.Cm 0 .
.It Sy delegation Ns = Ns Cm on No | Cm off
Controls whether a non-privileged user is granted access based on the dataset
permissions defined on the dataset. See
@ -691,7 +699,7 @@ decreased. The preferred method of updating pools is with the
command, though this property can be used when a specific version is needed
for backwards compatibility. This property can be any number between 1 and the
current version reported by
.Qo Ic zpool upgrade -v Qc Ns .
.Qo Ic zpool upgrade -v Qc .
.El
.Sh SUBCOMMANDS
All subcommands that modify state are logged persistently to the pool in their
@ -728,7 +736,7 @@ subcommand.
.Bl -tag -width indent
.It Fl f
Forces use of
.Ar vdev Ns ,
.Ar vdev ,
even if they appear in use or specify a conflicting replication level.
Not all devices can be overridden in this manner.
.It Fl n
@ -759,7 +767,8 @@ configuration. If
is not currently part of a mirrored configuration,
.Ar device
automatically transforms into a two-way mirror of
.Ar device No and Ar new_device Ns . If
.Ar device No and Ar new_device .
If
.Ar device
is part of a two-way mirror, attaching
.Ar new_device
@ -769,7 +778,7 @@ begins to resilver immediately.
.Bl -tag -width indent
.It Fl f
Forces use of
.Ar new_device Ns ,
.Ar new_device ,
even if its appears to be in use. Not all devices can be overridden in this
manner.
.El
@ -843,7 +852,7 @@ is specified.
Unless the
.Fl R
option is specified, the default mount point is
.Qq Pa /pool Ns .
.Qq Pa /pool .
The mount point must not exist or must be empty, or else the
root dataset cannot be mounted. This can be overridden with the
.Fl m
@ -887,9 +896,11 @@ or
if
.Sy altroot
is specified. The mount point must be an absolute path,
.Qq Cm legacy Ns , or Qq Cm none Ns .
.Qq Cm legacy ,
or
.Qq Cm none .
For more information on dataset mount points, see
.Xr zfs 8 Ns \&.
.Xr zfs 8 .
.El
.It Xo
.Nm
@ -997,7 +1008,7 @@ performed.
Lists pools available to import. If the
.Fl d
option is not specified, this command searches for devices in
.Qq Pa /dev Ns .
.Qq Pa /dev .
The
.Fl d
option can be specified multiple times, and all directories are searched. If
@ -1025,7 +1036,7 @@ pool property. This
is used instead of searching for devices.
.It Fl d Ar dir
Searches for devices or files in
.Ar dir Ns .
.Ar dir .
The
.Fl d
option can be specified multiple times.
@ -1075,7 +1086,7 @@ pool property. This
is used instead of searching for devices.
.It Fl d Ar dir
Searches for devices or files in
.Ar dir Ns .
.Ar dir .
The
.Fl d
option can be specified multiple times. This option is incompatible with the
@ -1138,7 +1149,7 @@ Imports a specific pool. A pool can be identified by its name or the numeric
identifier. If
.Ar newpool
is specified, the pool is imported using the name
.Ar newpool Ns .
.Ar newpool .
Otherwise, it is imported with the same name as its exported name.
.Pp
If a device is removed from a system without running
@ -1168,7 +1179,7 @@ pool property. This
is used instead of searching for devices.
.It Fl d Ar dir
Searches for devices or files in
.Ar dir Ns .
.Ar dir .
The
.Fl d
option can be specified multiple times. This option is incompatible with the
@ -1233,11 +1244,11 @@ Print a timestamp.
Use modifier
.Cm d
for standard date format. See
.Xr date 1 Ns .
.Xr date 1 .
Use modifier
.Cm u
for unixtime
.Pq equals Qq Ic date +%s Ns .
.Pq equals Qq Ic date +%s .
.It Fl v
Verbose statistics. Reports usage statistics for individual
.No vdev Ns s
@ -1253,7 +1264,7 @@ within the pool, in addition to the pool-wide statistics.
Removes
.Tn ZFS
label information from the specified
.Ar device Ns .
.Ar device .
The
.Ar device
must not be part of an active pool configuration.
@ -1292,24 +1303,24 @@ instead of arbitrary space.
Comma-separated list of properties to display. See the
.Qq Sx Properties
section for a list of valid properties. The default list is
.Sy name Ns ,
.Sy size Ns ,
.Sy used Ns ,
.Sy available Ns ,
.Sy capacity Ns ,
.Sy health Ns ,
.Sy altroot Ns .
.Sy name ,
.Sy size ,
.Sy used ,
.Sy available ,
.Sy capacity ,
.Sy health ,
.Sy altroot .
.It Fl T Cm d Ns | Ns Cm u
Print a timestamp.
.Pp
Use modifier
.Cm d
for standard date format. See
.Xr date 1 Ns .
.Xr date 1 .
Use modifier
.Cm u
for unixtime
.Pq equals Qq Ic date +%s Ns .
.Pq equals Qq Ic date +%s .
.El
.It Xo
.Nm
@ -1346,6 +1357,14 @@ available to the pool.
.El
.It Xo
.Nm
.Cm reguid
.Ar pool
.Xc
.Pp
Generates a new unique identifier for the pool. You must ensure that all
devices in this pool are online and healthy before performing this action.
.It Xo
.Nm
.Cm remove
.Ar pool device ...
.Xc
@ -1369,11 +1388,11 @@ devices cannot be removed from a pool.
Replaces
.Ar old_device
with
.Ar new_device Ns .
.Ar new_device .
This is equivalent to attaching
.Ar new_device Ns ,
.Ar new_device ,
waiting for it to resilver, and then detaching
.Ar old_device Ns .
.Ar old_device .
.Pp
The size of
.Ar new_device
@ -1386,7 +1405,7 @@ configuration.
is required if the pool is not redundant. If
.Ar new_device
is not specified, it defaults to
.Ar old_device Ns .
.Ar old_device .
This form of replacement is useful after an existing disk has failed and has
been physically replaced. In this case, the new disk may have the same
.Pa /dev
@ -1396,7 +1415,7 @@ recognizes this.
.Bl -tag -width indent
.It Fl f
Forces use of
.Ar new_device Ns ,
.Ar new_device ,
even if its appears to be in use. Not all devices can be overridden in this
manner.
.El
@ -1409,7 +1428,7 @@ manner.
.Pp
Begins a scrub. The scrub examines all data in the specified pools to verify
that it checksums correctly. For replicated (mirror or
.No raidz Ns )
.No raidz )
devices,
.Tn ZFS
automatically repairs any damage discovered during the scrub. The
@ -1554,11 +1573,11 @@ Print a timestamp.
Use modifier
.Cm d
for standard date format. See
.Xr date 1 Ns .
.Xr date 1 .
Use modifier
.Cm u
for unixtime
.Pq equals Qq Ic date +%s Ns .
.Pq equals Qq Ic date +%s .
.El
.It Xo
.Nm
@ -1638,7 +1657,7 @@ recommended, a pool based on files can be useful for experimental purposes.
.It Sy Example 5 No Adding a Mirror to a Tn ZFS No Storage Pool
.Pp
The following command adds two mirrored disks to the pool
.Em tank Ns ,
.Em tank ,
assuming the pool is already made up of two-way mirrors. The additional space
is immediately available to any datasets within the pool.
.Bd -literal -offset 2n
@ -1782,7 +1801,7 @@ subcommand as follows:
.It Sy Example 15 No Removing a Mirrored Log Device
.Pp
The following command removes the mirrored log device
.Em mirror-2 Ns .
.Em mirror-2 .
.Pp
Given this configuration:
.Bd -literal -offset 2n

View File

@ -22,6 +22,8 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright (c) 2011 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
#include <solaris.h>
@ -68,6 +70,8 @@ static int zpool_do_online(int, char **);
static int zpool_do_offline(int, char **);
static int zpool_do_clear(int, char **);
static int zpool_do_reguid(int, char **);
static int zpool_do_attach(int, char **);
static int zpool_do_detach(int, char **);
static int zpool_do_replace(int, char **);
@ -126,7 +130,8 @@ typedef enum {
HELP_UPGRADE,
HELP_GET,
HELP_SET,
HELP_SPLIT
HELP_SPLIT,
HELP_REGUID
} zpool_help_t;
@ -172,6 +177,7 @@ static zpool_command_t command_table[] = {
{ "import", zpool_do_import, HELP_IMPORT },
{ "export", zpool_do_export, HELP_EXPORT },
{ "upgrade", zpool_do_upgrade, HELP_UPGRADE },
{ "reguid", zpool_do_reguid, HELP_REGUID },
{ NULL },
{ "history", zpool_do_history, HELP_HISTORY },
{ "get", zpool_do_get, HELP_GET },
@ -251,6 +257,8 @@ get_usage(zpool_help_t idx) {
return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n"
"\t [-o property=value] <pool> <newpool> "
"[<device> ...]\n"));
case HELP_REGUID:
return (gettext("\treguid <pool>\n"));
}
abort();
@ -1454,6 +1462,7 @@ show_import(nvlist_t *config)
const char *health;
uint_t vsc;
int namewidth;
char *comment;
verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
&name) == 0);
@ -1470,9 +1479,9 @@ show_import(nvlist_t *config)
reason = zpool_import_status(config, &msgid);
(void) printf(gettext(" pool: %s\n"), name);
(void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
(void) printf(gettext(" state: %s"), health);
(void) printf(gettext(" pool: %s\n"), name);
(void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
(void) printf(gettext(" state: %s"), health);
if (pool_state == POOL_STATE_DESTROYED)
(void) printf(gettext(" (DESTROYED)"));
(void) printf("\n");
@ -1481,58 +1490,59 @@ show_import(nvlist_t *config)
case ZPOOL_STATUS_MISSING_DEV_R:
case ZPOOL_STATUS_MISSING_DEV_NR:
case ZPOOL_STATUS_BAD_GUID_SUM:
(void) printf(gettext("status: One or more devices are missing "
"from the system.\n"));
(void) printf(gettext(" status: One or more devices are "
"missing from the system.\n"));
break;
case ZPOOL_STATUS_CORRUPT_LABEL_R:
case ZPOOL_STATUS_CORRUPT_LABEL_NR:
(void) printf(gettext("status: One or more devices contains "
(void) printf(gettext(" status: One or more devices contains "
"corrupted data.\n"));
break;
case ZPOOL_STATUS_CORRUPT_DATA:
(void) printf(gettext("status: The pool data is corrupted.\n"));
(void) printf(
gettext(" status: The pool data is corrupted.\n"));
break;
case ZPOOL_STATUS_OFFLINE_DEV:
(void) printf(gettext("status: One or more devices "
(void) printf(gettext(" status: One or more devices "
"are offlined.\n"));
break;
case ZPOOL_STATUS_CORRUPT_POOL:
(void) printf(gettext("status: The pool metadata is "
(void) printf(gettext(" status: The pool metadata is "
"corrupted.\n"));
break;
case ZPOOL_STATUS_VERSION_OLDER:
(void) printf(gettext("status: The pool is formatted using an "
(void) printf(gettext(" status: The pool is formatted using an "
"older on-disk version.\n"));
break;
case ZPOOL_STATUS_VERSION_NEWER:
(void) printf(gettext("status: The pool is formatted using an "
(void) printf(gettext(" status: The pool is formatted using an "
"incompatible version.\n"));
break;
case ZPOOL_STATUS_HOSTID_MISMATCH:
(void) printf(gettext("status: The pool was last accessed by "
(void) printf(gettext(" status: The pool was last accessed by "
"another system.\n"));
break;
case ZPOOL_STATUS_FAULTED_DEV_R:
case ZPOOL_STATUS_FAULTED_DEV_NR:
(void) printf(gettext("status: One or more devices are "
(void) printf(gettext(" status: One or more devices are "
"faulted.\n"));
break;
case ZPOOL_STATUS_BAD_LOG:
(void) printf(gettext("status: An intent log record cannot be "
(void) printf(gettext(" status: An intent log record cannot be "
"read.\n"));
break;
case ZPOOL_STATUS_RESILVERING:
(void) printf(gettext("status: One or more devices were being "
(void) printf(gettext(" status: One or more devices were being "
"resilvered.\n"));
break;
@ -1548,26 +1558,26 @@ show_import(nvlist_t *config)
*/
if (vs->vs_state == VDEV_STATE_HEALTHY) {
if (reason == ZPOOL_STATUS_VERSION_OLDER)
(void) printf(gettext("action: The pool can be "
(void) printf(gettext(" action: The pool can be "
"imported using its name or numeric identifier, "
"though\n\tsome features will not be available "
"without an explicit 'zpool upgrade'.\n"));
else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
(void) printf(gettext("action: The pool can be "
(void) printf(gettext(" action: The pool can be "
"imported using its name or numeric "
"identifier and\n\tthe '-f' flag.\n"));
else
(void) printf(gettext("action: The pool can be "
(void) printf(gettext(" action: The pool can be "
"imported using its name or numeric "
"identifier.\n"));
} else if (vs->vs_state == VDEV_STATE_DEGRADED) {
(void) printf(gettext("action: The pool can be imported "
(void) printf(gettext(" action: The pool can be imported "
"despite missing or damaged devices. The\n\tfault "
"tolerance of the pool may be compromised if imported.\n"));
} else {
switch (reason) {
case ZPOOL_STATUS_VERSION_NEWER:
(void) printf(gettext("action: The pool cannot be "
(void) printf(gettext(" action: The pool cannot be "
"imported. Access the pool on a system running "
"newer\n\tsoftware, or recreate the pool from "
"backup.\n"));
@ -1575,16 +1585,20 @@ show_import(nvlist_t *config)
case ZPOOL_STATUS_MISSING_DEV_R:
case ZPOOL_STATUS_MISSING_DEV_NR:
case ZPOOL_STATUS_BAD_GUID_SUM:
(void) printf(gettext("action: The pool cannot be "
(void) printf(gettext(" action: The pool cannot be "
"imported. Attach the missing\n\tdevices and try "
"again.\n"));
break;
default:
(void) printf(gettext("action: The pool cannot be "
(void) printf(gettext(" action: The pool cannot be "
"imported due to damaged devices or data.\n"));
}
}
/* Print the comment attached to the pool. */
if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
(void) printf(gettext("comment: %s\n"), comment);
/*
* If the state is "closed" or "can't open", and the aux state
* is "corrupt data":
@ -1605,7 +1619,7 @@ show_import(nvlist_t *config)
(void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
msgid);
(void) printf(gettext("config:\n\n"));
(void) printf(gettext(" config:\n\n"));
namewidth = max_width(NULL, nvroot, 0, 0);
if (namewidth < 10)
@ -3320,6 +3334,52 @@ zpool_do_clear(int argc, char **argv)
return (ret);
}
/*
* zpool reguid <pool>
*/
int
zpool_do_reguid(int argc, char **argv)
{
int c;
char *poolname;
zpool_handle_t *zhp;
int ret = 0;
/* check options */
while ((c = getopt(argc, argv, "")) != -1) {
switch (c) {
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
usage(B_FALSE);
}
}
argc -= optind;
argv += optind;
/* get pool name and check number of arguments */
if (argc < 1) {
(void) fprintf(stderr, gettext("missing pool name\n"));
usage(B_FALSE);
}
if (argc > 1) {
(void) fprintf(stderr, gettext("too many arguments\n"));
usage(B_FALSE);
}
poolname = argv[0];
if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
return (1);
ret = zpool_reguid(zhp);
zpool_close(zhp);
return (ret);
}
typedef struct scrub_cbdata {
int cb_type;
int cb_argc;

View File

@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/*
@ -259,6 +260,7 @@ ztest_func_t ztest_vdev_LUN_growth;
ztest_func_t ztest_vdev_add_remove;
ztest_func_t ztest_vdev_aux_add_remove;
ztest_func_t ztest_split_pool;
ztest_func_t ztest_reguid;
uint64_t zopt_always = 0ULL * NANOSEC; /* all the time */
uint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */
@ -289,6 +291,7 @@ ztest_info_t ztest_info[] = {
{ ztest_fault_inject, 1, &zopt_sometimes },
{ ztest_ddt_repair, 1, &zopt_sometimes },
{ ztest_dmu_snapshot_hold, 1, &zopt_sometimes },
{ ztest_reguid, 1, &zopt_sometimes },
{ ztest_spa_rename, 1, &zopt_rarely },
{ ztest_scrub, 1, &zopt_rarely },
{ ztest_dsl_dataset_promote_busy, 1, &zopt_rarely },
@ -325,6 +328,7 @@ typedef struct ztest_shared {
uint64_t zs_vdev_aux;
uint64_t zs_alloc;
uint64_t zs_space;
uint64_t zs_guid;
mutex_t zs_vdev_lock;
rwlock_t zs_name_lock;
ztest_info_t zs_info[ZTEST_FUNCS];
@ -4646,7 +4650,7 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
object = od[0].od_object;
blocksize = od[0].od_blocksize;
pattern = spa_guid(spa) ^ dmu_objset_fsid_guid(os);
pattern = zs->zs_guid ^ dmu_objset_fsid_guid(os);
ASSERT(object != 0);
@ -4716,6 +4720,31 @@ ztest_scrub(ztest_ds_t *zd, uint64_t id)
(void) spa_scan(spa, POOL_SCAN_SCRUB);
}
/*
* Change the guid for the pool.
*/
/* ARGSUSED */
void
ztest_reguid(ztest_ds_t *zd, uint64_t id)
{
ztest_shared_t *zs = ztest_shared;
spa_t *spa = zs->zs_spa;
uint64_t orig, load;
orig = spa_guid(spa);
load = spa_load_guid(spa);
if (spa_change_guid(spa) != 0)
return;
if (zopt_verbose >= 3) {
(void) printf("Changed guid old %llu -> %llu\n",
(u_longlong_t)orig, (u_longlong_t)spa_guid(spa));
}
VERIFY3U(orig, !=, spa_guid(spa));
VERIFY3U(load, ==, spa_load_guid(spa));
}
/*
* Rename the pool to a different name and then rename it back.
*/
@ -5145,6 +5174,7 @@ ztest_run(ztest_shared_t *zs)
{
thread_t *tid;
spa_t *spa;
objset_t *os;
thread_t resume_tid;
int error;
@ -5176,6 +5206,10 @@ ztest_run(ztest_shared_t *zs)
spa->spa_debug = B_TRUE;
zs->zs_spa = spa;
VERIFY3U(0, ==, dmu_objset_hold(zs->zs_pool, FTAG, &os));
zs->zs_guid = dmu_objset_fsid_guid(os);
dmu_objset_rele(os, FTAG);
spa->spa_dedup_ditto = 2 * ZIO_DEDUPDITTO_MIN;
/*

View File

@ -21,8 +21,8 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* All rights reserved.
*/
@ -233,6 +233,7 @@ typedef struct splitflags {
*/
extern int zpool_scan(zpool_handle_t *, pool_scan_func_t);
extern int zpool_clear(zpool_handle_t *, const char *, nvlist_t *);
extern int zpool_reguid(zpool_handle_t *);
extern int zpool_vdev_online(zpool_handle_t *, const char *, int,
vdev_state_t *);
@ -384,6 +385,7 @@ extern void zpool_explain_recover(libzfs_handle_t *, const char *, int,
* underlying datasets, only the references to them.
*/
extern zfs_handle_t *zfs_open(libzfs_handle_t *, const char *, int);
extern zfs_handle_t *zfs_handle_dup(zfs_handle_t *);
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 *);
@ -417,12 +419,20 @@ extern int zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname,
uint64_t *propvalue);
extern int zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname,
char *propbuf, int proplen, boolean_t literal);
extern int zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname,
uint64_t *propvalue);
extern int zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
char *propbuf, int proplen, boolean_t literal);
extern int zfs_get_snapused_int(zfs_handle_t *firstsnap, zfs_handle_t *lastsnap,
uint64_t *usedp);
extern uint64_t zfs_prop_get_int(zfs_handle_t *, zfs_prop_t);
extern int zfs_prop_inherit(zfs_handle_t *, const char *, boolean_t);
extern const char *zfs_prop_values(zfs_prop_t);
extern int zfs_prop_is_string(zfs_prop_t prop);
extern nvlist_t *zfs_get_user_props(zfs_handle_t *);
extern nvlist_t *zfs_get_recvd_props(zfs_handle_t *);
extern nvlist_t *zfs_get_clones_nvl(zfs_handle_t *);
typedef struct zprop_list {
int pl_prop;
@ -497,6 +507,7 @@ extern int zfs_iter_dependents(zfs_handle_t *, boolean_t, zfs_iter_f, void *);
extern int zfs_iter_filesystems(zfs_handle_t *, zfs_iter_f, void *);
extern int zfs_iter_snapshots(zfs_handle_t *, zfs_iter_f, void *);
extern int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *);
extern int zfs_iter_snapspec(zfs_handle_t *, const char *, zfs_iter_f, void *);
typedef struct get_all_cb {
zfs_handle_t **cb_handles;
@ -517,6 +528,7 @@ extern int zfs_create(libzfs_handle_t *, const char *, zfs_type_t,
extern int zfs_create_ancestors(libzfs_handle_t *, const char *);
extern int zfs_destroy(zfs_handle_t *, boolean_t);
extern int zfs_destroy_snaps(zfs_handle_t *, char *, boolean_t);
extern int zfs_destroy_snaps_nvl(zfs_handle_t *, nvlist_t *, boolean_t);
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);
@ -533,29 +545,34 @@ extern int zfs_rename(zfs_handle_t *, const char *, renameflags_t flags);
typedef struct sendflags {
/* print informational messages (ie, -v was specified) */
int verbose : 1;
boolean_t verbose;
/* recursive send (ie, -R) */
int replicate : 1;
boolean_t replicate;
/* for incrementals, do all intermediate snapshots */
int doall : 1; /* (ie, -I) */
boolean_t doall;
/* if dataset is a clone, do incremental from its origin */
int fromorigin : 1;
boolean_t fromorigin;
/* do deduplication */
int dedup : 1;
boolean_t dedup;
/* send properties (ie, -p) */
int props : 1;
boolean_t props;
/* do not send (no-op, ie. -n) */
boolean_t dryrun;
/* parsable verbose output (ie. -P) */
boolean_t parsable;
} sendflags_t;
typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);
extern int zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
sendflags_t flags, int outfd, snapfilter_cb_t filter_func,
void *cb_arg, nvlist_t **debugnvp);
extern int zfs_send(zfs_handle_t *, const char *, const char *,
sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **);
extern int zfs_promote(zfs_handle_t *);
extern int zfs_hold(zfs_handle_t *, const char *, const char *, boolean_t,
@ -575,34 +592,34 @@ extern int zfs_set_fsacl(zfs_handle_t *, boolean_t, nvlist_t *);
typedef struct recvflags {
/* print informational messages (ie, -v was specified) */
int verbose : 1;
boolean_t verbose;
/* the destination is a prefix, not the exact fs (ie, -d) */
int isprefix : 1;
boolean_t isprefix;
/*
* Only the tail of the sent snapshot path is appended to the
* destination to determine the received snapshot name (ie, -e).
*/
int istail : 1;
boolean_t istail;
/* do not actually do the recv, just check if it would work (ie, -n) */
int dryrun : 1;
boolean_t dryrun;
/* rollback/destroy filesystems as necessary (eg, -F) */
int force : 1;
boolean_t force;
/* set "canmount=off" on all modified filesystems */
int canmountoff : 1;
boolean_t canmountoff;
/* byteswap flag is used internally; callers need not specify */
int byteswap : 1;
boolean_t byteswap;
/* do not mount file systems as they are extracted (private) */
int nomount : 1;
boolean_t nomount;
} recvflags_t;
extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t,
extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t *,
int, avl_tree_t *);
typedef enum diff_flags {

View File

@ -496,7 +496,7 @@ make_dataset_handle(libzfs_handle_t *hdl, const char *path)
return (zhp);
}
static zfs_handle_t *
zfs_handle_t *
make_dataset_handle_zc(libzfs_handle_t *hdl, zfs_cmd_t *zc)
{
zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
@ -513,6 +513,53 @@ make_dataset_handle_zc(libzfs_handle_t *hdl, zfs_cmd_t *zc)
return (zhp);
}
zfs_handle_t *
zfs_handle_dup(zfs_handle_t *zhp_orig)
{
zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
if (zhp == NULL)
return (NULL);
zhp->zfs_hdl = zhp_orig->zfs_hdl;
zhp->zpool_hdl = zhp_orig->zpool_hdl;
(void) strlcpy(zhp->zfs_name, zhp_orig->zfs_name,
sizeof (zhp->zfs_name));
zhp->zfs_type = zhp_orig->zfs_type;
zhp->zfs_head_type = zhp_orig->zfs_head_type;
zhp->zfs_dmustats = zhp_orig->zfs_dmustats;
if (zhp_orig->zfs_props != NULL) {
if (nvlist_dup(zhp_orig->zfs_props, &zhp->zfs_props, 0) != 0) {
(void) no_memory(zhp->zfs_hdl);
zfs_close(zhp);
return (NULL);
}
}
if (zhp_orig->zfs_user_props != NULL) {
if (nvlist_dup(zhp_orig->zfs_user_props,
&zhp->zfs_user_props, 0) != 0) {
(void) no_memory(zhp->zfs_hdl);
zfs_close(zhp);
return (NULL);
}
}
if (zhp_orig->zfs_recvd_props != NULL) {
if (nvlist_dup(zhp_orig->zfs_recvd_props,
&zhp->zfs_recvd_props, 0)) {
(void) no_memory(zhp->zfs_hdl);
zfs_close(zhp);
return (NULL);
}
}
zhp->zfs_mntcheck = zhp_orig->zfs_mntcheck;
if (zhp_orig->zfs_mntopts != NULL) {
zhp->zfs_mntopts = zfs_strdup(zhp_orig->zfs_hdl,
zhp_orig->zfs_mntopts);
}
zhp->zfs_props_table = zhp_orig->zfs_props_table;
return (zhp);
}
/*
* Opens the given snapshot, filesystem, or volume. The 'types'
* argument is a mask of acceptable types. The function will print an
@ -876,6 +923,12 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
goto error;
}
continue;
} else if (prop == ZPROP_INVAL && zfs_prop_written(propname)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' is readonly"),
propname);
(void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
goto error;
}
if (prop == ZPROP_INVAL) {
@ -1869,8 +1922,6 @@ zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf,
err = zfs_prop_get(zhp, prop, propbuf, proplen,
NULL, NULL, 0, literal);
zfs_unset_recvd_props_mode(zhp, &cookie);
} else if (zfs_prop_userquota(propname)) {
return (-1);
} else {
nvlist_t *propval;
char *recvdval;
@ -1885,6 +1936,120 @@ zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf,
return (err == 0 ? 0 : -1);
}
static int
get_clones_string(zfs_handle_t *zhp, char *propbuf, size_t proplen)
{
nvlist_t *value;
nvpair_t *pair;
value = zfs_get_clones_nvl(zhp);
if (value == NULL)
return (-1);
propbuf[0] = '\0';
for (pair = nvlist_next_nvpair(value, NULL); pair != NULL;
pair = nvlist_next_nvpair(value, pair)) {
if (propbuf[0] != '\0')
(void) strlcat(propbuf, ",", proplen);
(void) strlcat(propbuf, nvpair_name(pair), proplen);
}
return (0);
}
struct get_clones_arg {
uint64_t numclones;
nvlist_t *value;
const char *origin;
char buf[ZFS_MAXNAMELEN];
};
int
get_clones_cb(zfs_handle_t *zhp, void *arg)
{
struct get_clones_arg *gca = arg;
if (gca->numclones == 0) {
zfs_close(zhp);
return (0);
}
if (zfs_prop_get(zhp, ZFS_PROP_ORIGIN, gca->buf, sizeof (gca->buf),
NULL, NULL, 0, B_TRUE) != 0)
goto out;
if (strcmp(gca->buf, gca->origin) == 0) {
if (nvlist_add_boolean(gca->value, zfs_get_name(zhp)) != 0) {
zfs_close(zhp);
return (no_memory(zhp->zfs_hdl));
}
gca->numclones--;
}
out:
(void) zfs_iter_children(zhp, get_clones_cb, gca);
zfs_close(zhp);
return (0);
}
nvlist_t *
zfs_get_clones_nvl(zfs_handle_t *zhp)
{
nvlist_t *nv, *value;
if (nvlist_lookup_nvlist(zhp->zfs_props,
zfs_prop_to_name(ZFS_PROP_CLONES), &nv) != 0) {
struct get_clones_arg gca;
/*
* if this is a snapshot, then the kernel wasn't able
* to get the clones. Do it by slowly iterating.
*/
if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT)
return (NULL);
if (nvlist_alloc(&nv, NV_UNIQUE_NAME, 0) != 0)
return (NULL);
if (nvlist_alloc(&value, NV_UNIQUE_NAME, 0) != 0) {
nvlist_free(nv);
return (NULL);
}
gca.numclones = zfs_prop_get_int(zhp, ZFS_PROP_NUMCLONES);
gca.value = value;
gca.origin = zhp->zfs_name;
if (gca.numclones != 0) {
zfs_handle_t *root;
char pool[ZFS_MAXNAMELEN];
char *cp = pool;
/* get the pool name */
(void) strlcpy(pool, zhp->zfs_name, sizeof (pool));
(void) strsep(&cp, "/@");
root = zfs_open(zhp->zfs_hdl, pool,
ZFS_TYPE_FILESYSTEM);
(void) get_clones_cb(root, &gca);
}
if (gca.numclones != 0 ||
nvlist_add_nvlist(nv, ZPROP_VALUE, value) != 0 ||
nvlist_add_nvlist(zhp->zfs_props,
zfs_prop_to_name(ZFS_PROP_CLONES), nv) != 0) {
nvlist_free(nv);
nvlist_free(value);
return (NULL);
}
nvlist_free(nv);
nvlist_free(value);
verify(0 == nvlist_lookup_nvlist(zhp->zfs_props,
zfs_prop_to_name(ZFS_PROP_CLONES), &nv));
}
verify(nvlist_lookup_nvlist(nv, ZPROP_VALUE, &value) == 0);
return (value);
}
/*
* Retrieve a property from the given object. If 'literal' is specified, then
* numbers are left as exact values. Otherwise, numbers are converted to a
@ -2013,6 +2178,11 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
return (-1);
break;
case ZFS_PROP_CLONES:
if (get_clones_string(zhp, propbuf, proplen) != 0)
return (-1);
break;
case ZFS_PROP_QUOTA:
case ZFS_PROP_REFQUOTA:
case ZFS_PROP_RESERVATION:
@ -2385,7 +2555,7 @@ zfs_prop_get_userquota_common(zfs_handle_t *zhp, const char *propname,
int err;
zfs_cmd_t zc = { 0 };
(void) strncpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
err = userquota_propname_decode(propname,
zfs_prop_get_int(zhp, ZFS_PROP_ZONED),
@ -2437,6 +2607,79 @@ zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname,
return (0);
}
int
zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname,
uint64_t *propvalue)
{
int err;
zfs_cmd_t zc = { 0 };
const char *snapname;
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
snapname = strchr(propname, '@') + 1;
if (strchr(snapname, '@')) {
(void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
} else {
/* snapname is the short name, append it to zhp's fsname */
char *cp;
(void) strlcpy(zc.zc_value, zhp->zfs_name,
sizeof (zc.zc_value));
cp = strchr(zc.zc_value, '@');
if (cp != NULL)
*cp = '\0';
(void) strlcat(zc.zc_value, "@", sizeof (zc.zc_value));
(void) strlcat(zc.zc_value, snapname, sizeof (zc.zc_value));
}
err = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SPACE_WRITTEN, &zc);
if (err)
return (err);
*propvalue = zc.zc_cookie;
return (0);
}
int
zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
char *propbuf, int proplen, boolean_t literal)
{
int err;
uint64_t propvalue;
err = zfs_prop_get_written_int(zhp, propname, &propvalue);
if (err)
return (err);
if (literal) {
(void) snprintf(propbuf, proplen, "%llu", propvalue);
} else {
zfs_nicenum(propvalue, propbuf, proplen);
}
return (0);
}
int
zfs_get_snapused_int(zfs_handle_t *firstsnap, zfs_handle_t *lastsnap,
uint64_t *usedp)
{
int err;
zfs_cmd_t zc = { 0 };
(void) strlcpy(zc.zc_name, lastsnap->zfs_name, sizeof (zc.zc_name));
(void) strlcpy(zc.zc_value, firstsnap->zfs_name, sizeof (zc.zc_value));
err = ioctl(lastsnap->zfs_hdl->libzfs_fd, ZFS_IOC_SPACE_SNAPS, &zc);
if (err)
return (err);
*usedp = zc.zc_cookie;
return (0);
}
/*
* Returns the name of the given zfs handle.
*/
@ -2455,128 +2698,6 @@ zfs_get_type(const zfs_handle_t *zhp)
return (zhp->zfs_type);
}
static int
zfs_do_list_ioctl(zfs_handle_t *zhp, unsigned long arg, zfs_cmd_t *zc)
{
int rc;
uint64_t orig_cookie;
orig_cookie = zc->zc_cookie;
top:
(void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name));
rc = ioctl(zhp->zfs_hdl->libzfs_fd, arg, zc);
if (rc == -1) {
switch (errno) {
case ENOMEM:
/* expand nvlist memory and try again */
if (zcmd_expand_dst_nvlist(zhp->zfs_hdl, zc) != 0) {
zcmd_free_nvlists(zc);
return (-1);
}
zc->zc_cookie = orig_cookie;
goto top;
/*
* An errno value of ESRCH indicates normal completion.
* If ENOENT is returned, then the underlying dataset
* has been removed since we obtained the handle.
*/
case ESRCH:
case ENOENT:
rc = 1;
break;
default:
rc = zfs_standard_error(zhp->zfs_hdl, errno,
dgettext(TEXT_DOMAIN,
"cannot iterate filesystems"));
break;
}
}
return (rc);
}
/*
* Iterate over all child filesystems
*/
int
zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
{
zfs_cmd_t zc = { 0 };
zfs_handle_t *nzhp;
int ret;
if (zhp->zfs_type != ZFS_TYPE_FILESYSTEM)
return (0);
if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
return (-1);
while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_DATASET_LIST_NEXT,
&zc)) == 0) {
/*
* Silently ignore errors, as the only plausible explanation is
* that the pool has since been removed.
*/
if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl,
&zc)) == NULL) {
continue;
}
if ((ret = func(nzhp, data)) != 0) {
zcmd_free_nvlists(&zc);
return (ret);
}
}
zcmd_free_nvlists(&zc);
return ((ret < 0) ? ret : 0);
}
/*
* Iterate over all snapshots
*/
int
zfs_iter_snapshots(zfs_handle_t *zhp, zfs_iter_f func, void *data)
{
zfs_cmd_t zc = { 0 };
zfs_handle_t *nzhp;
int ret;
if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
return (0);
if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
return (-1);
while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_SNAPSHOT_LIST_NEXT,
&zc)) == 0) {
if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl,
&zc)) == NULL) {
continue;
}
if ((ret = func(nzhp, data)) != 0) {
zcmd_free_nvlists(&zc);
return (ret);
}
}
zcmd_free_nvlists(&zc);
return ((ret < 0) ? ret : 0);
}
/*
* Iterate over all children, snapshots and filesystems
*/
int
zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
{
int ret;
if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0)
return (ret);
return (zfs_iter_snapshots(zhp, func, data));
}
/*
* Is one dataset name a child dataset of another?
*
@ -2600,18 +2721,19 @@ is_descendant(const char *ds1, const char *ds2)
/*
* Given a complete name, return just the portion that refers to the parent.
* Can return NULL if this is a pool.
* Will return -1 if there is no parent (path is just the name of the
* pool).
*/
static int
parent_name(const char *path, char *buf, size_t buflen)
{
char *loc;
char *slashp;
if ((loc = strrchr(path, '/')) == NULL)
(void) strlcpy(buf, path, buflen);
if ((slashp = strrchr(buf, '/')) == NULL)
return (-1);
(void) strncpy(buf, path, MIN(buflen, loc - path));
buf[loc - path] = '\0';
*slashp = '\0';
return (0);
}
@ -3010,9 +3132,8 @@ zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
}
struct destroydata {
char *snapname;
boolean_t gotone;
boolean_t closezhp;
nvlist_t *nvl;
const char *snapname;
};
static int
@ -3021,24 +3142,19 @@ zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
struct destroydata *dd = arg;
zfs_handle_t *szhp;
char name[ZFS_MAXNAMELEN];
boolean_t closezhp = dd->closezhp;
int rv = 0;
(void) strlcpy(name, zhp->zfs_name, sizeof (name));
(void) strlcat(name, "@", sizeof (name));
(void) strlcat(name, dd->snapname, sizeof (name));
(void) snprintf(name, sizeof (name),
"%s@%s", zhp->zfs_name, dd->snapname);
szhp = make_dataset_handle(zhp->zfs_hdl, name);
if (szhp) {
dd->gotone = B_TRUE;
verify(nvlist_add_boolean(dd->nvl, name) == 0);
zfs_close(szhp);
}
dd->closezhp = B_TRUE;
if (!dd->gotone)
rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, arg);
if (closezhp)
zfs_close(zhp);
rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, dd);
zfs_close(zhp);
return (rv);
}
@ -3048,29 +3164,45 @@ zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
int
zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
{
zfs_cmd_t zc = { 0 };
int ret;
struct destroydata dd = { 0 };
dd.snapname = snapname;
(void) zfs_check_snap_cb(zhp, &dd);
verify(nvlist_alloc(&dd.nvl, NV_UNIQUE_NAME, 0) == 0);
(void) zfs_check_snap_cb(zfs_handle_dup(zhp), &dd);
if (!dd.gotone) {
return (zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
if (nvlist_next_nvpair(dd.nvl, NULL) == NULL) {
ret = zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
zhp->zfs_name, snapname));
zhp->zfs_name, snapname);
} else {
ret = zfs_destroy_snaps_nvl(zhp, dd.nvl, defer);
}
nvlist_free(dd.nvl);
return (ret);
}
/*
* Destroys all the snapshots named in the nvlist. They must be underneath
* the zhp (either snapshots of it, or snapshots of its descendants).
*/
int
zfs_destroy_snaps_nvl(zfs_handle_t *zhp, nvlist_t *snaps, boolean_t defer)
{
int ret;
zfs_cmd_t zc = { 0 };
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
(void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
if (zcmd_write_src_nvlist(zhp->zfs_hdl, &zc, snaps) != 0)
return (-1);
zc.zc_defer_destroy = defer;
ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY_SNAPS, &zc);
ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY_SNAPS_NVL, &zc);
if (ret != 0) {
char errbuf[1024];
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"cannot destroy '%s@%s'"), zc.zc_name, snapname);
"cannot destroy snapshots in %s"), zc.zc_name);
switch (errno) {
case EEXIST:
@ -3106,7 +3238,7 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"cannot create '%s'"), target);
/* validate the target name */
/* validate the target/clone name */
if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE))
return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
@ -3442,42 +3574,6 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
return (err);
}
/*
* Iterate over all dependents for a given dataset. This includes both
* hierarchical dependents (children) and data dependents (snapshots and
* clones). The bulk of the processing occurs in get_dependents() in
* libzfs_graph.c.
*/
int
zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion,
zfs_iter_f func, void *data)
{
char **dependents;
size_t count;
int i;
zfs_handle_t *child;
int ret = 0;
if (get_dependents(zhp->zfs_hdl, allowrecursion, zhp->zfs_name,
&dependents, &count) != 0)
return (-1);
for (i = 0; i < count; i++) {
if ((child = make_dataset_handle(zhp->zfs_hdl,
dependents[i])) == NULL)
continue;
if ((ret = func(child, data)) != 0)
break;
}
for (i = 0; i < count; i++)
free(dependents[i]);
free(dependents);
return (ret);
}
/*
* Renames the given dataset.
*/
@ -3947,7 +4043,7 @@ zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
int error;
zfs_useracct_t buf[100];
(void) strncpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
zc.zc_objset_type = type;
zc.zc_nvlist_dst = (uintptr_t)buf;

View File

@ -1,653 +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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Iterate over all children of the current object. This includes the normal
* dataset hierarchy, but also arbitrary hierarchies due to clones. We want to
* walk all datasets in the pool, and construct a directed graph of the form:
*
* home
* |
* +----+----+
* | |
* v v ws
* bar baz |
* | |
* v v
* @yesterday ----> foo
*
* In order to construct this graph, we have to walk every dataset in the pool,
* because the clone parent is stored as a property of the child, not the
* parent. The parent only keeps track of the number of clones.
*
* In the normal case (without clones) this would be rather expensive. To avoid
* unnecessary computation, we first try a walk of the subtree hierarchy
* starting from the initial node. At each dataset, we construct a node in the
* graph and an edge leading from its parent. If we don't see any snapshots
* with a non-zero clone count, then we are finished.
*
* If we do find a cloned snapshot, then we finish the walk of the current
* subtree, but indicate that we need to do a complete walk. We then perform a
* global walk of all datasets, avoiding the subtree we already processed.
*
* At the end of this, we'll end up with a directed graph of all relevant (and
* possible some irrelevant) datasets in the system. We need to both find our
* limiting subgraph and determine a safe ordering in which to destroy the
* datasets. We do a topological ordering of our graph starting at our target
* dataset, and then walk the results in reverse.
*
* It's possible for the graph to have cycles if, for example, the user renames
* a clone to be the parent of its origin snapshot. The user can request to
* generate an error in this case, or ignore the cycle and continue.
*
* When removing datasets, we want to destroy the snapshots in chronological
* order (because this is the most efficient method). In order to accomplish
* this, we store the creation transaction group with each vertex and keep each
* vertex's edges sorted according to this value. The topological sort will
* automatically walk the snapshots in the correct order.
*/
#include <assert.h>
#include <libintl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <libzfs.h>
#include "libzfs_impl.h"
#include "zfs_namecheck.h"
#define MIN_EDGECOUNT 4
/*
* Vertex structure. Indexed by dataset name, this structure maintains a list
* of edges to other vertices.
*/
struct zfs_edge;
typedef struct zfs_vertex {
char zv_dataset[ZFS_MAXNAMELEN];
struct zfs_vertex *zv_next;
int zv_visited;
uint64_t zv_txg;
struct zfs_edge **zv_edges;
int zv_edgecount;
int zv_edgealloc;
} zfs_vertex_t;
enum {
VISIT_SEEN = 1,
VISIT_SORT_PRE,
VISIT_SORT_POST
};
/*
* Edge structure. Simply maintains a pointer to the destination vertex. There
* is no need to store the source vertex, since we only use edges in the context
* of the source vertex.
*/
typedef struct zfs_edge {
zfs_vertex_t *ze_dest;
struct zfs_edge *ze_next;
} zfs_edge_t;
#define ZFS_GRAPH_SIZE 1027 /* this could be dynamic some day */
/*
* Graph structure. Vertices are maintained in a hash indexed by dataset name.
*/
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;
/*
* Allocate a new edge pointing to the target vertex.
*/
static zfs_edge_t *
zfs_edge_create(libzfs_handle_t *hdl, zfs_vertex_t *dest)
{
zfs_edge_t *zep = zfs_alloc(hdl, sizeof (zfs_edge_t));
if (zep == NULL)
return (NULL);
zep->ze_dest = dest;
return (zep);
}
/*
* Destroy an edge.
*/
static void
zfs_edge_destroy(zfs_edge_t *zep)
{
free(zep);
}
/*
* Allocate a new vertex with the given name.
*/
static zfs_vertex_t *
zfs_vertex_create(libzfs_handle_t *hdl, const char *dataset)
{
zfs_vertex_t *zvp = zfs_alloc(hdl, sizeof (zfs_vertex_t));
if (zvp == NULL)
return (NULL);
assert(strlen(dataset) < ZFS_MAXNAMELEN);
(void) strlcpy(zvp->zv_dataset, dataset, sizeof (zvp->zv_dataset));
if ((zvp->zv_edges = zfs_alloc(hdl,
MIN_EDGECOUNT * sizeof (void *))) == NULL) {
free(zvp);
return (NULL);
}
zvp->zv_edgealloc = MIN_EDGECOUNT;
return (zvp);
}
/*
* Destroy a vertex. Frees up any associated edges.
*/
static void
zfs_vertex_destroy(zfs_vertex_t *zvp)
{
int i;
for (i = 0; i < zvp->zv_edgecount; i++)
zfs_edge_destroy(zvp->zv_edges[i]);
free(zvp->zv_edges);
free(zvp);
}
/*
* Given a vertex, add an edge to the destination vertex.
*/
static int
zfs_vertex_add_edge(libzfs_handle_t *hdl, zfs_vertex_t *zvp,
zfs_vertex_t *dest)
{
zfs_edge_t *zep = zfs_edge_create(hdl, dest);
if (zep == NULL)
return (-1);
if (zvp->zv_edgecount == zvp->zv_edgealloc) {
void *ptr;
if ((ptr = zfs_realloc(hdl, zvp->zv_edges,
zvp->zv_edgealloc * sizeof (void *),
zvp->zv_edgealloc * 2 * sizeof (void *))) == NULL)
return (-1);
zvp->zv_edges = ptr;
zvp->zv_edgealloc *= 2;
}
zvp->zv_edges[zvp->zv_edgecount++] = zep;
return (0);
}
static int
zfs_edge_compare(const void *a, const void *b)
{
const zfs_edge_t *ea = *((zfs_edge_t **)a);
const zfs_edge_t *eb = *((zfs_edge_t **)b);
if (ea->ze_dest->zv_txg < eb->ze_dest->zv_txg)
return (-1);
if (ea->ze_dest->zv_txg > eb->ze_dest->zv_txg)
return (1);
return (0);
}
/*
* Sort the given vertex edges according to the creation txg of each vertex.
*/
static void
zfs_vertex_sort_edges(zfs_vertex_t *zvp)
{
if (zvp->zv_edgecount == 0)
return;
qsort(zvp->zv_edges, zvp->zv_edgecount, sizeof (void *),
zfs_edge_compare);
}
/*
* Construct a new graph object. We allow the size to be specified as a
* parameter so in the future we can size the hash according to the number of
* datasets in the pool.
*/
static zfs_graph_t *
zfs_graph_create(libzfs_handle_t *hdl, const char *dataset, size_t size)
{
zfs_graph_t *zgp = zfs_alloc(hdl, sizeof (zfs_graph_t));
if (zgp == NULL)
return (NULL);
zgp->zg_size = size;
if ((zgp->zg_hash = zfs_alloc(hdl,
size * sizeof (zfs_vertex_t *))) == NULL) {
free(zgp);
return (NULL);
}
zgp->zg_root = dataset;
zgp->zg_clone_count = 0;
return (zgp);
}
/*
* Destroy a graph object. We have to iterate over all the hash chains,
* destroying each vertex in the process.
*/
static void
zfs_graph_destroy(zfs_graph_t *zgp)
{
int i;
zfs_vertex_t *current, *next;
for (i = 0; i < zgp->zg_size; i++) {
current = zgp->zg_hash[i];
while (current != NULL) {
next = current->zv_next;
zfs_vertex_destroy(current);
current = next;
}
}
free(zgp->zg_hash);
free(zgp);
}
/*
* Graph hash function. Classic bernstein k=33 hash function, taken from
* usr/src/cmd/sgs/tools/common/strhash.c
*/
static size_t
zfs_graph_hash(zfs_graph_t *zgp, const char *str)
{
size_t hash = 5381;
int c;
while ((c = *str++) != 0)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return (hash % zgp->zg_size);
}
/*
* Given a dataset name, finds the associated vertex, creating it if necessary.
*/
static zfs_vertex_t *
zfs_graph_lookup(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset,
uint64_t txg)
{
size_t idx = zfs_graph_hash(zgp, dataset);
zfs_vertex_t *zvp;
for (zvp = zgp->zg_hash[idx]; zvp != NULL; zvp = zvp->zv_next) {
if (strcmp(zvp->zv_dataset, dataset) == 0) {
if (zvp->zv_txg == 0)
zvp->zv_txg = txg;
return (zvp);
}
}
if ((zvp = zfs_vertex_create(hdl, dataset)) == NULL)
return (NULL);
zvp->zv_next = zgp->zg_hash[idx];
zvp->zv_txg = txg;
zgp->zg_hash[idx] = zvp;
zgp->zg_nvertex++;
return (zvp);
}
/*
* Given two dataset names, create an edge between them. For the source vertex,
* mark 'zv_visited' to indicate that we have seen this vertex, and not simply
* created it as a destination of another edge. If 'dest' is NULL, then this
* is an individual vertex (i.e. the starting vertex), so don't add an edge.
*/
static int
zfs_graph_add(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *source,
const char *dest, uint64_t txg)
{
zfs_vertex_t *svp, *dvp;
if ((svp = zfs_graph_lookup(hdl, zgp, source, 0)) == NULL)
return (-1);
svp->zv_visited = VISIT_SEEN;
if (dest != NULL) {
dvp = zfs_graph_lookup(hdl, zgp, dest, txg);
if (dvp == NULL)
return (-1);
if (zfs_vertex_add_edge(hdl, svp, dvp) != 0)
return (-1);
}
return (0);
}
/*
* 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().
*/
static int
iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
{
zfs_cmd_t zc = { 0 };
zfs_vertex_t *zvp;
/*
* Look up the source vertex, and avoid it if we've seen it before.
*/
zvp = zfs_graph_lookup(hdl, zgp, dataset, 0);
if (zvp == NULL)
return (-1);
if (zvp->zv_visited == VISIT_SEEN)
return (0);
/*
* Iterate over all children
*/
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))) {
/*
* Get statistics for this dataset, to determine the type of the
* 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.
*/
if (zfs_graph_add(hdl, zgp, dataset, zc.zc_name,
zc.zc_objset_stats.dds_creation_txg) != 0)
return (-1);
/*
* Recursively visit child
*/
if (iterate_children(hdl, zgp, zc.zc_name))
return (-1);
}
/*
* Now iterate over all snapshots.
*/
bzero(&zc, sizeof (zc));
for ((void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
ioctl(hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT, &zc) == 0;
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name))) {
/*
* Get statistics for this dataset, to determine the type of the
* dataset and clone statistics. If this fails, the dataset has
* since been removed, and we're pretty much screwed anyway.
*/
if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0)
continue;
/*
* Add an edge between the parent and the child.
*/
if (zfs_graph_add(hdl, zgp, dataset, zc.zc_name,
zc.zc_objset_stats.dds_creation_txg) != 0)
return (-1);
zgp->zg_clone_count += zc.zc_objset_stats.dds_num_clones;
}
zvp->zv_visited = VISIT_SEEN;
return (0);
}
/*
* 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.
*/
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);
int ret = 0;
if (zgp == NULL)
return (zgp);
if ((strchr(dataset, '/') == NULL) ||
(external_dependents(hdl, zgp, dataset))) {
/*
* Determine pool name and try again.
*/
int len = strcspn(dataset, "/@") + 1;
char *pool = zfs_alloc(hdl, len);
if (pool == NULL) {
zfs_graph_destroy(zgp);
return (NULL);
}
(void) strlcpy(pool, dataset, len);
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) {
zfs_graph_destroy(zgp);
return (NULL);
}
return (zgp);
}
/*
* Given a graph, do a recursive topological sort into the given array. This is
* really just a depth first search, so that the deepest nodes appear first.
* hijack the 'zv_visited' marker to avoid visiting the same vertex twice.
*/
static int
topo_sort(libzfs_handle_t *hdl, boolean_t allowrecursion, char **result,
size_t *idx, zfs_vertex_t *zgv)
{
int i;
if (zgv->zv_visited == VISIT_SORT_PRE && !allowrecursion) {
/*
* If we've already seen this vertex as part of our depth-first
* search, then we have a cyclic dependency, and we must return
* an error.
*/
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"recursive dependency at '%s'"),
zgv->zv_dataset);
return (zfs_error(hdl, EZFS_RECURSIVE,
dgettext(TEXT_DOMAIN,
"cannot determine dependent datasets")));
} else if (zgv->zv_visited >= VISIT_SORT_PRE) {
/*
* If we've already processed this as part of the topological
* sort, then don't bother doing so again.
*/
return (0);
}
zgv->zv_visited = VISIT_SORT_PRE;
/* avoid doing a search if we don't have to */
zfs_vertex_sort_edges(zgv);
for (i = 0; i < zgv->zv_edgecount; i++) {
if (topo_sort(hdl, allowrecursion, result, idx,
zgv->zv_edges[i]->ze_dest) != 0)
return (-1);
}
/* we may have visited this in the course of the above */
if (zgv->zv_visited == VISIT_SORT_POST)
return (0);
if ((result[*idx] = zfs_alloc(hdl,
strlen(zgv->zv_dataset) + 1)) == NULL)
return (-1);
(void) strcpy(result[*idx], zgv->zv_dataset);
*idx += 1;
zgv->zv_visited = VISIT_SORT_POST;
return (0);
}
/*
* The only public interface for this file. Do the dirty work of constructing a
* child list for the given object. Construct the graph, do the toplogical
* sort, and then return the array of strings to the caller.
*
* The 'allowrecursion' parameter controls behavior when cycles are found. If
* it is set, the the cycle is ignored and the results returned as if the cycle
* did not exist. If it is not set, then the routine will generate an error if
* a cycle is found.
*/
int
get_dependents(libzfs_handle_t *hdl, boolean_t allowrecursion,
const char *dataset, char ***result, size_t *count)
{
zfs_graph_t *zgp;
zfs_vertex_t *zvp;
if ((zgp = construct_graph(hdl, dataset)) == NULL)
return (-1);
if ((*result = zfs_alloc(hdl,
zgp->zg_nvertex * sizeof (char *))) == NULL) {
zfs_graph_destroy(zgp);
return (-1);
}
if ((zvp = zfs_graph_lookup(hdl, zgp, dataset, 0)) == NULL) {
free(*result);
zfs_graph_destroy(zgp);
return (-1);
}
*count = 0;
if (topo_sort(hdl, allowrecursion, *result, count, zvp) != 0) {
free(*result);
zfs_graph_destroy(zgp);
return (-1);
}
/*
* Get rid of the last entry, which is our starting vertex and not
* strictly a dependent.
*/
assert(*count > 0);
free((*result)[*count - 1]);
(*count)--;
zfs_graph_destroy(zgp);
return (0);
}

View File

@ -23,6 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#ifndef _LIBFS_IMPL_H
@ -116,7 +117,7 @@ struct zpool_handle {
diskaddr_t zpool_start_block;
};
typedef enum {
typedef enum {
PROTO_NFS = 0,
PROTO_SMB = 1,
PROTO_END = 2
@ -148,6 +149,7 @@ int zpool_standard_error_fmt(libzfs_handle_t *, int, const char *, ...);
int get_dependents(libzfs_handle_t *, boolean_t, const char *, char ***,
size_t *);
zfs_handle_t *make_dataset_handle_zc(libzfs_handle_t *, zfs_cmd_t *);
int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t,

View File

@ -20,6 +20,8 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
/*
@ -435,7 +437,7 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
uint_t i, nspares, nl2cache;
boolean_t config_seen;
uint64_t best_txg;
char *name, *hostname;
char *name, *hostname, *comment;
uint64_t version, guid;
uint_t children = 0;
nvlist_t **child = NULL;
@ -524,6 +526,7 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
* version
* pool guid
* name
* comment (if available)
* pool state
* hostid (if available)
* hostname (if available)
@ -545,11 +548,24 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
if (nvlist_add_string(config,
ZPOOL_CONFIG_POOL_NAME, name) != 0)
goto nomem;
/*
* COMMENT is optional, don't bail if it's not
* there, instead, set it to NULL.
*/
if (nvlist_lookup_string(tmp,
ZPOOL_CONFIG_COMMENT, &comment) != 0)
comment = NULL;
else if (nvlist_add_string(config,
ZPOOL_CONFIG_COMMENT, comment) != 0)
goto nomem;
verify(nvlist_lookup_uint64(tmp,
ZPOOL_CONFIG_POOL_STATE, &state) == 0);
if (nvlist_add_uint64(config,
ZPOOL_CONFIG_POOL_STATE, state) != 0)
goto nomem;
hostid = 0;
if (nvlist_lookup_uint64(tmp,
ZPOOL_CONFIG_HOSTID, &hostid) == 0) {

View File

@ -0,0 +1,462 @@
/*
* 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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <stddef.h>
#include <libintl.h>
#include <libzfs.h>
#include "libzfs_impl.h"
int
zfs_iter_clones(zfs_handle_t *zhp, zfs_iter_f func, void *data)
{
nvlist_t *nvl = zfs_get_clones_nvl(zhp);
nvpair_t *pair;
if (nvl == NULL)
return (0);
for (pair = nvlist_next_nvpair(nvl, NULL); pair != NULL;
pair = nvlist_next_nvpair(nvl, pair)) {
zfs_handle_t *clone = zfs_open(zhp->zfs_hdl, nvpair_name(pair),
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
if (clone != NULL) {
int err = func(clone, data);
if (err != 0)
return (err);
}
}
return (0);
}
static int
zfs_do_list_ioctl(zfs_handle_t *zhp, unsigned long arg, zfs_cmd_t *zc)
{
int rc;
uint64_t orig_cookie;
orig_cookie = zc->zc_cookie;
top:
(void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name));
rc = ioctl(zhp->zfs_hdl->libzfs_fd, arg, zc);
if (rc == -1) {
switch (errno) {
case ENOMEM:
/* expand nvlist memory and try again */
if (zcmd_expand_dst_nvlist(zhp->zfs_hdl, zc) != 0) {
zcmd_free_nvlists(zc);
return (-1);
}
zc->zc_cookie = orig_cookie;
goto top;
/*
* An errno value of ESRCH indicates normal completion.
* If ENOENT is returned, then the underlying dataset
* has been removed since we obtained the handle.
*/
case ESRCH:
case ENOENT:
rc = 1;
break;
default:
rc = zfs_standard_error(zhp->zfs_hdl, errno,
dgettext(TEXT_DOMAIN,
"cannot iterate filesystems"));
break;
}
}
return (rc);
}
/*
* Iterate over all child filesystems
*/
int
zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
{
zfs_cmd_t zc = { 0 };
zfs_handle_t *nzhp;
int ret;
if (zhp->zfs_type != ZFS_TYPE_FILESYSTEM)
return (0);
if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
return (-1);
while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_DATASET_LIST_NEXT,
&zc)) == 0) {
/*
* Silently ignore errors, as the only plausible explanation is
* that the pool has since been removed.
*/
if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl,
&zc)) == NULL) {
continue;
}
if ((ret = func(nzhp, data)) != 0) {
zcmd_free_nvlists(&zc);
return (ret);
}
}
zcmd_free_nvlists(&zc);
return ((ret < 0) ? ret : 0);
}
/*
* Iterate over all snapshots
*/
int
zfs_iter_snapshots(zfs_handle_t *zhp, zfs_iter_f func, void *data)
{
zfs_cmd_t zc = { 0 };
zfs_handle_t *nzhp;
int ret;
if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
return (0);
if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
return (-1);
while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_SNAPSHOT_LIST_NEXT,
&zc)) == 0) {
if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl,
&zc)) == NULL) {
continue;
}
if ((ret = func(nzhp, data)) != 0) {
zcmd_free_nvlists(&zc);
return (ret);
}
}
zcmd_free_nvlists(&zc);
return ((ret < 0) ? ret : 0);
}
/*
* Routines for dealing with the sorted snapshot functionality
*/
typedef struct zfs_node {
zfs_handle_t *zn_handle;
avl_node_t zn_avlnode;
} zfs_node_t;
static int
zfs_sort_snaps(zfs_handle_t *zhp, void *data)
{
avl_tree_t *avl = data;
zfs_node_t *node;
zfs_node_t search;
search.zn_handle = zhp;
node = avl_find(avl, &search, NULL);
if (node) {
/*
* If this snapshot was renamed while we were creating the
* AVL tree, it's possible that we already inserted it under
* its old name. Remove the old handle before adding the new
* one.
*/
zfs_close(node->zn_handle);
avl_remove(avl, node);
free(node);
}
node = zfs_alloc(zhp->zfs_hdl, sizeof (zfs_node_t));
node->zn_handle = zhp;
avl_add(avl, node);
return (0);
}
static int
zfs_snapshot_compare(const void *larg, const void *rarg)
{
zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
uint64_t lcreate, rcreate;
/*
* Sort them according to creation time. We use the hidden
* CREATETXG property to get an absolute ordering of snapshots.
*/
lcreate = zfs_prop_get_int(l, ZFS_PROP_CREATETXG);
rcreate = zfs_prop_get_int(r, ZFS_PROP_CREATETXG);
if (lcreate < rcreate)
return (-1);
else if (lcreate > rcreate)
return (+1);
else
return (0);
}
int
zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback, void *data)
{
int ret = 0;
zfs_node_t *node;
avl_tree_t avl;
void *cookie = NULL;
avl_create(&avl, zfs_snapshot_compare,
sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode));
ret = zfs_iter_snapshots(zhp, zfs_sort_snaps, &avl);
for (node = avl_first(&avl); node != NULL; node = AVL_NEXT(&avl, node))
ret |= callback(node->zn_handle, data);
while ((node = avl_destroy_nodes(&avl, &cookie)) != NULL)
free(node);
avl_destroy(&avl);
return (ret);
}
typedef struct {
char *ssa_first;
char *ssa_last;
boolean_t ssa_seenfirst;
boolean_t ssa_seenlast;
zfs_iter_f ssa_func;
void *ssa_arg;
} snapspec_arg_t;
static int
snapspec_cb(zfs_handle_t *zhp, void *arg) {
snapspec_arg_t *ssa = arg;
char *shortsnapname;
int err = 0;
if (ssa->ssa_seenlast)
return (0);
shortsnapname = zfs_strdup(zhp->zfs_hdl,
strchr(zfs_get_name(zhp), '@') + 1);
if (!ssa->ssa_seenfirst && strcmp(shortsnapname, ssa->ssa_first) == 0)
ssa->ssa_seenfirst = B_TRUE;
if (ssa->ssa_seenfirst) {
err = ssa->ssa_func(zhp, ssa->ssa_arg);
} else {
zfs_close(zhp);
}
if (strcmp(shortsnapname, ssa->ssa_last) == 0)
ssa->ssa_seenlast = B_TRUE;
free(shortsnapname);
return (err);
}
/*
* spec is a string like "A,B%C,D"
*
* <snaps>, where <snaps> can be:
* <snap> (single snapshot)
* <snap>%<snap> (range of snapshots, inclusive)
* %<snap> (range of snapshots, starting with earliest)
* <snap>% (range of snapshots, ending with last)
* % (all snapshots)
* <snaps>[,...] (comma separated list of the above)
*
* If a snapshot can not be opened, continue trying to open the others, but
* return ENOENT at the end.
*/
int
zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
zfs_iter_f func, void *arg)
{
char buf[ZFS_MAXNAMELEN];
char *comma_separated, *cp;
int err = 0;
int ret = 0;
(void) strlcpy(buf, spec_orig, sizeof (buf));
cp = buf;
while ((comma_separated = strsep(&cp, ",")) != NULL) {
char *pct = strchr(comma_separated, '%');
if (pct != NULL) {
snapspec_arg_t ssa = { 0 };
ssa.ssa_func = func;
ssa.ssa_arg = arg;
if (pct == comma_separated)
ssa.ssa_seenfirst = B_TRUE;
else
ssa.ssa_first = comma_separated;
*pct = '\0';
ssa.ssa_last = pct + 1;
/*
* If there is a lastname specified, make sure it
* exists.
*/
if (ssa.ssa_last[0] != '\0') {
char snapname[ZFS_MAXNAMELEN];
(void) snprintf(snapname, sizeof (snapname),
"%s@%s", zfs_get_name(fs_zhp),
ssa.ssa_last);
if (!zfs_dataset_exists(fs_zhp->zfs_hdl,
snapname, ZFS_TYPE_SNAPSHOT)) {
ret = ENOENT;
continue;
}
}
err = zfs_iter_snapshots_sorted(fs_zhp,
snapspec_cb, &ssa);
if (ret == 0)
ret = err;
if (ret == 0 && (!ssa.ssa_seenfirst ||
(ssa.ssa_last[0] != '\0' && !ssa.ssa_seenlast))) {
ret = ENOENT;
}
} else {
char snapname[ZFS_MAXNAMELEN];
zfs_handle_t *snap_zhp;
(void) snprintf(snapname, sizeof (snapname), "%s@%s",
zfs_get_name(fs_zhp), comma_separated);
snap_zhp = make_dataset_handle(fs_zhp->zfs_hdl,
snapname);
if (snap_zhp == NULL) {
ret = ENOENT;
continue;
}
err = func(snap_zhp, arg);
if (ret == 0)
ret = err;
}
}
return (ret);
}
/*
* Iterate over all children, snapshots and filesystems
*/
int
zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
{
int ret;
if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0)
return (ret);
return (zfs_iter_snapshots(zhp, func, data));
}
typedef struct iter_stack_frame {
struct iter_stack_frame *next;
zfs_handle_t *zhp;
} iter_stack_frame_t;
typedef struct iter_dependents_arg {
boolean_t first;
boolean_t allowrecursion;
iter_stack_frame_t *stack;
zfs_iter_f func;
void *data;
} iter_dependents_arg_t;
static int
iter_dependents_cb(zfs_handle_t *zhp, void *arg)
{
iter_dependents_arg_t *ida = arg;
int err;
boolean_t first = ida->first;
ida->first = B_FALSE;
if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
err = zfs_iter_clones(zhp, iter_dependents_cb, ida);
} else {
iter_stack_frame_t isf;
iter_stack_frame_t *f;
/*
* check if there is a cycle by seeing if this fs is already
* on the stack.
*/
for (f = ida->stack; f != NULL; f = f->next) {
if (f->zhp->zfs_dmustats.dds_guid ==
zhp->zfs_dmustats.dds_guid) {
if (ida->allowrecursion) {
zfs_close(zhp);
return (0);
} else {
zfs_error_aux(zhp->zfs_hdl,
dgettext(TEXT_DOMAIN,
"recursive dependency at '%s'"),
zfs_get_name(zhp));
err = zfs_error(zhp->zfs_hdl,
EZFS_RECURSIVE,
dgettext(TEXT_DOMAIN,
"cannot determine dependent "
"datasets"));
zfs_close(zhp);
return (err);
}
}
}
isf.zhp = zhp;
isf.next = ida->stack;
ida->stack = &isf;
err = zfs_iter_filesystems(zhp, iter_dependents_cb, ida);
if (err == 0)
err = zfs_iter_snapshots(zhp, iter_dependents_cb, ida);
ida->stack = isf.next;
}
if (!first && err == 0)
err = ida->func(zhp, ida->data);
return (err);
}
int
zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion,
zfs_iter_f func, void *data)
{
iter_dependents_arg_t ida;
ida.allowrecursion = allowrecursion;
ida.stack = NULL;
ida.func = func;
ida.data = data;
ida.first = B_TRUE;
return (iter_dependents_cb(zfs_handle_dup(zhp), &ida));
}

View File

@ -21,6 +21,8 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/types.h>
@ -261,6 +263,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
case ZPOOL_PROP_ALTROOT:
case ZPOOL_PROP_CACHEFILE:
case ZPOOL_PROP_COMMENT:
if (zhp->zpool_props != NULL ||
zpool_get_all_props(zhp) == 0) {
(void) strlcpy(buf,
@ -412,7 +415,7 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
zpool_prop_t prop;
char *strval;
uint64_t intval;
char *slash;
char *slash, *check;
struct stat64 statbuf;
zpool_handle_t *zhp;
nvlist_t *nvroot;
@ -573,6 +576,26 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
*slash = '/';
break;
case ZPOOL_PROP_COMMENT:
for (check = strval; *check != '\0'; check++) {
if (!isprint(*check)) {
zfs_error_aux(hdl,
dgettext(TEXT_DOMAIN,
"comment may only have printable "
"characters"));
(void) zfs_error(hdl, EZFS_BADPROP,
errbuf);
goto error;
}
}
if (strlen(strval) > ZPROP_MAX_COMMENT) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"comment must not exceed %d characters"),
ZPROP_MAX_COMMENT);
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
goto error;
}
break;
case ZPOOL_PROP_READONLY:
if (!flags.import) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
@ -3010,6 +3033,26 @@ zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
return (zpool_standard_error(hdl, errno, msg));
}
/*
* Change the GUID for a pool.
*/
int
zpool_reguid(zpool_handle_t *zhp)
{
char msg[1024];
libzfs_handle_t *hdl = zhp->zpool_hdl;
zfs_cmd_t zc = { 0 };
(void) snprintf(msg, sizeof (msg),
dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name);
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
if (zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc) == 0)
return (0);
return (zpool_standard_error(hdl, errno, msg));
}
/*
* Convert from a devid string to a path.
*/

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
/*
@ -351,6 +352,7 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
switch (error) {
case ENXIO:
case ENODEV:
case EPIPE:
zfs_verror(hdl, EZFS_IO, fmt, ap);
break;
@ -1324,7 +1326,8 @@ addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
* dataset property,
*/
if (prop == ZPROP_INVAL && (type == ZFS_TYPE_POOL ||
(!zfs_prop_user(propname) && !zfs_prop_userquota(propname)))) {
(!zfs_prop_user(propname) && !zfs_prop_userquota(propname) &&
!zfs_prop_written(propname)))) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid property '%s'"), propname);
return (zfs_error(hdl, EZFS_BADPROP,

View File

@ -20,8 +20,8 @@ SRCS+= libzfs_changelist.c \
libzfs_config.c \
libzfs_dataset.c \
libzfs_diff.c \
libzfs_graph.c \
libzfs_import.c \
libzfs_iter.c \
libzfs_mount.c \
libzfs_pool.c \
libzfs_sendrecv.c \

View File

@ -27,7 +27,7 @@
# $FreeBSD$
#
# PROVIDE: kld
# REQUIRE: FILESYSTEMS
# REQUIRE: kldxref
# KEYWORD: nojail
. /etc/rc.subr

View File

@ -29,11 +29,11 @@ CFLAGS+=-I${KRB5DIR}/lib/asn1 -I${KRB5DIR}/lib/krb5 -I${KRB5DIR}/lib/roken \
DPADD= ${LIBKADM5CLNT} ${LIBKADM5SRV} ${LIBHDB} ${LIBKRB5} ${LIBHX509} \
${LIBSL} ${LIBROKEN} ${LIBVERS} ${LIBASN1} \
${LIBCRYPTO} ${LIBCRYPT} ${LIBCOM_ERR} \
${LIBREADLINE} ${LIBNCURSES} ${LDAPDPADD}
${LIBEDIT} ${LIBNCURSES} ${LDAPDPADD}
LDADD= -lkadm5clnt -lkadm5srv -lhdb -lkrb5 -lhx509 \
${LIBSL} -lroken ${LIBVERS} -lasn1 \
-lcrypto -lcrypt -lcom_err \
-lreadline -lncurses ${LDAPLDADD}
-ledit -lncurses ${LDAPLDADD}
LDFLAGS=${LDAPLDFLAGS}
.include <bsd.prog.mk>

View File

@ -18,10 +18,10 @@ SRCS= add.c \
CFLAGS+=-I${KRB5DIR}/lib/roken -I${KRB5DIR}/lib/sl -I.
DPADD= ${LIBKADM5CLNT} ${LIBKRB5} ${LIBHX509} ${LIBSL} ${LIBROKEN} ${LIBVERS} \
${LIBASN1} ${LIBCRYPTO} ${LIBCRYPT} ${LIBCOM_ERR} \
${LIBREADLINE} ${LIBNCURSES}
${LIBEDIT} ${LIBNCURSES}
LDADD= -lkadm5clnt -lkrb5 -lhx509 ${LIBSL} -lroken ${LIBVERS} \
-lasn1 -lcrypto -lcrypt -lcom_err \
-lreadline -lncurses
-ledit -lncurses
.include <bsd.prog.mk>

View File

@ -265,7 +265,7 @@ vsyslog(int pri, const char *fmt, va_list ap)
* 1) syslogd was restarted
* 2) /var/run/log is out of socket buffer space, which
* in most cases means local DoS.
* We attempt to reconnect to /var/run/log to take care of
* We attempt to reconnect to /var/run/log[priv] to take care of
* case #1 and keep send()ing data to cover case #2
* to give syslogd a chance to empty its socket buffer.
*
@ -281,13 +281,13 @@ vsyslog(int pri, const char *fmt, va_list ap)
connectlog();
}
do {
if (status == CONNPRIV)
break;
_usleep(1);
if (send(LogFile, tbuf, cnt, 0) >= 0) {
THREAD_UNLOCK();
return;
}
if (status == CONNPRIV)
break;
} while (errno == ENOBUFS);
} else {
THREAD_UNLOCK();

View File

@ -36,25 +36,26 @@
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In xlocale.h
.Ft locale_t
.In xlocale.h
.Ft locale_t
.Fn duplocale "locale_t locale"
.Sh DESCRIPTION
Duplicates an existing
.Fa locale_t
returning a new
returning a new
.Fa locale_t
that refers to the same locale values but has independent internal state.
Various functions, such as
.Xr mblen 3
require presistent state. These functions formerly used static variables and
calls to them from multiple threads had undefined behavior. They now use
fields in the
require presistent state.
These functions formerly used static variables and calls to them from multiple
threads had undefined behavior.
They now use fields in the
.Fa locale_t
associated with the current thread by
.Xr uselocale 3 .
These calls are therefore only thread safe on threads with a unique per-thread
locale.
locale.
.Pt
The locale returned by this call must be freed with
.Xr freelocale 3 .
@ -63,8 +64,9 @@ Ideally,
.Xr uselocale 3
should make a copy of the
.Fa locale_t
implicitly to ensure thread safety, and a copy of the global locale should be
installed lazily on each thread. The FreeBSD implementation does not do this,
implicitly to ensure thread safety,
and a copy of the global locale should be installed lazily on each thread.
The FreeBSD implementation does not do this,
for compatibility with Darwin.
.Sh SEE ALSO
.Xr freelocale 3 ,

View File

@ -33,22 +33,22 @@
.Nm freelocale
.Nd Frees a locale created with
.Xr duplocale 3
or
or
.Xr newlocale 3 .
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In xlocale.h
.In xlocale.h
.Ft int
.Fn freelocale "locale_t locale"
.Sh DESCRIPTION
Frees a
.Fa locale_t .
This relinquishes any resources held exclusively by this locale. Note that
locales share reference-counted components, so a call to this function is not
guaranteed to free all of the components.
This relinquishes any resources held exclusively by this locale.
Note that locales share reference-counted components,
so a call to this function is not guaranteed to free all of the components.
.Sh RETURN VALUES
Returns 0 on success or -1 on error.
Returns 0 on success or -1 on error.
.Sh SEE ALSO
.Xr duplocale 3 ,
.Xr localeconv 3 ,

View File

@ -203,7 +203,7 @@ result similarly denotes an unavailable value.
The
.Fn localeconv_l
function takes an explicit locale parameter. For more information, see
.Xr xlocale 3 .
.Xr xlocale 3 .
.Sh RETURN VALUES
The
.Fn localeconv
@ -212,9 +212,10 @@ which may be altered by later calls to
.Xr setlocale 3
or
.Fn localeconv .
The return value for
The return value for
.Fn localeconv_l
is stored with the locale. It will remain valid until a subsequent call to
is stored with the locale.
It will remain valid until a subsequent call to
.Xr freelocale 3 .
If a thread-local locale is in effect then the return value from
.Fn localeconv

View File

@ -31,40 +31,44 @@
.Os
.Sh NAME
.Nm newlocale
.Nd Creates a new locale
.Nd Creates a new locale
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In xlocale
.Ft
.Ft
.Fn newlocale "int mask" "const char * locale" "locale_t base"
.Sh DESCRIPTION
Creates a new locale, inheriting some properties from an existing locale. The
.Fa mask
Creates a new locale, inheriting some properties from an existing locale.
The
.Fa mask
defines the components that the new locale will have set to the locale with the
name specified in the
name specified in the
.Fa locale
parameter. Any other components will be inherited from
parameter.
Any other components will be inherited from
.Fa base .
.Pt
The
.Fa mask
is either
.Fa LC_ALL_MASK,
indicating all possible locale components, or the logical OR of some
combination of the following:
indicating all possible locale components,
or the logical OR of some combination of the following:
.Bl -tag -width "LC_MESSAGES_MASK" -offset indent
.It LC_COLLATE_MASK
The locale for string collation routines. This controls alphabetic ordering in
The locale for string collation routines.
This controls alphabetic ordering in
.Xr strcoll 3
and
and
.Xr strxfrm 3 .
.It LC_CTYPE_MASK
The locale for the
.Xr ctype 3
and
.Xr multibyte 3
functions. This controls recognition of upper and lower case, alpha- betic or
functions.
This controls recognition of upper and lower case, alphabetic or
non-alphabetic characters, and so on.
.It LC_MESSAGES_MASK
Set a locale for message catalogs, see
@ -76,8 +80,8 @@ the
.Xr localeconv 3
function.
.It LC_NUMERIC_MASK
Set a locale for formatting numbers. This controls the for-
matting of decimal points in input and output of floating
Set a locale for formatting numbers.
This controls the formatting of decimal points in input and output of floating
point numbers in functions such as
.Xr printf 3
and
@ -95,7 +99,8 @@ This function uses the same rules for loading locale components as
.Sh RETURN VALUES
Returns a new, valid,
.Fa locale_t
or NULL if an error occurs. You must free the returned locale with
or NULL if an error occurs.
You must free the returned locale with
.Xr freelocale 3 .
.Sh SEE ALSO
.Xr duplocale 3 ,

View File

@ -36,15 +36,15 @@
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In xlocale.h
.In xlocale.h
.Ft const char *
.Fn querylocale "int mask" "locale_t locale"
.Sh DESCRIPTION
Returns the name of the locale for the category specified by
.Fa mask.
This possible values for the mask are the same as those in
.Xr newlocale 3 . If more than one bit in the mask is set, the returned value
is undefined.
.Xr newlocale 3 .
If more than one bit in the mask is set, the returned value is undefined.
.Sh SEE ALSO
.Xr duplocale 3 ,
.Xr freelocale 3 ,

View File

@ -36,17 +36,18 @@
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In xlocale.h
.In xlocale.h
.Ft locale_t
.Fn uselocale "locale_t locale"
.Sh DESCRIPTION
Specifies the locale for this thread to use. Specifying
Specifies the locale for this thread to use.
Specifying
.Fa LC_GLOBAL_LOCALE
disables the per-thread locale, while NULL returns the current locale without
setting a new one.
disables the per-thread locale,
while NULL returns the current locale without setting a new one.
.Sh RETURN VALUES
Returns the previous locale, or LC_GLOBAL_LOCALE if this thread has no locale
associated with it.
Returns the previous locale,
or LC_GLOBAL_LOCALE if this thread has no locale associated with it.
.Sh SEE ALSO
.Xr duplocale 3 ,
.Xr freelocale 3 ,
@ -55,5 +56,5 @@ associated with it.
.Xr querylocale 3 ,
.Xr xlocale 3
.Sh STANDARDS
This function, conforms to
This function conforms to
.St -p1003.1-2008

View File

@ -39,39 +39,45 @@
.In xlocale.h
.Sh DESCRIPTION
The extended locale support includes a set of functions for setting
thread-local locales, as well convenience functions for performing locale-aware
thread-local locales,
as well convenience functions for performing locale-aware
calls with a specified locale.
.Pp
The core of the xlocale API is the
.Fa locale_t
type. This is an opaque type encapsulating a locale. Instances of this can be
either set as the locale for a specific thread or passed directly to the
type.
This is an opaque type encapsulating a locale.
Instances of this can be either set as the locale for a specific thread or
passed directly to the
.Fa _l
suffixed variants of various standard C functions. Two special
suffixed variants of various standard C functions.
Two special
.Fa locale_t
values are available:
.Bl -bullet -offset indent
.Bl -bullet -offset indent
.It
NULL refers to the current locale for the thread, or to the global locale if no
locale has been set for this thread.
NULL refers to the current locale for the thread,
or to the global locale if no locale has been set for this thread.
.It
LC_GLOBAL_LOCALE refers to the global locale.
.El
.Pp
The global locale is the locale set with the
The global locale is the locale set with the
.Xr setlocale 3
function.
.Sh CAVEATS
The
The
.Xr setlocale 3
function, and others in the family, refer to the global locale. Other
functions that depend on the locale, however, will take the thread-local locale
if one has been set. This means that the idiom of setting the locale using
function, and others in the family, refer to the global locale.
Other functions that depend on the locale, however,
will take the thread-local locale if one has been set.
This means that the idiom of setting the locale using
.Xr setlocale 3 ,
calling a locale-dependent function, and then restoring the locale will not
calling a locale-dependent function,
and then restoring the locale will not
have the expected behavior if the current thread has had a locale set using
.Xr uselocale 3 .
You should avoid this idiom and prefer to use the
You should avoid this idiom and prefer to use the
.Fa _l
suffixed versions instead.
.Sh SEE ALSO
@ -84,29 +90,34 @@ suffixed versions instead.
.Sh CONVENIENCE FUNCTIONS
The xlocale API includes a number of
.Fa _l
suffixed convenience functions. These are variants of standard C functions
that have been modified to take an explicit
suffixed convenience functions.
These are variants of standard C functions
that have been modified to take an explicit
.Fa locale_t
parameter as the final argument or, in the case of variadic functions, as an
additional argument directly before the format string. Each of these functions
accepts either NULL or LC_GLOBAL_LOCALE. In these functions, NULL refers to
the C locale, rather than the thread's current locale. If you wish to use the
thread's current locale, then use the unsuffixed version of the function.
parameter as the final argument or, in the case of variadic functions,
as an additional argument directly before the format string.
Each of these functions accepts either NULL or LC_GLOBAL_LOCALE.
In these functions, NULL refers to the C locale,
rather than the thread's current locale.
If you wish to use the thread's current locale,
then use the unsuffixed version of the function.
.Pp
These functions are exposed by including
These functions are exposed by including
.In xlocale.h
.Em after
including the relevant headers for the standard variant. For example, the
including the relevant headers for the standard variant.
For example, the
.Xr strtol_l 3
function is exposed by including
function is exposed by including
.In xlocale.h
after
after
.In stdlib.h ,
which defines
.Xr strtol 3 .
.Pp
For reference, a complete list of the locale-aware functions that are available
in this form, along with the headers that expose them, is provided here:
For reference,
a complete list of the locale-aware functions that are available in this form,
along with the headers that expose them, is provided here:
.Pp
.Bl -tag -width "<monetary.h> "
.It In wctype.h
@ -117,7 +128,7 @@ in this form, along with the headers that expose them, is provided here:
.Xr iswdigit_l 3 ,
.Xr iswgraph_l 3 ,
.Xr iswlower_l 3 ,
.Xr iswprint_l 3 ,
.Xr iswprint_l 3 ,
.Xr iswpunct_l 3 ,
.Xr iswspace_l 3 ,
.Xr iswupper_l 3 ,
@ -264,7 +275,7 @@ The functions
conform to
.St -p1003.1-2008 .
.Sh HISTORY
The xlocale APIs first appeared in Darwin 8.0. This implementation was
written by David Chisnall, under sponsorship from the FreeBSD Foundation and
first appeared in
The xlocale APIs first appeared in Darwin 8.0.
This implementation was written by David Chisnall,
under sponsorship from the FreeBSD Foundation and first appeared in
.Fx 9.1 .

View File

@ -48,9 +48,6 @@ strcasecmp_l(const char *s1, const char *s2, locale_t locale)
const u_char
*us1 = (const u_char *)s1,
*us2 = (const u_char *)s2;
if (s1 == s2)
return (0);
FIX_LOCALE(locale);
while (tolower_l(*us1, locale) == tolower_l(*us2++, locale))
@ -68,22 +65,18 @@ int
strncasecmp_l(const char *s1, const char *s2, size_t n, locale_t locale)
{
FIX_LOCALE(locale);
if (n != 0) {
const u_char
*us1 = (const u_char *)s1,
*us2 = (const u_char *)s2;
const u_char
*us1 = (const u_char *)s1,
*us2 = (const u_char *)s2;
/* use a bitwise or to avoid an additional branch instruction */
if ((s1 == s2) | (n == 0))
return (0);
do {
if (tolower_l(*us1, locale) != tolower_l(*us2++, locale))
return (tolower_l(*us1, locale) - tolower_l(*--us2, locale));
if (*us1++ == '\0')
break;
} while (--n != 0);
do {
if (tolower_l(*us1, locale) != tolower_l(*us2++, locale))
return (tolower_l(*us1, locale) - tolower_l(*--us2, locale));
if (*us1++ == '\0')
break;
} while (--n != 0);
}
return (0);
}

View File

@ -44,9 +44,6 @@ __FBSDID("$FreeBSD$");
int
strcmp(const char *s1, const char *s2)
{
if (s1 == s2)
return (0);
while (*s1 == *s2++)
if (*s1++ == '\0')
return (0);

View File

@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
int
strcoll_l(const char *s1, const char *s2, locale_t locale)
strcoll_l(const char *s, const char *s2, locale_t locale)
{
int len, len2, prim, prim2, sec, sec2, ret, ret2;
const char *t, *t2;
@ -50,16 +50,16 @@ strcoll_l(const char *s1, const char *s2, locale_t locale)
(struct xlocale_collate*)locale->components[XLC_COLLATE];
if (table->__collate_load_error)
return strcmp(s1, s2);
return strcmp(s, s2);
len = len2 = 1;
ret = ret2 = 0;
if (table->__collate_substitute_nontrivial) {
t = tt = __collate_substitute(table, s1);
t = tt = __collate_substitute(table, s);
t2 = tt2 = __collate_substitute(table, s2);
} else {
tt = tt2 = NULL;
t = s1;
t = s;
t2 = s2;
}
while(*t && *t2) {
@ -95,8 +95,8 @@ strcoll_l(const char *s1, const char *s2, locale_t locale)
}
int
strcoll(const char *s1, const char *s2)
strcoll(const char *s, const char *s2)
{
return strcoll_l(s1, s2, __get_locale());
return strcoll_l(s, s2, __get_locale());
}

View File

@ -39,10 +39,8 @@ int
strncmp(const char *s1, const char *s2, size_t n)
{
/* use a bitwise or to avoid an additional branch instruction */
if ((n == 0) | (s1 == s2))
if (n == 0)
return (0);
do {
if (*s1 != *s2++)
return (*(const unsigned char *)s1 -

View File

@ -2,6 +2,7 @@
# $FreeBSD$
INCS= readline.h history.h
INCSLINKS= readline.h ${INCSDIR}/tilde.h
INCSDIR= ${INCLUDEDIR}/edit/readline

View File

@ -200,7 +200,6 @@ void rl_get_screen_size(int *, int *);
void rl_set_screen_size(int, int);
char *rl_filename_completion_function (const char *, int);
int _rl_abort_internal(void);
int _rl_qsort_string_compare(char **, char **);
char **rl_completion_matches(const char *, rl_compentry_func_t *);
void rl_forced_update_display(void);
int rl_set_prompt(const char *);

View File

@ -125,7 +125,7 @@ CRUNCH_LIBS+= -lipx
.if ${MK_ZFS} != "no"
CRUNCH_LIBS+= -lavl -lnvpair -lzfs -lpthread -luutil -lumem
.endif
CRUNCH_LIBS+= -lgeom -lbsdxml -ljail -lkiconv -lmd -lreadline -lsbuf -lufs -lz
CRUNCH_LIBS+= -lgeom -lbsdxml -ljail -lkiconv -lmd -lsbuf -lufs -lz
.if ${MACHINE_CPUARCH} == "i386"
CRUNCH_PROGS_sbin+= bsdlabel sconfig fdisk

View File

@ -25,6 +25,15 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This software is derived from Andre Albsmeier's fwprog.c which contained
* the following note:
*
* Many thanks goes to Marc Frajola <marc@terasolutions.com> from
* TeraSolutions for the initial idea and his programme for upgrading
* the firmware of I*M DDYS drives.
*/
/*
* BEWARE:
*

View File

@ -201,7 +201,7 @@ parse(char *string)
if (oidfmt(mib, len, fmt, &kind))
err(1, "couldn't find format of oid '%s'", bufp);
if (newval == NULL) {
if (newval == NULL || dflag) {
if ((kind & CTLTYPE) == CTLTYPE_NODE) {
if (dflag) {
i = show_var(mib, len);

View File

@ -123,6 +123,7 @@ MAN= aac.4 \
fdc.4 \
fdt.4 \
fdtbus.4 \
ffclock.4 \
firewire.4 \
fpa.4 \
fwe.4 \

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd May 17, 2011
.Dd December 2, 2011
.Dt AHCI 4
.Os
.Sh NAME
@ -96,6 +96,9 @@ A manual bus reset is needed on device hot-plug.
.It Va hint.ahcich. Ns Ar X Ns Va .sata_rev
setting to nonzero value limits maximum SATA revision (speed).
Values 1, 2 and 3 are respectively 1.5, 3 and 6Gbps.
.It Va hw.ahci.force
setting to nonzero value forces driver attach to some known AHCI-capable
chips even if they are configured for legacy IDE emulation. Default is 1.
.El
.Sh DESCRIPTION
This driver provides the

View File

@ -31,7 +31,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd November 23, 2010
.Dd December 2, 2011
.Dt BGE 4
.Os
.Sh NAME
@ -82,9 +82,9 @@ copper gigabit transceivers,
which support autonegotiation of 10, 100 and 1000Mbps modes in
full or half duplex.
.Pp
The BCM5700, BCM5701, BCM5702, BCM5703, BCM5704 and BCM5717 also support
jumbo frames, which can be configured
via the interface MTU setting.
The BCM5700, BCM5701, BCM5702, BCM5703, BCM5704, BCM5714, BCM5717, BCM5719,
BCM5720, BCM5780 and BCM57765 also support jumbo frames, which can be
configured via the interface MTU setting.
Selecting an MTU larger than 1500 bytes with the
.Xr ifconfig 8
utility configures the adapter to receive and transmit jumbo frames.

128
share/man/man4/ffclock.4 Normal file
View File

@ -0,0 +1,128 @@
.\" Copyright (c) 2011 The University of Melbourne
.\" All rights reserved.
.\"
.\" This documentation was written by Julien Ridoux at the University of
.\" Melbourne under sponsorship from the FreeBSD Foundation.
.\"
.\" 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 AUTHOR 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 AUTHOR 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 December 1, 2011
.Dt FFCLOCK 4
.Os
.Sh NAME
.Nm FFCLOCK
.Nd Feed-forward system clock
.Sh SYNOPSIS
.Cd options FFCLOCK
.Sh DESCRIPTION
The
.Xr ntpd 8
daemon has been the dominant solution for system clock synchronisation for many
years, which has in turn influenced the design of the system clock.
The ntpd daemon implements a feedback control algorithm which has been
demonstrated to perform poorly in common use cases.
.Pp
Feed-forward clock synchronisation algorithms implemented by an appropriate
daemon, in concert with the
.Nm
kernel support, have been shown to provide highly robust and accurate clock
synchronisation.
In addition to time keeping, the
.Nm
kernel mechanism provides new timestamping capabilities and the ability to
use specialised clocks.
Feed-forward synchronisation is also very well suited for virtualised
environments, reducing the overhead of timekeeping in guests and ensuring
continued smooth operation of the system clock during guest live migration.
.Pp
The
.Nm
kernel support provides feed-forward timestamping functions within the kernel
and system calls to support feed-forward synchronisation daemons
.Po see
.Xr ffclock 2
.Pc .
.Ss Kernel Options
The following kernel configuration options are related to
.Nm :
.Pp
.Bl -tag -width ".Dv FFCLOCK" -compact
.It Dv FFCLOCK
Enable feed-forward clock support.
.El
.Ss Configuration
When feed-forward clock support is compiled into the kernel, multiple system
clocks become available to choose from.
System clock configuration is possible via the
.Va kern.sysclock
.Xr sysctl 8
tree which provides the following variables:
.Bl -tag -width " " -offset indent
.It Va kern.sysclock.active
Name of the current active system clock which is serving time.
Set to one of the names in
.Va kern.sysclock.available
in order to change the default active system clock.
.It Va kern.sysclock.available
Lists the names of available system clocks
.Po
read only
.Pc .
.El
.Pp
Feed-forward system clock configuration is possible via the
.Va kern.sysclock.ffclock
sysctl tree which provides the following variables:
.Bl -tag -width " " -offset indent
.It Va kern.sysclock.ffclock.version
Feed-forward clock kernel version
.Po
read only
.Pc .
.It Va kern.sysclock.ffclock.ffcounter_bypass
Use reliable hardware timecounter as the feed-forward counter.
Will eventually be useful for virtualised environment like
.Xr xen 4 ,
but currently does nothing.
.El
.Sh SEE ALSO
.Xr clock_gettime 2 ,
.Xr ffclock 2 ,
.Xr bpf 4 ,
.Xr sysctl 8
.Sh HISTORY
Feed-forward clock support first appeared in
.Fx 10.0 .
.Sh AUTHORS
.An -nosplit
The feed-forward clock support was written by
.An Julien Ridoux Aq jridoux@unimelb.edu.au
in collaboration with
.An Darryl Veitch Aq dveitch@unimelb.edu.au
at the University of Melbourne under sponsorship from the FreeBSD Foundation.
.Pp
This manual page was written by
.An Julien Ridoux Aq jridoux@unimelb.edu.au
and
.An Lawrence Stewart Aq lstewart@FreeBSD.org .

View File

@ -1,7 +1,7 @@
.\" DO NOT EDIT-- this file is automatically generated.
.\" from FreeBSD: head/tools/build/options/makeman 221733 2011-05-10 13:01:11Z ru
.\" $FreeBSD$
.Dd June 17, 2011
.Dd December 2, 2011
.Dt SRC.CONF 5
.Os
.Sh NAME
@ -258,6 +258,8 @@ When set, it also enforces the following options:
.Pp
.Bl -item -compact
.It
.Va WITHOUT_CTF
.It
.Va WITHOUT_ZFS
.El
.It Va WITHOUT_CLANG
@ -265,13 +267,13 @@ When set, it also enforces the following options:
Set to not build the Clang C/C++ compiler.
.Pp
It is a default setting on
arm/arm, arm/armeb, ia64/ia64, mips/mipsel, mips/mipseb, mips/mips64el, mips/mips64eb, mips/mipsn32eb, powerpc/powerpc64 and sparc64/sparc64.
arm/arm, arm/armeb, ia64/ia64, mips/mipsel, mips/mipseb, mips/mips64el, mips/mips64eb, mips/mipsn32eb and sparc64/sparc64.
.It Va WITH_CLANG
.\" from FreeBSD: head/tools/build/options/WITH_CLANG 221730 2011-05-10 11:14:40Z ru
Set to build the Clang C/C++ compiler.
.Pp
It is a default setting on
amd64/amd64, i386/i386, pc98/i386 and powerpc/powerpc.
amd64/amd64, i386/i386, pc98/i386, powerpc/powerpc and powerpc/powerpc64.
.It Va WITHOUT_CPP
.\" from FreeBSD: head/tools/build/options/WITHOUT_CPP 156932 2006-03-21 07:50:50Z ru
Set to not build
@ -300,6 +302,11 @@ When set, the following options are also in effect:
.Va WITH_GSSAPI
is set explicitly)
.El
.It Va WITH_CTF
.\" from FreeBSD: head/tools/build/options/WITH_CTF 228159 2011-11-30 18:22:44Z fjoe
Set to compile with CTF (Compact C Type Format) data.
CTF data encapsulates a reduced form of debugging information
similar to DWARF and the venerable stabs and is required for DTrace.
.It Va WITHOUT_CTM
.\" from FreeBSD: head/tools/build/options/WITHOUT_CTM 183242 2008-09-21 22:02:26Z sam
Set to not build
@ -345,14 +352,14 @@ Set to not build Flattened Device Tree support as part of the base system.
This includes the device tree compiler (dtc) and libfdt support library.
.Pp
It is a default setting on
amd64/amd64, i386/i386, ia64/ia64, mips/mipsel, mips/mipseb, mips/mips64el, mips/mips64eb, mips/mipsn32eb, pc98/i386, powerpc/powerpc64 and sparc64/sparc64.
amd64/amd64, i386/i386, ia64/ia64, pc98/i386 and sparc64/sparc64.
.It Va WITH_FDT
.\" from FreeBSD: head/tools/build/options/WITH_FDT 221730 2011-05-10 11:14:40Z ru
Set to build Flattened Device Tree support as part of the base system.
This includes the device tree compiler (dtc) and libfdt support library.
.Pp
It is a default setting on
arm/arm, arm/armeb and powerpc/powerpc.
arm/arm, arm/armeb, mips/mipsel, mips/mipseb, mips/mips64el, mips/mips64eb, mips/mipsn32eb, powerpc/powerpc and powerpc/powerpc64.
.It Va WITHOUT_FLOPPY
.\" from FreeBSD: head/tools/build/options/WITHOUT_FLOPPY 221540 2011-05-06 19:13:03Z ru
Set to not build or install programs
@ -409,7 +416,7 @@ Set to build some programs without optional GNU support.
.\" from FreeBSD: head/tools/build/options/WITHOUT_GPIB 156932 2006-03-21 07:50:50Z ru
Set to not build GPIB bus support.
.It Va WITHOUT_GPIO
.\" from FreeBSD: head/tools/build/options/WITHOUT_GPIO 221541 2011-05-06 19:14:06Z ru
.\" from FreeBSD: head/tools/build/options/WITHOUT_GPIO 228081 2011-11-28 17:54:34Z dim
Set to not build
.Xr gpioctl 8
as part of the base system.
@ -563,6 +570,9 @@ and
On amd64, set to not build 32-bit library set and a
.Nm ld-elf32.so.1
runtime linker.
.It Va WITH_LIBCPLUSPLUS
.\" from FreeBSD: head/tools/build/options/WITH_LIBCPLUSPLUS 228082 2011-11-28 17:56:46Z dim
Set to build libcxxrt and libc++.
.It Va WITHOUT_LIBPTHREAD
.\" from FreeBSD: head/tools/build/options/WITHOUT_LIBPTHREAD 188848 2009-02-20 11:09:55Z mtm
Set to not build the
@ -734,7 +744,7 @@ Set to not build
.Xr ntpd 8
and related programs.
.It Va WITH_OFED
.\" from FreeBSD: head/tools/build/options/WITH_OFED 222016 2011-05-17 11:06:41Z ru
.\" from FreeBSD: head/tools/build/options/WITH_OFED 228081 2011-11-28 17:54:34Z dim
Set to build the
.Dq "OpenFabrics Enterprise Distribution"
Infiniband software stack.
@ -811,7 +821,7 @@ Set to not build
.Xr ppp 8
and related programs.
.It Va WITHOUT_PROFILE
.\" from FreeBSD: head/tools/build/options/WITHOUT_PROFILE 156932 2006-03-21 07:50:50Z ru
.\" from FreeBSD: head/tools/build/options/WITH_PROFILE 228143 2011-11-29 19:46:17Z fjoe
Set to avoid compiling profiled libraries.
.It Va WITHOUT_QUOTAS
.\" from FreeBSD: head/tools/build/options/WITHOUT_QUOTAS 183242 2008-09-21 22:02:26Z sam

View File

@ -33,15 +33,10 @@ CFLAGS+= -DNDEBUG
NO_WERROR=
.endif
# Enable CTF conversion on request.
.if defined(WITH_CTF)
.undef NO_CTF
.endif
.if defined(DEBUG_FLAGS)
CFLAGS+= ${DEBUG_FLAGS}
.if !defined(NO_CTF) && (${DEBUG_FLAGS:M-g} != "")
.if ${MK_CTF} != "no" && ${DEBUG_FLAGS:M-g} != ""
CTFFLAGS+= -g
.endif
.endif
@ -69,21 +64,15 @@ PO_FLAG=-pg
.c.o:
${CC} ${STATIC_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.c.po:
${CC} ${PO_FLAG} ${STATIC_CFLAGS} ${PO_CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.c.So:
${CC} ${PICFLAG} -DPIC ${SHARED_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.cc.o:
${CXX} ${STATIC_CXXFLAGS} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET}
@ -96,47 +85,33 @@ PO_FLAG=-pg
.f.po:
${FC} -pg ${FFLAGS} -o ${.TARGET} -c ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.f.So:
${FC} ${PICFLAG} -DPIC ${FFLAGS} -o ${.TARGET} -c ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.s.po .s.So:
${AS} ${AFLAGS} -o ${.TARGET} ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.asm.po:
${CC} -x assembler-with-cpp -DPROF ${PO_CFLAGS} ${ACFLAGS} \
-c ${.IMPSRC} -o ${.TARGET}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.asm.So:
${CC} -x assembler-with-cpp ${PICFLAG} -DPIC ${CFLAGS} ${ACFLAGS} \
-c ${.IMPSRC} -o ${.TARGET}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.S.po:
${CC} -DPROF ${PO_CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.S.So:
${CC} ${PICFLAG} -DPIC ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
all: objwarn
@ -211,9 +186,9 @@ ${SHLIB_NAME}: ${SOBJS}
-o ${.TARGET} -Wl,-soname,${SONAME} \
`NM='${NM}' lorder ${SOBJS} | tsort -q` ${LDADD}
.endif
@[ -z "${CTFMERGE}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SOBJS} && \
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SOBJS})
.if ${MK_CTF} != "no"
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SOBJS}
.endif
.endif
.if defined(INSTALL_PIC_ARCHIVE) && defined(LIB) && !empty(LIB) && ${MK_TOOLCHAIN} != "no"

View File

@ -203,10 +203,14 @@ COMPRESS_EXT?= .gz
# regardless of user's setting).
#
.for var in \
CTF \
INSTALLLIB \
MAN \
PROFILE
.if defined(NO_${var})
.if defined(WITH_${var})
.undef WITH_${var}
.endif
WITHOUT_${var}=
.endif
.endfor
@ -410,6 +414,7 @@ __DEFAULT_NO_OPTIONS = \
BIND_LIBS \
BIND_SIGCHASE \
BIND_XML \
CTF \
HESIOD \
ICONV \
IDEA \
@ -507,6 +512,7 @@ MK_BIND_ETC:= no
.if ${MK_CDDL} == "no"
MK_ZFS:= no
MK_CTF:= no
.endif
.if ${MK_CRYPT} == "no"
@ -607,6 +613,14 @@ MK_${vv:H}:= ${MK_${vv:T}}
.endif
.endfor
.if ${MK_CTF} != "no"
CTFCONVERT_CMD= ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.elif ${MAKE_VERSION} >= 5201111300
CTFCONVERT_CMD=
.else
CTFCONVERT_CMD= @:
.endif
.endif # !_WITHOUT_SRCCONF
.endif # !target(__<bsd.own.mk>__)

View File

@ -15,16 +15,11 @@ CFLAGS+= -DNDEBUG
NO_WERROR=
.endif
# Enable CTF conversion on request.
.if defined(WITH_CTF)
.undef NO_CTF
.endif
.if defined(DEBUG_FLAGS)
CFLAGS+=${DEBUG_FLAGS}
CXXFLAGS+=${DEBUG_FLAGS}
.if !defined(NO_CTF) && (${DEBUG_FLAGS:M-g} != "")
.if ${MK_CTF} != "no" && ${DEBUG_FLAGS:M-g} != ""
CTFFLAGS+= -g
.endif
.endif
@ -60,9 +55,9 @@ ${PROG}: ${OBJS}
.else
${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
.endif
@[ -z "${CTFMERGE}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS} && \
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS})
.if ${MK_CTF} != "no"
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
.endif
.else # !defined(SRCS)
@ -90,9 +85,9 @@ ${PROG}: ${OBJS}
.else
${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
.endif
@[ -z "${CTFMERGE}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS} && \
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS})
.if ${MK_CTF} != "no"
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
.endif
.endif
.endif

View File

@ -59,12 +59,6 @@ CFLAGS += -fno-strict-aliasing
.endif
PO_CFLAGS ?= ${CFLAGS}
# Turn CTF conversion off by default for now. This default could be
# changed later if DTrace becomes popular.
.if !defined(WITH_CTF)
NO_CTF = 1
.endif
# C Type Format data is required for DTrace
CTFFLAGS ?= -L VERSION
@ -158,15 +152,11 @@ YFLAGS ?= -d
# SINGLE SUFFIX RULES
.c:
${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.f:
${FC} ${FFLAGS} ${LDFLAGS} -o ${.TARGET} ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.sh:
cp -f ${.IMPSRC} ${.TARGET}
@ -176,33 +166,25 @@ YFLAGS ?= -d
.c.o:
${CC} ${CFLAGS} -c ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.f.o:
${FC} ${FFLAGS} -c ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.y.o:
${YACC} ${YFLAGS} ${.IMPSRC}
${CC} ${CFLAGS} -c y.tab.c
rm -f y.tab.c
mv y.tab.o ${.TARGET}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.l.o:
${LEX} ${LFLAGS} ${.IMPSRC}
${CC} ${CFLAGS} -c lex.yy.c
rm -f lex.yy.c
mv lex.yy.o ${.TARGET}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.y.c:
${YACC} ${YFLAGS} ${.IMPSRC}
@ -240,15 +222,11 @@ YFLAGS ?= -d
.c:
${CC} ${CFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.c.o:
${CC} ${CFLAGS} -c ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.cc .cpp .cxx .C:
${CXX} ${CXXFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET}
@ -258,15 +236,11 @@ YFLAGS ?= -d
.m.o:
${OBJC} ${OBJCFLAGS} -c ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.p.o:
${PC} ${PFLAGS} -c ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.e .r .F .f:
${FC} ${RFLAGS} ${EFLAGS} ${FFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} \
@ -277,38 +251,28 @@ YFLAGS ?= -d
.S.o:
${CC} ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.asm.o:
${CC} -x assembler-with-cpp ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.s.o:
${AS} ${AFLAGS} -o ${.TARGET} ${.IMPSRC}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
# XXX not -j safe
.y.o:
${YACC} ${YFLAGS} ${.IMPSRC}
${CC} ${CFLAGS} -c y.tab.c -o ${.TARGET}
rm -f y.tab.c
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.l.o:
${LEX} -t ${LFLAGS} ${.IMPSRC} > ${.PREFIX}.tmp.c
${CC} ${CFLAGS} -c ${.PREFIX}.tmp.c -o ${.TARGET}
rm -f ${.PREFIX}.tmp.c
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
# XXX not -j safe
.y.c:
@ -320,34 +284,26 @@ YFLAGS ?= -d
.s.out .c.out .o.out:
${CC} ${CFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.f.out .F.out .r.out .e.out:
${FC} ${EFLAGS} ${RFLAGS} ${FFLAGS} ${LDFLAGS} ${.IMPSRC} \
${LDLIBS} -o ${.TARGET}
rm -f ${.PREFIX}.o
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
# XXX not -j safe
.y.out:
${YACC} ${YFLAGS} ${.IMPSRC}
${CC} ${CFLAGS} ${LDFLAGS} y.tab.c ${LDLIBS} -ly -o ${.TARGET}
rm -f y.tab.c
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
.l.out:
${LEX} -t ${LFLAGS} ${.IMPSRC} > ${.PREFIX}.tmp.c
${CC} ${CFLAGS} ${LDFLAGS} ${.PREFIX}.tmp.c ${LDLIBS} -ll -o ${.TARGET}
rm -f ${.PREFIX}.tmp.c
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
(${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET})
${CTFCONVERT_CMD}
# FreeBSD build pollution. Hide it in the non-POSIX part of the ifdef.
__MAKE_CONF?=/etc/make.conf

View File

@ -294,6 +294,7 @@ options DRM_DEBUG # Include debug printfs (slow)
# Requires the mwl firmware module
# nfe: nVidia nForce MCP on-board Ethernet Networking (BSD open source)
# nve: nVidia nForce MCP on-board Ethernet Networking
# sfxge: Solarflare SFC9000 family 10Gb Ethernet adapters
# wpi: Intel 3945ABG Wireless LAN controller
# Requires the wpi firmware module
@ -307,6 +308,7 @@ device iwn
device mwl
device nfe
device nve
device sfxge
device wpi
# IEEE 802.11 adapter firmware modules

View File

@ -1693,7 +1693,7 @@ fdt_get_ranges(const char *nodename, void *buf, int size, int *tuples,
int len, tuple_size, tuples_count;
node = OF_finddevice(nodename);
if (node <= 0)
if (node == -1)
return (EINVAL);
if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
@ -1762,11 +1762,11 @@ win_cpu_from_dt(void)
/*
* Retrieve CESA SRAM data.
*/
if ((node = OF_finddevice("sram")) != 0)
if ((node = OF_finddevice("sram")) != -1)
if (fdt_is_compatible(node, "mrvl,cesa-sram"))
goto moveon;
if ((node = OF_finddevice("/")) == 0)
if ((node = OF_finddevice("/")) != -1)
return (ENXIO);
if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0)
@ -1796,7 +1796,7 @@ fdt_win_setup(void)
int err, i;
node = OF_finddevice("/");
if (node == 0)
if (node == -1)
panic("fdt_win_setup: no root node");
node = fdt_find_compatible(node, "simple-bus", 1);

View File

@ -617,13 +617,13 @@ platform_mpp_init(void)
/*
* Try to access the MPP node directly i.e. through /aliases/mpp.
*/
if ((node = OF_finddevice("mpp")) != 0)
if ((node = OF_finddevice("mpp")) != -1)
if (fdt_is_compatible(node, "mrvl,mpp"))
goto moveon;
/*
* Find the node the long way.
*/
if ((node = OF_finddevice("/")) == 0)
if ((node = OF_finddevice("/")) == -1)
return (ENXIO);
if ((node = fdt_find_compatible(node, "simple-bus", 0)) == 0)
@ -752,7 +752,7 @@ platform_devmap_init(void)
/*
* PCI range(s).
*/
if ((root = OF_finddevice("/")) == 0)
if ((root = OF_finddevice("/")) == -1)
return (ENXIO);
for (child = OF_child(root); child != 0; child = OF_peer(child))
@ -779,7 +779,7 @@ platform_devmap_init(void)
/*
* CESA SRAM range.
*/
if ((child = OF_finddevice("sram")) != 0)
if ((child = OF_finddevice("sram")) != -1)
if (fdt_is_compatible(child, "mrvl,cesa-sram"))
goto moveon;

View File

@ -267,7 +267,7 @@ zfs_prop_init(void)
/* default index properties */
zprop_register_index(ZFS_PROP_VERSION, "version", 0, PROP_DEFAULT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
"1 | 2 | 3 | 4 | current", "VERSION", version_table);
"1 | 2 | 3 | 4 | 5 | current", "VERSION", version_table);
zprop_register_index(ZFS_PROP_CANMOUNT, "canmount", ZFS_CANMOUNT_ON,
PROP_DEFAULT, ZFS_TYPE_FILESYSTEM, "on | off | noauto",
"CANMOUNT", canmount_table);
@ -297,6 +297,8 @@ zfs_prop_init(void)
/* string properties */
zprop_register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN");
zprop_register_string(ZFS_PROP_CLONES, "clones", NULL, PROP_READONLY,
ZFS_TYPE_SNAPSHOT, "<dataset>[,...]", "CLONES");
zprop_register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/",
PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "<path> | legacy | none",
"MOUNTPOINT");
@ -342,6 +344,8 @@ zfs_prop_init(void)
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDREFRESERV");
zprop_register_number(ZFS_PROP_USERREFS, "userrefs", 0, PROP_READONLY,
ZFS_TYPE_SNAPSHOT, "<count>", "USERREFS");
zprop_register_number(ZFS_PROP_WRITTEN, "written", 0, PROP_READONLY,
ZFS_TYPE_DATASET, "<size>", "WRITTEN");
/* default number properties */
zprop_register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT,
@ -467,6 +471,18 @@ zfs_prop_userquota(const char *name)
return (B_FALSE);
}
/*
* Returns true if this is a valid written@ property.
* Note that after the @, any character is valid (eg, another @, for
* written@pool/fs@origin).
*/
boolean_t
zfs_prop_written(const char *name)
{
static const char *prefix = "written@";
return (strncmp(name, prefix, strlen(prefix)) == 0);
}
/*
* Tables of index types, plus functions to convert between the user view
* (strings) and internal representation (uint64_t).

View File

@ -121,6 +121,8 @@ uint64_t zprop_random_value(int, uint64_t, zfs_type_t);
const char *zprop_values(int, zfs_type_t);
size_t zprop_width(int, boolean_t *, zfs_type_t);
boolean_t zprop_valid_for_type(int, zfs_type_t);
boolean_t zfs_prop_written(const char *name);
#ifdef __cplusplus
}

View File

@ -20,6 +20,8 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/zio.h>
@ -69,6 +71,8 @@ zpool_prop_init(void)
ZFS_TYPE_POOL, "<filesystem>", "BOOTFS");
zprop_register_string(ZPOOL_PROP_CACHEFILE, "cachefile", NULL,
PROP_DEFAULT, ZFS_TYPE_POOL, "<file> | none", "CACHEFILE");
zprop_register_string(ZPOOL_PROP_COMMENT, "comment", NULL,
PROP_DEFAULT, ZFS_TYPE_POOL, "<comment-string>", "COMMENT");
/* readonly number properties */
zprop_register_number(ZPOOL_PROP_SIZE, "size", 0, PROP_READONLY,

View File

@ -20,6 +20,8 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
/*
@ -1365,7 +1367,7 @@ arc_buf_alloc(spa_t *spa, int size, void *tag, arc_buf_contents_t type)
ASSERT(BUF_EMPTY(hdr));
hdr->b_size = size;
hdr->b_type = type;
hdr->b_spa = spa_guid(spa);
hdr->b_spa = spa_load_guid(spa);
hdr->b_state = arc_anon;
hdr->b_arc_access = 0;
buf = kmem_cache_alloc(buf_cache, KM_PUSHPAGE);
@ -2146,7 +2148,7 @@ arc_flush(spa_t *spa)
uint64_t guid = 0;
if (spa)
guid = spa_guid(spa);
guid = spa_load_guid(spa);
while (arc_mru->arcs_lsize[ARC_BUFC_DATA]) {
(void) arc_evict(arc_mru, guid, -1, FALSE, ARC_BUFC_DATA);
@ -2936,7 +2938,7 @@ arc_read_nolock(zio_t *pio, spa_t *spa, const blkptr_t *bp,
arc_buf_t *buf;
kmutex_t *hash_lock;
zio_t *rzio;
uint64_t guid = spa_guid(spa);
uint64_t guid = spa_load_guid(spa);
top:
hdr = buf_hash_find(guid, BP_IDENTITY(bp), BP_PHYSICAL_BIRTH(bp),
@ -4593,7 +4595,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
boolean_t have_lock, full;
l2arc_write_callback_t *cb;
zio_t *pio, *wzio;
uint64_t guid = spa_guid(spa);
uint64_t guid = spa_load_guid(spa);
int try;
ASSERT(dev->l2ad_vdev != NULL);

View File

@ -20,11 +20,13 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/bpobj.h>
#include <sys/zfs_context.h>
#include <sys/refcount.h>
#include <sys/dsl_pool.h>
uint64_t
bpobj_alloc(objset_t *os, int blocksize, dmu_tx_t *tx)
@ -440,7 +442,10 @@ space_range_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
struct space_range_arg *sra = arg;
if (bp->blk_birth > sra->mintxg && bp->blk_birth <= sra->maxtxg) {
sra->used += bp_get_dsize_sync(sra->spa, bp);
if (dsl_pool_sync_context(spa_get_dsl(sra->spa)))
sra->used += bp_get_dsize_sync(sra->spa, bp);
else
sra->used += bp_get_dsize(sra->spa, bp);
sra->comp += BP_GET_PSIZE(bp);
sra->uncomp += BP_GET_UCSIZE(bp);
}

View File

@ -20,9 +20,11 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/dmu.h>
@ -47,6 +49,9 @@
#include <sys/ddt.h>
#include <sys/zfs_onexit.h>
/* Set this tunable to TRUE to replace corrupt data with 0x2f5baddb10c */
int zfs_send_corrupt_data = B_FALSE;
static char *dmu_recv_tag = "dmu_recv_tag";
/*
@ -384,8 +389,20 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf,
if (dsl_read(NULL, spa, bp, pbuf,
arc_getbuf_func, &abuf, ZIO_PRIORITY_ASYNC_READ,
ZIO_FLAG_CANFAIL, &aflags, zb) != 0)
return (EIO);
ZIO_FLAG_CANFAIL, &aflags, zb) != 0) {
if (zfs_send_corrupt_data) {
/* Send a block filled with 0x"zfs badd bloc" */
abuf = arc_buf_alloc(spa, blksz, &abuf,
ARC_BUFC_DATA);
uint64_t *ptr;
for (ptr = abuf->b_data;
(char *)ptr < (char *)abuf->b_data + blksz;
ptr++)
*ptr = 0x2f5baddb10c;
} else {
return (EIO);
}
}
err = dump_data(ba, type, zb->zb_object, zb->zb_blkid * blksz,
blksz, bp, abuf->b_data);
@ -515,6 +532,86 @@ dmu_sendbackup(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
return (0);
}
int
dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
uint64_t *sizep)
{
dsl_dataset_t *ds = tosnap->os_dsl_dataset;
dsl_dataset_t *fromds = fromsnap ? fromsnap->os_dsl_dataset : NULL;
dsl_pool_t *dp = ds->ds_dir->dd_pool;
int err;
uint64_t size;
/* tosnap must be a snapshot */
if (ds->ds_phys->ds_next_snap_obj == 0)
return (EINVAL);
/* fromsnap must be an earlier snapshot from the same fs as tosnap */
if (fromds && (ds->ds_dir != fromds->ds_dir ||
fromds->ds_phys->ds_creation_txg >= ds->ds_phys->ds_creation_txg))
return (EXDEV);
if (fromorigin) {
if (fromsnap)
return (EINVAL);
if (dsl_dir_is_clone(ds->ds_dir)) {
rw_enter(&dp->dp_config_rwlock, RW_READER);
err = dsl_dataset_hold_obj(dp,
ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &fromds);
rw_exit(&dp->dp_config_rwlock);
if (err)
return (err);
} else {
fromorigin = B_FALSE;
}
}
/* Get uncompressed size estimate of changed data. */
if (fromds == NULL) {
size = ds->ds_phys->ds_uncompressed_bytes;
} else {
uint64_t used, comp;
err = dsl_dataset_space_written(fromds, ds,
&used, &comp, &size);
if (fromorigin)
dsl_dataset_rele(fromds, FTAG);
if (err)
return (err);
}
/*
* Assume that space (both on-disk and in-stream) is dominated by
* data. We will adjust for indirect blocks and the copies property,
* but ignore per-object space used (eg, dnodes and DRR_OBJECT records).
*/
/*
* Subtract out approximate space used by indirect blocks.
* Assume most space is used by data blocks (non-indirect, non-dnode).
* Assume all blocks are recordsize. Assume ditto blocks and
* internal fragmentation counter out compression.
*
* Therefore, space used by indirect blocks is sizeof(blkptr_t) per
* block, which we observe in practice.
*/
uint64_t recordsize;
rw_enter(&dp->dp_config_rwlock, RW_READER);
err = dsl_prop_get_ds(ds, "recordsize",
sizeof (recordsize), 1, &recordsize, NULL);
rw_exit(&dp->dp_config_rwlock);
if (err)
return (err);
size -= size / recordsize * sizeof (blkptr_t);
/* Add in the space for the record associated with each block. */
size += size / recordsize * sizeof (dmu_replay_record_t);
*sizep = size;
return (0);
}
struct recvbeginsyncarg {
const char *tofs;
const char *tosnap;
@ -1540,7 +1637,7 @@ dmu_recv_existing_end(dmu_recv_cookie_t *drc)
{
struct recvendsyncarg resa;
dsl_dataset_t *ds = drc->drc_logical_ds;
int err;
int err, myerr;
/*
* XXX hack; seems the ds is still dirty and dsl_pool_zil_clean()
@ -1578,7 +1675,8 @@ out:
if (err == 0 && drc->drc_guid_to_ds_map != NULL)
(void) add_ds_to_guidmap(drc->drc_guid_to_ds_map, ds);
dsl_dataset_disown(ds, dmu_recv_tag);
(void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag, B_FALSE);
myerr = dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag, B_FALSE);
ASSERT3U(myerr, ==, 0);
return (err);
}

View File

@ -23,6 +23,7 @@
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Portions Copyright (c) 2011 Martin Matuska <mm@FreeBSD.org>
*/
#include <sys/dmu_objset.h>
@ -908,69 +909,95 @@ dsl_dataset_create_sync(dsl_dir_t *pdd, const char *lastname,
return (dsobj);
}
#ifdef __FreeBSD__
/* FreeBSD ioctl compat begin */
struct destroyarg {
dsl_sync_task_group_t *dstg;
char *snapname;
char *failed;
boolean_t defer;
nvlist_t *nvl;
const char *snapname;
};
static int
dsl_snapshot_destroy_one(const char *name, void *arg)
dsl_check_snap_cb(const char *name, void *arg)
{
struct destroyarg *da = arg;
dsl_dataset_t *ds;
int err;
char *dsname;
dsname = kmem_asprintf("%s@%s", name, da->snapname);
err = dsl_dataset_own(dsname, B_TRUE, da->dstg, &ds);
strfree(dsname);
if (err == 0) {
struct dsl_ds_destroyarg *dsda;
VERIFY(nvlist_add_boolean(da->nvl, dsname) == 0);
dsl_dataset_make_exclusive(ds, da->dstg);
dsda = kmem_zalloc(sizeof (struct dsl_ds_destroyarg), KM_SLEEP);
dsda->ds = ds;
dsda->defer = da->defer;
dsl_sync_task_create(da->dstg, dsl_dataset_destroy_check,
dsl_dataset_destroy_sync, dsda, da->dstg, 0);
} else if (err == ENOENT) {
err = 0;
} else {
(void) strcpy(da->failed, name);
}
return (err);
return (0);
}
/*
* Destroy 'snapname' in all descendants of 'fsname'.
*/
#pragma weak dmu_snapshots_destroy = dsl_snapshots_destroy
int
dsl_snapshots_destroy(char *fsname, char *snapname, boolean_t defer)
dmu_get_recursive_snaps_nvl(const char *fsname, const char *snapname,
nvlist_t *snaps)
{
struct destroyarg *da;
int err;
da = kmem_zalloc(sizeof (struct destroyarg), KM_SLEEP);
da->nvl = snaps;
da->snapname = snapname;
err = dmu_objset_find(fsname, dsl_check_snap_cb, da,
DS_FIND_CHILDREN);
kmem_free(da, sizeof (struct destroyarg));
return (err);
}
/* FreeBSD ioctl compat end */
#endif /* __FreeBSD__ */
/*
* The snapshots must all be in the same pool.
*/
int
dmu_snapshots_destroy_nvl(nvlist_t *snaps, boolean_t defer, char *failed)
{
int err;
struct destroyarg da;
dsl_sync_task_t *dst;
spa_t *spa;
nvpair_t *pair;
dsl_sync_task_group_t *dstg;
err = spa_open(fsname, &spa, FTAG);
pair = nvlist_next_nvpair(snaps, NULL);
if (pair == NULL)
return (0);
err = spa_open(nvpair_name(pair), &spa, FTAG);
if (err)
return (err);
da.dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
da.snapname = snapname;
da.failed = fsname;
da.defer = defer;
dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
err = dmu_objset_find(fsname,
dsl_snapshot_destroy_one, &da, DS_FIND_CHILDREN);
for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
pair = nvlist_next_nvpair(snaps, pair)) {
dsl_dataset_t *ds;
int err;
err = dsl_dataset_own(nvpair_name(pair), B_TRUE, dstg, &ds);
if (err == 0) {
struct dsl_ds_destroyarg *dsda;
dsl_dataset_make_exclusive(ds, dstg);
dsda = kmem_zalloc(sizeof (struct dsl_ds_destroyarg),
KM_SLEEP);
dsda->ds = ds;
dsda->defer = defer;
dsl_sync_task_create(dstg, dsl_dataset_destroy_check,
dsl_dataset_destroy_sync, dsda, dstg, 0);
} else if (err == ENOENT) {
err = 0;
} else {
(void) strcpy(failed, nvpair_name(pair));
break;
}
}
if (err == 0)
err = dsl_sync_task_group_wait(da.dstg);
err = dsl_sync_task_group_wait(dstg);
for (dst = list_head(&da.dstg->dstg_tasks); dst;
dst = list_next(&da.dstg->dstg_tasks, dst)) {
for (dst = list_head(&dstg->dstg_tasks); dst;
dst = list_next(&dstg->dstg_tasks, dst)) {
struct dsl_ds_destroyarg *dsda = dst->dst_arg1;
dsl_dataset_t *ds = dsda->ds;
@ -978,17 +1005,17 @@ dsl_snapshots_destroy(char *fsname, char *snapname, boolean_t defer)
* Return the file system name that triggered the error
*/
if (dst->dst_err) {
dsl_dataset_name(ds, fsname);
*strchr(fsname, '@') = '\0';
dsl_dataset_name(ds, failed);
}
ASSERT3P(dsda->rm_origin, ==, NULL);
dsl_dataset_disown(ds, da.dstg);
dsl_dataset_disown(ds, dstg);
kmem_free(dsda, sizeof (struct dsl_ds_destroyarg));
}
dsl_sync_task_group_destroy(da.dstg);
dsl_sync_task_group_destroy(dstg);
spa_close(spa, FTAG);
return (err);
}
static boolean_t
@ -2150,6 +2177,55 @@ dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx)
dmu_objset_sync(ds->ds_objset, zio, tx);
}
static void
get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv)
{
uint64_t count = 0;
objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
zap_cursor_t zc;
zap_attribute_t za;
nvlist_t *propval;
nvlist_t *val;
rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER);
VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
VERIFY(nvlist_alloc(&val, NV_UNIQUE_NAME, KM_SLEEP) == 0);
/*
* There may me missing entries in ds_next_clones_obj
* due to a bug in a previous version of the code.
* Only trust it if it has the right number of entries.
*/
if (ds->ds_phys->ds_next_clones_obj != 0) {
ASSERT3U(0, ==, zap_count(mos, ds->ds_phys->ds_next_clones_obj,
&count));
}
if (count != ds->ds_phys->ds_num_children - 1) {
goto fail;
}
for (zap_cursor_init(&zc, mos, ds->ds_phys->ds_next_clones_obj);
zap_cursor_retrieve(&zc, &za) == 0;
zap_cursor_advance(&zc)) {
dsl_dataset_t *clone;
char buf[ZFS_MAXNAMELEN];
if (dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
za.za_first_integer, FTAG, &clone) != 0) {
goto fail;
}
dsl_dir_name(clone->ds_dir, buf);
VERIFY(nvlist_add_boolean(val, buf) == 0);
dsl_dataset_rele(clone, FTAG);
}
zap_cursor_fini(&zc);
VERIFY(nvlist_add_nvlist(propval, ZPROP_VALUE, val) == 0);
VERIFY(nvlist_add_nvlist(nv, zfs_prop_to_name(ZFS_PROP_CLONES),
propval) == 0);
fail:
nvlist_free(val);
nvlist_free(propval);
rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock);
}
void
dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
{
@ -2180,6 +2256,26 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_DEFER_DESTROY,
DS_IS_DEFER_DESTROY(ds) ? 1 : 0);
if (ds->ds_phys->ds_prev_snap_obj != 0) {
uint64_t written, comp, uncomp;
dsl_pool_t *dp = ds->ds_dir->dd_pool;
dsl_dataset_t *prev;
rw_enter(&dp->dp_config_rwlock, RW_READER);
int err = dsl_dataset_hold_obj(dp,
ds->ds_phys->ds_prev_snap_obj, FTAG, &prev);
rw_exit(&dp->dp_config_rwlock);
if (err == 0) {
err = dsl_dataset_space_written(prev, ds, &written,
&comp, &uncomp);
dsl_dataset_rele(prev, FTAG);
if (err == 0) {
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_WRITTEN,
written);
}
}
}
ratio = ds->ds_phys->ds_compressed_bytes == 0 ? 100 :
(ds->ds_phys->ds_uncompressed_bytes * 100 /
ds->ds_phys->ds_compressed_bytes);
@ -2193,6 +2289,8 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED,
ds->ds_phys->ds_unique_bytes);
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, ratio);
get_clones_stat(ds, nv);
}
}
@ -4025,7 +4123,7 @@ dsl_dataset_get_holds(const char *dsname, nvlist_t **nvp)
}
/*
* Note, this fuction is used as the callback for dmu_objset_find(). We
* Note, this function is used as the callback for dmu_objset_find(). We
* always return 0 so that we will continue to find and process
* inconsistent datasets, even if we encounter an error trying to
* process one of them.
@ -4044,3 +4142,151 @@ dsl_destroy_inconsistent(const char *dsname, void *arg)
}
return (0);
}
/*
* Return (in *usedp) the amount of space written in new that is not
* present in oldsnap. New may be a snapshot or the head. Old must be
* a snapshot before new, in new's filesystem (or its origin). If not then
* fail and return EINVAL.
*
* The written space is calculated by considering two components: First, we
* ignore any freed space, and calculate the written as new's used space
* minus old's used space. Next, we add in the amount of space that was freed
* between the two snapshots, thus reducing new's used space relative to old's.
* Specifically, this is the space that was born before old->ds_creation_txg,
* and freed before new (ie. on new's deadlist or a previous deadlist).
*
* space freed [---------------------]
* snapshots ---O-------O--------O-------O------
* oldsnap new
*/
int
dsl_dataset_space_written(dsl_dataset_t *oldsnap, dsl_dataset_t *new,
uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
{
int err = 0;
uint64_t snapobj;
dsl_pool_t *dp = new->ds_dir->dd_pool;
*usedp = 0;
*usedp += new->ds_phys->ds_used_bytes;
*usedp -= oldsnap->ds_phys->ds_used_bytes;
*compp = 0;
*compp += new->ds_phys->ds_compressed_bytes;
*compp -= oldsnap->ds_phys->ds_compressed_bytes;
*uncompp = 0;
*uncompp += new->ds_phys->ds_uncompressed_bytes;
*uncompp -= oldsnap->ds_phys->ds_uncompressed_bytes;
rw_enter(&dp->dp_config_rwlock, RW_READER);
snapobj = new->ds_object;
while (snapobj != oldsnap->ds_object) {
dsl_dataset_t *snap;
uint64_t used, comp, uncomp;
err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &snap);
if (err != 0)
break;
if (snap->ds_phys->ds_prev_snap_txg ==
oldsnap->ds_phys->ds_creation_txg) {
/*
* The blocks in the deadlist can not be born after
* ds_prev_snap_txg, so get the whole deadlist space,
* which is more efficient (especially for old-format
* deadlists). Unfortunately the deadlist code
* doesn't have enough information to make this
* optimization itself.
*/
dsl_deadlist_space(&snap->ds_deadlist,
&used, &comp, &uncomp);
} else {
dsl_deadlist_space_range(&snap->ds_deadlist,
0, oldsnap->ds_phys->ds_creation_txg,
&used, &comp, &uncomp);
}
*usedp += used;
*compp += comp;
*uncompp += uncomp;
/*
* If we get to the beginning of the chain of snapshots
* (ds_prev_snap_obj == 0) before oldsnap, then oldsnap
* was not a snapshot of/before new.
*/
snapobj = snap->ds_phys->ds_prev_snap_obj;
dsl_dataset_rele(snap, FTAG);
if (snapobj == 0) {
err = EINVAL;
break;
}
}
rw_exit(&dp->dp_config_rwlock);
return (err);
}
/*
* Return (in *usedp) the amount of space that will be reclaimed if firstsnap,
* lastsnap, and all snapshots in between are deleted.
*
* blocks that would be freed [---------------------------]
* snapshots ---O-------O--------O-------O--------O
* firstsnap lastsnap
*
* This is the set of blocks that were born after the snap before firstsnap,
* (birth > firstsnap->prev_snap_txg) and died before the snap after the
* last snap (ie, is on lastsnap->ds_next->ds_deadlist or an earlier deadlist).
* We calculate this by iterating over the relevant deadlists (from the snap
* after lastsnap, backward to the snap after firstsnap), summing up the
* space on the deadlist that was born after the snap before firstsnap.
*/
int
dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap,
dsl_dataset_t *lastsnap,
uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
{
int err = 0;
uint64_t snapobj;
dsl_pool_t *dp = firstsnap->ds_dir->dd_pool;
ASSERT(dsl_dataset_is_snapshot(firstsnap));
ASSERT(dsl_dataset_is_snapshot(lastsnap));
/*
* Check that the snapshots are in the same dsl_dir, and firstsnap
* is before lastsnap.
*/
if (firstsnap->ds_dir != lastsnap->ds_dir ||
firstsnap->ds_phys->ds_creation_txg >
lastsnap->ds_phys->ds_creation_txg)
return (EINVAL);
*usedp = *compp = *uncompp = 0;
rw_enter(&dp->dp_config_rwlock, RW_READER);
snapobj = lastsnap->ds_phys->ds_next_snap_obj;
while (snapobj != firstsnap->ds_object) {
dsl_dataset_t *ds;
uint64_t used, comp, uncomp;
err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &ds);
if (err != 0)
break;
dsl_deadlist_space_range(&ds->ds_deadlist,
firstsnap->ds_phys->ds_prev_snap_txg, UINT64_MAX,
&used, &comp, &uncomp);
*usedp += used;
*compp += comp;
*uncompp += uncomp;
snapobj = ds->ds_phys->ds_prev_snap_obj;
ASSERT3U(snapobj, !=, 0);
dsl_dataset_rele(ds, FTAG);
}
rw_exit(&dp->dp_config_rwlock);
return (err);
}

View File

@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/dsl_dataset.h>
@ -29,6 +30,26 @@
#include <sys/zfs_context.h>
#include <sys/dsl_pool.h>
/*
* Deadlist concurrency:
*
* Deadlists can only be modified from the syncing thread.
*
* Except for dsl_deadlist_insert(), it can only be modified with the
* dp_config_rwlock held with RW_WRITER.
*
* The accessors (dsl_deadlist_space() and dsl_deadlist_space_range()) can
* be called concurrently, from open context, with the dl_config_rwlock held
* with RW_READER.
*
* Therefore, we only need to provide locking between dsl_deadlist_insert() and
* the accessors, protecting:
* dl_phys->dl_used,comp,uncomp
* and protecting the dl_tree from being loaded.
* The locking is provided by dl_lock. Note that locking on the bpobj_t
* provides its own locking, and dl_oldfmt is immutable.
*/
static int
dsl_deadlist_compare(const void *arg1, const void *arg2)
{
@ -309,14 +330,14 @@ dsl_deadlist_space(dsl_deadlist_t *dl,
* return space used in the range (mintxg, maxtxg].
* Includes maxtxg, does not include mintxg.
* mintxg and maxtxg must both be keys in the deadlist (unless maxtxg is
* UINT64_MAX).
* larger than any bp in the deadlist (eg. UINT64_MAX)).
*/
void
dsl_deadlist_space_range(dsl_deadlist_t *dl, uint64_t mintxg, uint64_t maxtxg,
uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
{
dsl_deadlist_entry_t dle_tofind;
dsl_deadlist_entry_t *dle;
dsl_deadlist_entry_t dle_tofind;
avl_index_t where;
if (dl->dl_oldfmt) {
@ -325,9 +346,10 @@ dsl_deadlist_space_range(dsl_deadlist_t *dl, uint64_t mintxg, uint64_t maxtxg,
return;
}
dsl_deadlist_load_tree(dl);
*usedp = *compp = *uncompp = 0;
mutex_enter(&dl->dl_lock);
dsl_deadlist_load_tree(dl);
dle_tofind.dle_mintxg = mintxg;
dle = avl_find(&dl->dl_tree, &dle_tofind, &where);
/*
@ -336,6 +358,7 @@ dsl_deadlist_space_range(dsl_deadlist_t *dl, uint64_t mintxg, uint64_t maxtxg,
*/
ASSERT(dle != NULL ||
avl_nearest(&dl->dl_tree, where, AVL_AFTER) == NULL);
for (; dle && dle->dle_mintxg < maxtxg;
dle = AVL_NEXT(&dl->dl_tree, dle)) {
uint64_t used, comp, uncomp;
@ -347,6 +370,7 @@ dsl_deadlist_space_range(dsl_deadlist_t *dl, uint64_t mintxg, uint64_t maxtxg,
*compp += comp;
*uncompp += uncomp;
}
mutex_exit(&dl->dl_lock);
}
static void

View File

@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
/*
@ -525,10 +526,12 @@ dsl_load_user_sets(objset_t *mos, uint64_t zapobj, avl_tree_t *avl,
}
/*
* Check if user has requested permission.
* Check if user has requested permission. If descendent is set, must have
* descendent perms.
*/
int
dsl_deleg_access_impl(dsl_dataset_t *ds, const char *perm, cred_t *cr)
dsl_deleg_access_impl(dsl_dataset_t *ds, boolean_t descendent, const char *perm,
cred_t *cr)
{
dsl_dir_t *dd;
dsl_pool_t *dp;
@ -549,7 +552,7 @@ dsl_deleg_access_impl(dsl_dataset_t *ds, const char *perm, cred_t *cr)
SPA_VERSION_DELEGATED_PERMS)
return (EPERM);
if (dsl_dataset_is_snapshot(ds)) {
if (dsl_dataset_is_snapshot(ds) || descendent) {
/*
* Snapshots are treated as descendents only,
* local permissions do not apply.
@ -642,7 +645,7 @@ dsl_deleg_access(const char *dsname, const char *perm, cred_t *cr)
if (error)
return (error);
error = dsl_deleg_access_impl(ds, perm, cr);
error = dsl_deleg_access_impl(ds, B_FALSE, perm, cr);
dsl_dataset_rele(ds, FTAG);
return (error);

View File

@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/dsl_pool.h>
@ -316,7 +317,10 @@ static int
deadlist_enqueue_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
{
dsl_deadlist_t *dl = arg;
dsl_pool_t *dp = dmu_objset_pool(dl->dl_os);
rw_enter(&dp->dp_config_rwlock, RW_READER);
dsl_deadlist_insert(dl, bp, tx);
rw_exit(&dp->dp_config_rwlock);
return (0);
}

View File

@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
/*
@ -212,6 +213,11 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp)
spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src);
if (spa->spa_comment != NULL) {
spa_prop_add_list(*nvp, ZPOOL_PROP_COMMENT, spa->spa_comment,
0, ZPROP_SRC_LOCAL);
}
if (spa->spa_root != NULL)
spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root,
0, ZPROP_SRC_LOCAL);
@ -351,7 +357,7 @@ spa_prop_validate(spa_t *spa, nvlist_t *props)
char *propname, *strval;
uint64_t intval;
objset_t *os;
char *slash;
char *slash, *check;
propname = nvpair_name(elem);
@ -471,6 +477,26 @@ spa_prop_validate(spa_t *spa, nvlist_t *props)
error = EINVAL;
break;
case ZPOOL_PROP_COMMENT:
if ((error = nvpair_value_string(elem, &strval)) != 0)
break;
for (check = strval; *check != '\0'; check++) {
/*
* The kernel doesn't have an easy isprint()
* check. For this kernel check, we merely
* check ASCII apart from DEL. Fix this if
* there is an easy-to-use kernel isprint().
*/
if (*check >= 0x7f) {
error = EINVAL;
break;
}
check++;
}
if (strlen(strval) > ZPROP_MAX_COMMENT)
error = E2BIG;
break;
case ZPOOL_PROP_DEDUPDITTO:
if (spa_version(spa) < SPA_VERSION_DEDUP)
error = ENOTSUP;
@ -571,6 +597,43 @@ spa_prop_clear_bootfs(spa_t *spa, uint64_t dsobj, dmu_tx_t *tx)
}
}
/*
* Change the GUID for the pool. This is done so that we can later
* re-import a pool built from a clone of our own vdevs. We will modify
* the root vdev's guid, our own pool guid, and then mark all of our
* vdevs dirty. Note that we must make sure that all our vdevs are
* online when we do this, or else any vdevs that weren't present
* would be orphaned from our pool. We are also going to issue a
* sysevent to update any watchers.
*/
int
spa_change_guid(spa_t *spa)
{
uint64_t oldguid, newguid;
uint64_t txg;
if (!(spa_mode_global & FWRITE))
return (EROFS);
txg = spa_vdev_enter(spa);
if (spa->spa_root_vdev->vdev_state != VDEV_STATE_HEALTHY)
return (spa_vdev_exit(spa, NULL, txg, ENXIO));
oldguid = spa_guid(spa);
newguid = spa_generate_guid(NULL);
ASSERT3U(oldguid, !=, newguid);
spa->spa_root_vdev->vdev_guid = newguid;
spa->spa_root_vdev->vdev_guid_sum += (newguid - oldguid);
vdev_config_dirty(spa->spa_root_vdev);
spa_event_notify(spa, NULL, ESC_ZFS_POOL_REGUID);
return (spa_vdev_exit(spa, NULL, txg, 0));
}
/*
* ==========================================================================
* SPA state manipulation (open/create/destroy/import/export)
@ -1025,6 +1088,11 @@ spa_unload(spa_t *spa)
spa->spa_async_suspended = 0;
if (spa->spa_comment != NULL) {
spa_strfree(spa->spa_comment);
spa->spa_comment = NULL;
}
spa_config_exit(spa, SCL_ALL, FTAG);
}
@ -1742,6 +1810,7 @@ spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type,
{
nvlist_t *config = spa->spa_config;
char *ereport = FM_EREPORT_ZFS_POOL;
char *comment;
int error;
uint64_t pool_guid;
nvlist_t *nvl;
@ -1749,6 +1818,10 @@ spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type,
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pool_guid))
return (EINVAL);
ASSERT(spa->spa_comment == NULL);
if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
spa->spa_comment = spa_strdup(comment);
/*
* Versioning wasn't explicitly added to the label until later, so if
* it's not present treat it as the initial version.
@ -1764,7 +1837,7 @@ spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type,
spa_guid_exists(pool_guid, 0)) {
error = EEXIST;
} else {
spa->spa_load_guid = pool_guid;
spa->spa_config_guid = pool_guid;
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_SPLIT,
&nvl) == 0) {
@ -5380,6 +5453,20 @@ spa_sync_props(void *arg1, void *arg2, dmu_tx_t *tx)
* properties.
*/
break;
case ZPOOL_PROP_COMMENT:
VERIFY(nvpair_value_string(elem, &strval) == 0);
if (spa->spa_comment != NULL)
spa_strfree(spa->spa_comment);
spa->spa_comment = spa_strdup(strval);
/*
* We need to dirty the configuration on all the vdevs
* so that their labels get updated. It's unnecessary
* to do this for pool creation since the vdev's
* configuratoin has already been dirtied.
*/
if (tx->tx_txg != TXG_INITIAL)
vdev_config_dirty(spa->spa_root_vdev);
break;
default:
/*
* Set pool property values in the poolprops mos object.

View File

@ -21,6 +21,8 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@ -343,6 +345,10 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
txg) == 0);
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID,
spa_guid(spa)) == 0);
VERIFY(spa->spa_comment == NULL || nvlist_add_string(config,
ZPOOL_CONFIG_COMMENT, spa->spa_comment) == 0);
#ifdef _KERNEL
hostid = zone_get_hostid(NULL);
#else /* _KERNEL */

View File

@ -21,6 +21,7 @@
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/spa.h>
@ -101,11 +102,11 @@ spa_history_create_obj(spa_t *spa, dmu_tx_t *tx)
/*
* Figure out maximum size of history log. We set it at
* 1% of pool size, with a max of 32MB and min of 128KB.
* 0.1% of pool size, with a max of 1G and min of 128KB.
*/
shpp->sh_phys_max_off =
metaslab_class_get_dspace(spa_normal_class(spa)) / 100;
shpp->sh_phys_max_off = MIN(shpp->sh_phys_max_off, 32<<20);
metaslab_class_get_dspace(spa_normal_class(spa)) / 1000;
shpp->sh_phys_max_off = MIN(shpp->sh_phys_max_off, 1<<30);
shpp->sh_phys_max_off = MAX(shpp->sh_phys_max_off, 128<<10);
dmu_buf_rele(dbp, FTAG);

View File

@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/zfs_context.h>
@ -1308,13 +1309,24 @@ spa_guid(spa_t *spa)
/*
* If we fail to parse the config during spa_load(), we can go through
* the error path (which posts an ereport) and end up here with no root
* vdev. We stash the original pool guid in 'spa_load_guid' to handle
* vdev. We stash the original pool guid in 'spa_config_guid' to handle
* this case.
*/
if (spa->spa_root_vdev != NULL)
return (spa->spa_root_vdev->vdev_guid);
else
return (spa->spa_load_guid);
return (spa->spa_config_guid);
}
uint64_t
spa_load_guid(spa_t *spa)
{
/*
* This is a GUID that exists solely as a reference for the
* purposes of the arc. It is generated at load time, and
* is never written to persistent storage.
*/
return (spa->spa_load_guid);
}
uint64_t

View File

@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
@ -194,7 +195,9 @@ int dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags,
int dmu_objset_clone(const char *name, struct dsl_dataset *clone_origin,
uint64_t flags);
int dmu_objset_destroy(const char *name, boolean_t defer);
int dmu_snapshots_destroy(char *fsname, char *snapname, boolean_t defer);
int dmu_get_recursive_snaps_nvl(const char *fsname, const char *snapname,
struct nvlist *snaps);
int dmu_snapshots_destroy_nvl(struct nvlist *snaps, boolean_t defer, char *);
int dmu_objset_snapshot(char *fsname, char *snapname, char *tag,
struct nvlist *props, boolean_t recursive, boolean_t temporary, int fd);
int dmu_objset_rename(const char *name, const char *newname,
@ -705,6 +708,8 @@ void dmu_traverse_objset(objset_t *os, uint64_t txg_start,
int dmu_sendbackup(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
struct file *fp, offset_t *off);
int dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap,
boolean_t fromorigin, uint64_t *sizep);
typedef struct dmu_recv_cookie {
/*

View File

@ -22,6 +22,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#ifndef _SYS_DSL_DATASET_H
@ -257,6 +258,10 @@ void dsl_dataset_space(dsl_dataset_t *ds,
uint64_t *refdbytesp, uint64_t *availbytesp,
uint64_t *usedobjsp, uint64_t *availobjsp);
uint64_t dsl_dataset_fsid_guid(dsl_dataset_t *ds);
int dsl_dataset_space_written(dsl_dataset_t *oldsnap, dsl_dataset_t *new,
uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
int dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap, dsl_dataset_t *last,
uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
int dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf);

View File

@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#ifndef _SYS_DSL_DELEG_H
@ -64,7 +65,8 @@ extern "C" {
int dsl_deleg_get(const char *ddname, nvlist_t **nvp);
int dsl_deleg_set(const char *ddname, nvlist_t *nvp, boolean_t unset);
int dsl_deleg_access(const char *ddname, const char *perm, cred_t *cr);
int dsl_deleg_access_impl(struct dsl_dataset *ds, const char *perm, cred_t *cr);
int dsl_deleg_access_impl(struct dsl_dataset *ds, boolean_t descendent,
const char *perm, cred_t *cr);
void dsl_deleg_set_create_perms(dsl_dir_t *dd, dmu_tx_t *tx, cred_t *cr);
int dsl_deleg_can_allow(char *ddname, nvlist_t *nvp, cred_t *cr);
int dsl_deleg_can_unallow(char *ddname, nvlist_t *nvp, cred_t *cr);

View File

@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _SYS_SPA_H
@ -578,6 +579,7 @@ extern void spa_altroot(spa_t *, char *, size_t);
extern int spa_sync_pass(spa_t *spa);
extern char *spa_name(spa_t *spa);
extern uint64_t spa_guid(spa_t *spa);
extern uint64_t spa_load_guid(spa_t *spa);
extern uint64_t spa_last_synced_txg(spa_t *spa);
extern uint64_t spa_first_txg(spa_t *spa);
extern uint64_t spa_syncing_txg(spa_t *spa);
@ -611,6 +613,7 @@ extern uint64_t spa_get_random(uint64_t range);
extern uint64_t spa_generate_guid(spa_t *spa);
extern void sprintf_blkptr(char *buf, const blkptr_t *bp);
extern void spa_freeze(spa_t *spa);
extern int spa_change_guid(spa_t *spa);
extern void spa_upgrade(spa_t *spa, uint64_t version);
extern void spa_evict_all(void);
extern vdev_t *spa_lookup_by_guid(spa_t *spa, uint64_t guid,

View File

@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _SYS_SPA_IMPL_H
@ -111,6 +112,7 @@ struct spa {
* Fields protected by spa_namespace_lock.
*/
char spa_name[MAXNAMELEN]; /* pool name */
char *spa_comment; /* comment */
avl_node_t spa_avl; /* node in spa_namespace_avl */
nvlist_t *spa_config; /* last synced config */
nvlist_t *spa_config_syncing; /* currently syncing config */
@ -136,7 +138,8 @@ struct spa {
objset_t *spa_meta_objset; /* copy of dp->dp_meta_objset */
txg_list_t spa_vdev_txg_list; /* per-txg dirty vdev list */
vdev_t *spa_root_vdev; /* top-level vdev container */
uint64_t spa_load_guid; /* initial guid for spa_load */
uint64_t spa_config_guid; /* config pool guid */
uint64_t spa_load_guid; /* spa_load initialized guid */
list_t spa_config_dirty_list; /* vdevs with dirty config */
list_t spa_state_dirty_list; /* vdevs with dirty state */
spa_aux_vdev_t spa_spares; /* hot spares */

View File

@ -21,6 +21,8 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@ -297,6 +299,7 @@ vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops)
if (spa->spa_root_vdev == NULL) {
ASSERT(ops == &vdev_root_ops);
spa->spa_root_vdev = vd;
spa->spa_load_guid = spa_generate_guid(NULL);
}
if (guid == 0 && ops != &vdev_hole_ops) {

View File

@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/zio.h>
@ -1414,7 +1415,7 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
}
/*
* We lock the zap with adding == FALSE. Because, if we pass
* We lock the zap with adding == FALSE. Because, if we pass
* the actual value of add, it could trigger a mzap_upgrade().
* At present we are just evaluating the possibility of this operation
* and hence we donot want to trigger an upgrade.

View File

@ -23,6 +23,8 @@
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Portions Copyright 2011 Martin Matuska <mm@FreeBSD.org>
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <sys/types.h>
@ -348,17 +350,37 @@ zfs_dozonecheck_ds(const char *dataset, dsl_dataset_t *ds, cred_t *cr)
return (zfs_dozonecheck_impl(dataset, zoned, cr));
}
/*
* If name ends in a '@', then require recursive permissions.
*/
int
zfs_secpolicy_write_perms(const char *name, const char *perm, cred_t *cr)
{
int error;
boolean_t descendent = B_FALSE;
dsl_dataset_t *ds;
char *at;
error = zfs_dozonecheck(name, cr);
at = strchr(name, '@');
if (at != NULL && at[1] == '\0') {
*at = '\0';
descendent = B_TRUE;
}
error = dsl_dataset_hold(name, FTAG, &ds);
if (at != NULL)
*at = '@';
if (error != 0)
return (error);
error = zfs_dozonecheck_ds(name, ds, cr);
if (error == 0) {
error = secpolicy_zfs(cr);
if (error)
error = dsl_deleg_access(name, perm, cr);
error = dsl_deleg_access_impl(ds, descendent, perm, cr);
}
dsl_dataset_rele(ds, FTAG);
return (error);
}
@ -372,7 +394,7 @@ zfs_secpolicy_write_perms_ds(const char *name, dsl_dataset_t *ds,
if (error == 0) {
error = secpolicy_zfs(cr);
if (error)
error = dsl_deleg_access_impl(ds, perm, cr);
error = dsl_deleg_access_impl(ds, B_FALSE, perm, cr);
}
return (error);
}
@ -685,24 +707,14 @@ zfs_secpolicy_destroy(zfs_cmd_t *zc, cred_t *cr)
/*
* Destroying snapshots with delegated permissions requires
* descendent mount and destroy permissions.
* Reassemble the full filesystem@snap name so dsl_deleg_access()
* can do the correct permission check.
*
* Since this routine is used when doing a recursive destroy of snapshots
* and destroying snapshots requires descendent permissions, a successfull
* check of the top level snapshot applies to snapshots of all descendent
* datasets as well.
*
* The top level snapshot may not exist when doing a recursive destroy.
* In this case fallback to permissions of the parent dataset.
*/
static int
zfs_secpolicy_destroy_snaps(zfs_cmd_t *zc, cred_t *cr)
zfs_secpolicy_destroy_recursive(zfs_cmd_t *zc, cred_t *cr)
{
int error;
char *dsname;
dsname = kmem_asprintf("%s@%s", zc->zc_name, zc->zc_value);
dsname = kmem_asprintf("%s@", zc->zc_name);
error = zfs_secpolicy_destroy_perms(dsname, cr);
@ -1468,6 +1480,20 @@ zfs_ioc_pool_get_history(zfs_cmd_t *zc)
return (error);
}
static int
zfs_ioc_pool_reguid(zfs_cmd_t *zc)
{
spa_t *spa;
int error;
error = spa_open(zc->zc_name, &spa, FTAG);
if (error == 0) {
error = spa_change_guid(spa);
spa_close(spa, FTAG);
}
return (error);
}
static int
zfs_ioc_dsobj_to_dsname(zfs_cmd_t *zc)
{
@ -1765,9 +1791,12 @@ zfs_ioc_objset_stats_impl(zfs_cmd_t *zc, objset_t *os)
* inconsistent. So this is a bit of a workaround...
* XXX reading with out owning
*/
if (!zc->zc_objset_stats.dds_inconsistent) {
if (dmu_objset_type(os) == DMU_OST_ZVOL)
VERIFY(zvol_get_stats(os, nv) == 0);
if (!zc->zc_objset_stats.dds_inconsistent &&
dmu_objset_type(os) == DMU_OST_ZVOL) {
error = zvol_get_stats(os, nv);
if (error == EIO)
return (error);
VERIFY3S(error, ==, 0);
}
error = put_nvlist(zc, nv);
nvlist_free(nv);
@ -1978,8 +2007,7 @@ top:
NULL, &zc->zc_cookie);
if (error == ENOENT)
error = ESRCH;
} while (error == 0 && dataset_name_hidden(zc->zc_name) &&
!(zc->zc_iflags & FKIOCTL));
} while (error == 0 && dataset_name_hidden(zc->zc_name));
dmu_objset_rele(os, FTAG);
/*
@ -2257,6 +2285,8 @@ retry:
if (nvpair_type(propval) !=
DATA_TYPE_UINT64_ARRAY)
err = EINVAL;
} else {
err = EINVAL;
}
} else if (err == 0) {
if (nvpair_type(propval) == DATA_TYPE_STRING) {
@ -3124,25 +3154,62 @@ zfs_unmount_snap(const char *name, void *arg)
/*
* inputs:
* zc_name name of filesystem
* zc_value short name of snapshot
* zc_name name of filesystem, snaps must be under it
* zc_nvlist_src[_size] full names of snapshots to destroy
* zc_defer_destroy mark for deferred destroy
*
* outputs: none
* outputs:
* zc_name on failure, name of failed snapshot
*/
static int
zfs_ioc_destroy_snaps(zfs_cmd_t *zc)
zfs_ioc_destroy_snaps_nvl(zfs_cmd_t *zc)
{
int err;
int err, len;
nvlist_t *nvl;
nvpair_t *pair;
if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
return (EINVAL);
err = dmu_objset_find(zc->zc_name,
zfs_unmount_snap, zc->zc_value, DS_FIND_CHILDREN);
if (err)
if ((err = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
zc->zc_iflags, &nvl)) != 0) {
#ifndef __FreeBSD__
return (err);
return (dmu_snapshots_destroy(zc->zc_name, zc->zc_value,
zc->zc_defer_destroy));
#else
/*
* We are probably called by older binaries,
* allocate and populate nvlist with recursive snapshots
*/
if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
return (EINVAL);
VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) == 0);
err = dmu_get_recursive_snaps_nvl(zc->zc_name,
zc->zc_value, nvl);
if (err) {
nvlist_free(nvl);
return (err);
}
#endif /* __FreeBSD__ */
}
len = strlen(zc->zc_name);
for (pair = nvlist_next_nvpair(nvl, NULL); pair != NULL;
pair = nvlist_next_nvpair(nvl, pair)) {
const char *name = nvpair_name(pair);
/*
* The snap name must be underneath the zc_name. This ensures
* that our permission checks were legitimate.
*/
if (strncmp(zc->zc_name, name, len) != 0 ||
(name[len] != '@' && name[len] != '/')) {
nvlist_free(nvl);
return (EINVAL);
}
(void) zfs_unmount_snap(name, NULL);
}
err = dmu_snapshots_destroy_nvl(nvl, zc->zc_defer_destroy,
zc->zc_name);
nvlist_free(nvl);
return (err);
}
/*
@ -3789,6 +3856,8 @@ out:
* zc_obj fromorigin flag (mutually exclusive with zc_fromobj)
* zc_sendobj objsetid of snapshot to send
* zc_fromobj objsetid of incremental fromsnap (may be zero)
* zc_guid if set, estimate size of stream only. zc_cookie is ignored.
* output size in zc_objset_type.
*
* outputs: none
*/
@ -3797,13 +3866,13 @@ zfs_ioc_send(zfs_cmd_t *zc)
{
objset_t *fromsnap = NULL;
objset_t *tosnap;
file_t *fp;
int error;
offset_t off;
dsl_dataset_t *ds;
dsl_dataset_t *dsfrom = NULL;
spa_t *spa;
dsl_pool_t *dp;
boolean_t estimate = (zc->zc_guid != 0);
error = spa_open(zc->zc_name, &spa, FTAG);
if (error)
@ -3844,20 +3913,25 @@ zfs_ioc_send(zfs_cmd_t *zc)
spa_close(spa, FTAG);
}
fp = getf(zc->zc_cookie);
if (fp == NULL) {
dsl_dataset_rele(ds, FTAG);
if (dsfrom)
dsl_dataset_rele(dsfrom, FTAG);
return (EBADF);
if (estimate) {
error = dmu_send_estimate(tosnap, fromsnap, zc->zc_obj,
&zc->zc_objset_type);
} else {
file_t *fp = getf(zc->zc_cookie);
if (fp == NULL) {
dsl_dataset_rele(ds, FTAG);
if (dsfrom)
dsl_dataset_rele(dsfrom, FTAG);
return (EBADF);
}
off = fp->f_offset;
error = dmu_sendbackup(tosnap, fromsnap, zc->zc_obj, fp, &off);
if (off >= 0 && off <= MAXOFFSET_T)
fp->f_offset = off;
releasef(zc->zc_cookie);
}
off = fp->f_offset;
error = dmu_sendbackup(tosnap, fromsnap, zc->zc_obj, fp, &off);
if (off >= 0 && off <= MAXOFFSET_T)
fp->f_offset = off;
releasef(zc->zc_cookie);
if (dsfrom)
dsl_dataset_rele(dsfrom, FTAG);
dsl_dataset_rele(ds, FTAG);
@ -4665,6 +4739,70 @@ zfs_ioc_get_holds(zfs_cmd_t *zc)
return (error);
}
/*
* inputs:
* zc_name name of new filesystem or snapshot
* zc_value full name of old snapshot
*
* outputs:
* zc_cookie space in bytes
* zc_objset_type compressed space in bytes
* zc_perm_action uncompressed space in bytes
*/
static int
zfs_ioc_space_written(zfs_cmd_t *zc)
{
int error;
dsl_dataset_t *new, *old;
error = dsl_dataset_hold(zc->zc_name, FTAG, &new);
if (error != 0)
return (error);
error = dsl_dataset_hold(zc->zc_value, FTAG, &old);
if (error != 0) {
dsl_dataset_rele(new, FTAG);
return (error);
}
error = dsl_dataset_space_written(old, new, &zc->zc_cookie,
&zc->zc_objset_type, &zc->zc_perm_action);
dsl_dataset_rele(old, FTAG);
dsl_dataset_rele(new, FTAG);
return (error);
}
/*
* inputs:
* zc_name full name of last snapshot
* zc_value full name of first snapshot
*
* outputs:
* zc_cookie space in bytes
* zc_objset_type compressed space in bytes
* zc_perm_action uncompressed space in bytes
*/
static int
zfs_ioc_space_snaps(zfs_cmd_t *zc)
{
int error;
dsl_dataset_t *new, *old;
error = dsl_dataset_hold(zc->zc_name, FTAG, &new);
if (error != 0)
return (error);
error = dsl_dataset_hold(zc->zc_value, FTAG, &old);
if (error != 0) {
dsl_dataset_rele(new, FTAG);
return (error);
}
error = dsl_dataset_space_wouldfree(old, new, &zc->zc_cookie,
&zc->zc_objset_type, &zc->zc_perm_action);
dsl_dataset_rele(old, FTAG);
dsl_dataset_rele(new, FTAG);
return (error);
}
/*
* pool create, destroy, and export don't log the history as part of
* zfsdev_ioctl, but rather zfs_ioc_pool_create, and zfs_ioc_pool_export
@ -4739,7 +4877,7 @@ static zfs_ioc_vec_t zfs_ioc_vec[] = {
B_TRUE },
{ zfs_ioc_rename, zfs_secpolicy_rename, DATASET_NAME, B_TRUE, B_TRUE },
{ zfs_ioc_recv, zfs_secpolicy_receive, DATASET_NAME, B_TRUE, B_TRUE },
{ zfs_ioc_send, zfs_secpolicy_send, DATASET_NAME, B_TRUE, B_FALSE },
{ zfs_ioc_send, zfs_secpolicy_send, DATASET_NAME, B_FALSE, B_FALSE },
{ zfs_ioc_inject_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE,
B_FALSE },
{ zfs_ioc_clear_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE,
@ -4751,7 +4889,7 @@ static zfs_ioc_vec_t zfs_ioc_vec[] = {
{ zfs_ioc_clear, zfs_secpolicy_config, POOL_NAME, B_TRUE, B_FALSE },
{ zfs_ioc_promote, zfs_secpolicy_promote, DATASET_NAME, B_TRUE,
B_TRUE },
{ zfs_ioc_destroy_snaps, zfs_secpolicy_destroy_snaps, DATASET_NAME,
{ zfs_ioc_destroy_snaps_nvl, zfs_secpolicy_destroy_recursive, DATASET_NAME,
B_TRUE, B_TRUE },
{ zfs_ioc_snapshot, zfs_secpolicy_snapshot, DATASET_NAME, B_TRUE,
B_TRUE },
@ -4795,7 +4933,13 @@ static zfs_ioc_vec_t zfs_ioc_vec[] = {
{ zfs_ioc_obj_to_stats, zfs_secpolicy_diff, DATASET_NAME, B_FALSE,
B_TRUE },
{ zfs_ioc_jail, zfs_secpolicy_config, DATASET_NAME, B_TRUE, B_FALSE },
{ zfs_ioc_unjail, zfs_secpolicy_config, DATASET_NAME, B_TRUE, B_FALSE }
{ zfs_ioc_unjail, zfs_secpolicy_config, DATASET_NAME, B_TRUE, B_FALSE },
{ zfs_ioc_pool_reguid, zfs_secpolicy_config, POOL_NAME, B_TRUE,
B_TRUE },
{ zfs_ioc_space_written, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
B_TRUE },
{ zfs_ioc_space_snaps, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
B_TRUE }
};
int

View File

@ -22,6 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/* Portions Copyright 2010 Robert Milkowski */
@ -126,6 +127,8 @@ typedef enum {
ZFS_PROP_MLSLABEL,
ZFS_PROP_SYNC,
ZFS_PROP_REFRATIO,
ZFS_PROP_WRITTEN,
ZFS_PROP_CLONES,
ZFS_NUM_PROPS
} zfs_prop_t;
@ -165,9 +168,13 @@ typedef enum {
ZPOOL_PROP_FREE,
ZPOOL_PROP_ALLOCATED,
ZPOOL_PROP_READONLY,
ZPOOL_PROP_COMMENT,
ZPOOL_NUM_PROPS
} zpool_prop_t;
/* Small enough to not hog a whole line of printout in zpool(1M). */
#define ZPROP_MAX_COMMENT 32
#define ZPROP_CONT -2
#define ZPROP_INVAL -1
@ -492,6 +499,7 @@ typedef struct zpool_rewind_policy {
#define ZPOOL_CONFIG_SPLIT_LIST "guid_list"
#define ZPOOL_CONFIG_REMOVING "removing"
#define ZPOOL_CONFIG_RESILVERING "resilvering"
#define ZPOOL_CONFIG_COMMENT "comment"
#define ZPOOL_CONFIG_SUSPENDED "suspended" /* not stored on disk */
#define ZPOOL_CONFIG_TIMESTAMP "timestamp" /* not stored on disk */
#define ZPOOL_CONFIG_BOOTFS "bootfs" /* not stored on disk */
@ -758,7 +766,7 @@ typedef unsigned long zfs_ioc_t;
#define ZFS_IOC_ERROR_LOG _IOWR('Z', 32, struct zfs_cmd)
#define ZFS_IOC_CLEAR _IOWR('Z', 33, struct zfs_cmd)
#define ZFS_IOC_PROMOTE _IOWR('Z', 34, struct zfs_cmd)
#define ZFS_IOC_DESTROY_SNAPS _IOWR('Z', 35, struct zfs_cmd)
#define ZFS_IOC_DESTROY_SNAPS_NVL _IOWR('Z', 35, struct zfs_cmd)
#define ZFS_IOC_SNAPSHOT _IOWR('Z', 36, struct zfs_cmd)
#define ZFS_IOC_DSOBJ_TO_DSNAME _IOWR('Z', 37, struct zfs_cmd)
#define ZFS_IOC_OBJ_TO_PATH _IOWR('Z', 38, struct zfs_cmd)
@ -783,6 +791,9 @@ typedef unsigned long zfs_ioc_t;
#define ZFS_IOC_OBJ_TO_STATS _IOWR('Z', 57, struct zfs_cmd)
#define ZFS_IOC_JAIL _IOWR('Z', 58, struct zfs_cmd)
#define ZFS_IOC_UNJAIL _IOWR('Z', 59, struct zfs_cmd)
#define ZFS_IOC_POOL_REGUID _IOWR('Z', 60, struct zfs_cmd)
#define ZFS_IOC_SPACE_WRITTEN _IOWR('Z', 61, struct zfs_cmd)
#define ZFS_IOC_SPACE_SNAPS _IOWR('Z', 62, struct zfs_cmd)
/*
* Internal SPA load state. Used by FMA diagnosis engine.
@ -844,6 +855,7 @@ typedef enum {
* ESC_ZFS_RESILVER_START
* ESC_ZFS_RESILVER_END
* ESC_ZFS_POOL_DESTROY
* ESC_ZFS_POOL_REGUID
*
* ZFS_EV_POOL_NAME DATA_TYPE_STRING
* ZFS_EV_POOL_GUID DATA_TYPE_UINT64

View File

@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _SYS_SYSEVENT_EVENTDEFS_H
@ -256,6 +257,7 @@ extern "C" {
#define ESC_ZFS_SCRUB_FINISH "ESC_ZFS_scrub_finish"
#define ESC_ZFS_VDEV_SPARE "ESC_ZFS_vdev_spare"
#define ESC_ZFS_BOOTFS_VDEV_ATTACH "ESC_ZFS_bootfs_vdev_attach"
#define ESC_ZFS_POOL_REGUID "ESC_ZFS_pool_reguid"
#define ESC_ZFS_VDEV_AUTOEXPAND "ESC_ZFS_vdev_autoexpand"
/*

View File

@ -172,6 +172,7 @@ contrib/dev/acpica/disassembler/dmopcode.c optional acpi acpi_debug
contrib/dev/acpica/disassembler/dmobject.c optional acpi acpi_debug
contrib/dev/acpica/disassembler/dmresrc.c optional acpi acpi_debug
contrib/dev/acpica/disassembler/dmresrcl.c optional acpi acpi_debug
contrib/dev/acpica/disassembler/dmresrcl2.c optional acpi acpi_debug
contrib/dev/acpica/disassembler/dmresrcs.c optional acpi acpi_debug
contrib/dev/acpica/disassembler/dmutils.c optional acpi acpi_debug
contrib/dev/acpica/disassembler/dmwalk.c optional acpi acpi_debug
@ -272,6 +273,7 @@ contrib/dev/acpica/resources/rsirq.c optional acpi
contrib/dev/acpica/resources/rslist.c optional acpi
contrib/dev/acpica/resources/rsmemory.c optional acpi
contrib/dev/acpica/resources/rsmisc.c optional acpi
contrib/dev/acpica/resources/rsserial.c optional acpi
contrib/dev/acpica/resources/rsutils.c optional acpi
contrib/dev/acpica/resources/rsxface.c optional acpi
contrib/dev/acpica/tables/tbfadt.c optional acpi
@ -300,6 +302,7 @@ contrib/dev/acpica/utilities/utresrc.c optional acpi
contrib/dev/acpica/utilities/utstate.c optional acpi
contrib/dev/acpica/utilities/utxface.c optional acpi
contrib/dev/acpica/utilities/utxferror.c optional acpi
#contrib/dev/acpica/utilities/utxfmutex.c optional acpi
contrib/ipfilter/netinet/fil.c optional ipfilter inet \
compile-with "${NORMAL_C} -I$S/contrib/ipfilter"
contrib/ipfilter/netinet/ip_auth.c optional ipfilter inet \
@ -1674,37 +1677,6 @@ dev/scd/scd.c optional scd isa
dev/scd/scd_isa.c optional scd isa
dev/sdhci/sdhci.c optional sdhci pci
dev/sf/if_sf.c optional sf pci
dev/sfxge/common/efx_bootcfg.c optional sfxge inet pci
dev/sfxge/common/efx_ev.c optional sfxge inet pci
dev/sfxge/common/efx_filter.c optional sfxge inet pci
dev/sfxge/common/efx_intr.c optional sfxge inet pci
dev/sfxge/common/efx_mac.c optional sfxge inet pci
dev/sfxge/common/efx_mcdi.c optional sfxge inet pci
dev/sfxge/common/efx_mon.c optional sfxge inet pci
dev/sfxge/common/efx_nic.c optional sfxge inet pci
dev/sfxge/common/efx_nvram.c optional sfxge inet pci
dev/sfxge/common/efx_phy.c optional sfxge inet pci
dev/sfxge/common/efx_port.c optional sfxge inet pci
dev/sfxge/common/efx_rx.c optional sfxge inet pci
dev/sfxge/common/efx_sram.c optional sfxge inet pci
dev/sfxge/common/efx_tx.c optional sfxge inet pci
dev/sfxge/common/efx_vpd.c optional sfxge inet pci
dev/sfxge/common/efx_wol.c optional sfxge inet pci
dev/sfxge/common/siena_mac.c optional sfxge inet pci
dev/sfxge/common/siena_mon.c optional sfxge inet pci
dev/sfxge/common/siena_nic.c optional sfxge inet pci
dev/sfxge/common/siena_nvram.c optional sfxge inet pci
dev/sfxge/common/siena_phy.c optional sfxge inet pci
dev/sfxge/common/siena_sram.c optional sfxge inet pci
dev/sfxge/common/siena_vpd.c optional sfxge inet pci
dev/sfxge/sfxge.c optional sfxge inet pci
dev/sfxge/sfxge_dma.c optional sfxge inet pci
dev/sfxge/sfxge_ev.c optional sfxge inet pci
dev/sfxge/sfxge_intr.c optional sfxge inet pci
dev/sfxge/sfxge_mcdi.c optional sfxge inet pci
dev/sfxge/sfxge_port.c optional sfxge inet pci
dev/sfxge/sfxge_rx.c optional sfxge inet pci
dev/sfxge/sfxge_tx.c optional sfxge inet pci
dev/sge/if_sge.c optional sge pci
dev/si/si.c optional si
dev/si/si2_z280.c optional si

View File

@ -214,6 +214,37 @@ dev/qlxgb/qla_ioctl.c optional qlxgb pci
dev/qlxgb/qla_isr.c optional qlxgb pci
dev/qlxgb/qla_misc.c optional qlxgb pci
dev/qlxgb/qla_os.c optional qlxgb pci
dev/sfxge/common/efx_bootcfg.c optional sfxge inet pci
dev/sfxge/common/efx_ev.c optional sfxge inet pci
dev/sfxge/common/efx_filter.c optional sfxge inet pci
dev/sfxge/common/efx_intr.c optional sfxge inet pci
dev/sfxge/common/efx_mac.c optional sfxge inet pci
dev/sfxge/common/efx_mcdi.c optional sfxge inet pci
dev/sfxge/common/efx_mon.c optional sfxge inet pci
dev/sfxge/common/efx_nic.c optional sfxge inet pci
dev/sfxge/common/efx_nvram.c optional sfxge inet pci
dev/sfxge/common/efx_phy.c optional sfxge inet pci
dev/sfxge/common/efx_port.c optional sfxge inet pci
dev/sfxge/common/efx_rx.c optional sfxge inet pci
dev/sfxge/common/efx_sram.c optional sfxge inet pci
dev/sfxge/common/efx_tx.c optional sfxge inet pci
dev/sfxge/common/efx_vpd.c optional sfxge inet pci
dev/sfxge/common/efx_wol.c optional sfxge inet pci
dev/sfxge/common/siena_mac.c optional sfxge inet pci
dev/sfxge/common/siena_mon.c optional sfxge inet pci
dev/sfxge/common/siena_nic.c optional sfxge inet pci
dev/sfxge/common/siena_nvram.c optional sfxge inet pci
dev/sfxge/common/siena_phy.c optional sfxge inet pci
dev/sfxge/common/siena_sram.c optional sfxge inet pci
dev/sfxge/common/siena_vpd.c optional sfxge inet pci
dev/sfxge/sfxge.c optional sfxge inet pci
dev/sfxge/sfxge_dma.c optional sfxge inet pci
dev/sfxge/sfxge_ev.c optional sfxge inet pci
dev/sfxge/sfxge_intr.c optional sfxge inet pci
dev/sfxge/sfxge_mcdi.c optional sfxge inet pci
dev/sfxge/sfxge_port.c optional sfxge inet pci
dev/sfxge/sfxge_rx.c optional sfxge inet pci
dev/sfxge/sfxge_tx.c optional sfxge inet pci
dev/sio/sio.c optional sio
dev/sio/sio_isa.c optional sio isa
dev/sio/sio_pccard.c optional sio pccard

View File

@ -126,10 +126,3 @@ CFLAGS+= -ffreestanding
${MACHINE_CPUARCH} != "arm" && ${MACHINE_CPUARCH} != "mips"
CFLAGS+= -fstack-protector
.endif
#
# Enable CTF conversation on request
#
.if defined(WITH_CTF)
.undef NO_CTF
.endif

View File

@ -94,7 +94,9 @@ ${FULLKERNEL}: ${SYSTEM_DEP} vers.o
@rm -f ${.TARGET}
@echo linking ${.TARGET}
${SYSTEM_LD}
@${SYSTEM_CTFMERGE}
.if ${MK_CTF} != "no"
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJS} vers.o
.endif
.if !defined(DEBUG)
${OBJCOPY} --strip-debug ${.TARGET}
.endif
@ -247,7 +249,7 @@ kernel-reinstall:
config.o env.o hints.o vers.o vnode_if.o:
${NORMAL_C}
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
${NORMAL_CTFCONVERT}
config.ln env.ln hints.ln vers.ln vnode_if.ln:
${NORMAL_LINT}

View File

@ -123,8 +123,13 @@ NORMAL_C_NOWERROR= ${CC} -c ${CFLAGS} ${PROF} ${.IMPSRC}
NORMAL_M= ${AWK} -f $S/tools/makeobjops.awk ${.IMPSRC} -c ; \
${CC} -c ${CFLAGS} ${WERROR} ${PROF} ${.PREFIX}.c
NORMAL_CTFCONVERT= [ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \
${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.if ${MK_CTF} != "no"
NORMAL_CTFCONVERT= ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.elif ${MAKE_VERSION} >= 5201111300
NORMAL_CTFCONVERT=
.else
NORMAL_CTFCONVERT= @:
.endif
NORMAL_LINT= ${LINT} ${LINTFLAGS} ${CFLAGS:M-[DIU]*} ${.IMPSRC}
@ -142,7 +147,6 @@ SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
SYSTEM_OBJS= locore.o ${MDOBJS} ${OBJS}
SYSTEM_OBJS+= ${SYSTEM_CFILES:.c=.o}
SYSTEM_OBJS+= hack.So
SYSTEM_CTFMERGE= [ -z "${CTFMERGE}" -o -n "${NO_CTF}" ] || ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJS} vers.o
SYSTEM_LD= @${LD} -Bdynamic -T ${LDSCRIPT} \
-warn-common -export-dynamic -dynamic-linker /red/herring \
-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o

View File

@ -72,11 +72,6 @@ OBJCOPY?= objcopy
.error "Do not use KMODDEPS on 5.0+; use MODULE_VERSION/MODULE_DEPEND"
.endif
# Enable CTF conversion on request.
.if defined(WITH_CTF)
.undef NO_CTF
.endif
.include <bsd.init.mk>
.SUFFIXES: .out .o .c .cc .cxx .C .y .l .s .S
@ -206,7 +201,9 @@ ${KMOD}.kld: ${OBJS}
${FULLPROG}: ${OBJS}
.endif
${LD} ${LDFLAGS} -r -d -o ${.TARGET} ${OBJS}
@[ -z "${CTFMERGE}" -o -n "${NO_CTF}" ] || ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
.if ${MK_CTF} != "no"
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
.endif
.if defined(EXPORT_SYMS)
.if ${EXPORT_SYMS} != YES
.if ${EXPORT_SYMS} == NO

View File

@ -99,7 +99,6 @@ for dir in /bin /usr/bin /usr/local/bin; do
done
if [ -n "$svnversion" ] ; then
echo "$svnversion"
svn=`cd ${SYSDIR} && $svnversion`
case "$svn" in
[0-9]*) svn=" r${svn}" ;;

View File

@ -15,16 +15,14 @@ dst=`realpath ./acpi_ca_destination`
# files that should keep their full directory path
fulldirs="common compiler debugger disassembler dispatcher events \
executer hardware include namespace parser resources tables \
tools utilities"
executer hardware include namespace os_specific parser \
resources tables utilities"
# files to remove
stripdirs="acpinames acpisrc acpixtract examples generate os_specific \
tests"
stripdirs="generate tests tools"
stripfiles="Makefile README acintel.h aclinux.h acmsvc.h acnetbsd.h \
acos2.h accygwin.h acefi.h acwin.h acwin64.h aeexec.c \
aehandlers.c aemain.c aetables.c aetables.h osunixdir.c \
readme.txt utclib.c"
acos2.h accygwin.h acefi.h acwin.h acwin64.h osunixdir.c \
oswindir.c oswintbl.c oswinxf.c readme.txt utclib.c"
# include files to canonify
src_headers="acapps.h accommon.h acconfig.h acdebug.h acdisasm.h \
@ -32,7 +30,7 @@ src_headers="acapps.h accommon.h acconfig.h acdebug.h acdisasm.h \
aclocal.h acmacros.h acnames.h acnamesp.h acobject.h acopcode.h \
acoutput.h acparser.h acpi.h acpiosxf.h acpixf.h acpredef.h \
acresrc.h acrestyp.h acstruct.h actables.h actbl.h actbl1.h \
actbl2.h actypes.h acutils.h amlcode.h amlresrc.h \
actbl2.h actbl3.h actypes.h acutils.h amlcode.h amlresrc.h \
platform/acenv.h platform/acfreebsd.h platform/acgcc.h"
comp_headers="aslcompiler.h asldefine.h aslglobal.h aslmessages.h \
asltypes.h dtcompiler.h dttemplate.h"
@ -84,8 +82,8 @@ echo post-clean
rm -rf ${wrk}
# assist the developer in generating a diff
echo "Directories you may want to 'cvs diff':"
echo " src/sys/contrib/dev/acpica src/sys/dev/acpica \\"
echo " src/sys/amd64/acpica src/sys/i386/acpica src/sys/ia64/acpica \\"
echo " src/sys/amd64/include src/sys/i386/include src/sys/ia64/include \\"
echo " src/sys/boot src/sys/conf src/sys/modules/acpi src/usr.sbin/acpi"
echo "Directories you may want to 'svn diff':"
echo " sys/contrib/dev/acpica sys/dev/acpica \\"
echo " sys/amd64/acpica sys/i386/acpica sys/ia64/acpica sys/x86/acpica \\"
echo " sys/amd64/include sys/i386/include sys/ia64/include \\"
echo " sys/boot sys/conf sys/modules/acpi usr.sbin/acpi"

View File

@ -1,7 +1,356 @@
----------------------------------------
27 May 2011. Summary of changes for version 20110527:
23 November 2011. Summary of changes for version 20111123:
This release is available at www.acpica.org/downloads
The ACPI 5.0 specification is available at www.acpi.info
0) ACPI 5.0 Support:
This release contains full support for the ACPI 5.0 specification, as
summarized below.
Reduced Hardware Support:
-------------------------
This support allows for ACPI systems without the usual ACPI hardware. This
support is enabled by a flag in the revision 5 FADT. If it is set, ACPICA will
not attempt to initialize or use any of the usual ACPI hardware. Note, when
this flag is set, all of the following ACPI hardware is assumed to be not
present and is not initialized or accessed:
General Purpose Events (GPEs)
Fixed Events (PM1a/PM1b and PM Control)
Power Management Timer and Console Buttons (power/sleep)
Real-time Clock Alarm
Global Lock
System Control Interrupt (SCI)
The FACS is assumed to be non-existent
ACPI Tables:
------------
All new tables and updates to existing tables are fully supported in the
ACPICA headers (for use by device drivers), the disassembler, and the iASL
Data Table Compiler. ACPI 5.0 defines these new tables:
BGRT /* Boot Graphics Resource Table */
DRTM /* Dynamic Root of Trust for Measurement table */
FPDT /* Firmware Performance Data Table */
GTDT /* Generic Timer Description Table */
MPST /* Memory Power State Table */
PCCT /* Platform Communications Channel Table */
PMTT /* Platform Memory Topology Table */
RASF /* RAS Feature table */
Operation Regions/SpaceIDs:
---------------------------
All new operation regions are fully supported by the iASL compiler, the
disassembler, and the ACPICA runtime code (for dispatch to region handlers.)
The new operation region Space IDs are:
GeneralPurposeIo
GenericSerialBus
Resource Descriptors:
---------------------
All new ASL resource descriptors are fully supported by the iASL compiler, the
ASL/AML disassembler, and the ACPICA runtime Resource Manager code (including
all new predefined resource tags). New descriptors are:
FixedDma
GpioIo
GpioInt
I2cSerialBus
SpiSerialBus
UartSerialBus
ASL/AML Operators, New and Modified:
------------------------------------
One new operator is added, the Connection operator, which is used to associate
a GeneralPurposeIo or GenericSerialBus resource descriptor with individual
field objects within an operation region. Several new protocols are associated
with the AccessAs operator. All are fully supported by the iASL compiler,
disassembler, and runtime ACPICA AML interpreter:
Connection // Declare Field Connection attributes
AccessAs: AttribBytes (n) // Read/Write N-Bytes Protocol
AccessAs: AttribRawBytes (n) // Raw Read/Write N-Bytes Protocol
AccessAs: AttribRawProcessBytes (n) // Raw Process Call Protocol
RawDataBuffer // Data type for Vendor Data fields
Predefined ASL/AML Objects:
---------------------------
All new predefined objects/control-methods are supported by the iASL compiler
and the ACPICA runtime validation/repair (arguments and return values.) New
predefined names include the following:
Standard Predefined Names (Objects or Control Methods):
_AEI, _CLS, _CPC, _CWS, _DEP,
_DLM, _EVT, _GCP, _CRT, _GWS,
_HRV, _PRE, _PSE, _SRT, _SUB.
Resource Tags (Names used to access individual fields within resource
descriptors):
_DBT, _DPL, _DRS, _END, _FLC,
_IOR, _LIN, _MOD, _PAR, _PHA,
_PIN, _PPI, _POL, _RXL, _SLV,
_SPE, _STB, _TXL, _VEN.
ACPICA External Interfaces:
---------------------------
Several new interfaces have been defined for use by ACPI-related device
drivers and other host OS services:
AcpiAcquireMutex and AcpiReleaseMutex: These interfaces allow the host OS to
acquire and release AML mutexes that are defined in the DSDT/SSDT tables
provided by the BIOS. They are intended to be used in conjunction with the
ACPI 5.0 _DLM (Device Lock Method) in order to provide transaction-level
mutual exclusion with the AML code/interpreter.
AcpiGetEventResources: Returns the (formatted) resource descriptors as defined
by the ACPI 5.0 _AEI object (ACPI Event Information). This object provides
resource descriptors associated with hardware-reduced platform events, similar
to the AcpiGetCurrentResources interface.
Operation Region Handlers: For General Purpose IO and Generic Serial Bus
operation regions, information about the Connection() object and any optional
length information is passed to the region handler within the Context
parameter.
AcpiBufferToResource: This interface converts a raw AML buffer containing a
resource template or resource descriptor to the ACPI_RESOURCE internal format
suitable for use by device drivers. Can be used by an operation region handler
to convert the Connection() buffer object into a ACPI_RESOURCE.
Miscellaneous/Tools/TestSuites:
-------------------------------
Support for extended _HID names (Four alpha characters instead of three).
Support for ACPI 5.0 features in the AcpiExec and AcpiHelp utilities.
Support for ACPI 5.0 features in the ASLTS test suite.
Fully updated documentation (ACPICA and iASL reference documents.)
ACPI Table Definition Language:
-------------------------------
Support for this language was implemented and released as a subsystem of the
iASL compiler in 2010. (See the iASL compiler User Guide.)
Non-ACPI 5.0 changes for this release:
--------------------------------------
1) ACPICA Core Subsystem:
Fix a problem with operation region declarations where a failure can occur if
the region name and an argument that evaluates to an object (such as the
region address) are in different namespace scopes. Lin Ming, ACPICA BZ 937.
Do not abort an ACPI table load if an invalid space ID is found within. This
will be caught later if the offending method is executed. ACPICA BZ 925.
Fixed an issue with the FFixedHW space ID where the ID was not always
recognized properly (Both ACPICA and iASL). ACPICA BZ 926.
Fixed a problem with the 32-bit generation of the unix-specific OSL
(osunixxf.c). Lin Ming, ACPICA BZ 936.
Several changes made to enable generation with the GCC 4.6 compiler. ACPICA BZ
935.
New error messages: Unsupported I/O requests (not 8/16/32 bit), and Index/Bank
field registers out-of-range.
2) iASL Compiler/Disassembler and Tools:
iASL: Implemented the __PATH__ operator, which returns the full pathname of
the current source file.
AcpiHelp: Automatically display expanded keyword information for all ASL
operators.
Debugger: Add "Template" command to disassemble/dump resource template
buffers.
Added a new master script to generate and execute the ASLTS test suite.
Automatically handles 32- and 64-bit generation. See tests/aslts.sh
iASL: Fix problem with listing generation during processing of the Switch()
operator where AML listing was disabled until the entire Switch block was
completed.
iASL: Improve support for semicolon statement terminators. Fix "invalid
character" message for some cases when the semicolon is used. Semicolons are
now allowed after every <Term> grammar element. ACPICA BZ 927.
iASL: Fixed some possible aliasing warnings during generation. ACPICA BZ 923.
Disassembler: Fix problem with disassembly of the DataTableRegion operator
where an inadvertent "Unhandled deferred opcode" message could be generated.
3) Example Code and Data Size
These are the sizes for the OS-independent acpica.lib produced by the
Microsoft Visual C++ 9.0 32-bit compiler. The debug version of the code
includes the debug output trace mechanism and has a much larger code and data
size.
Previous Release:
Non-Debug Version: 90.2K Code, 23.9K Data, 114.1K Total
Debug Version: 165.6K Code, 68.4K Data, 234.0K Total
Current Release:
Non-Debug Version: 92.3K Code, 24.9K Data, 117.2K Total
Debug Version: 170.8K Code, 72.6K Data, 243.4K Total
----------------------------------------
22 September 2011. Summary of changes for version 20110922:
0) ACPI 5.0 News:
Support for ACPI 5.0 in ACPICA has been underway for several months and will
be released at the same time that ACPI 5.0 is officially released.
The ACPI 5.0 specification is on track for release in the next few months.
1) ACPICA Core Subsystem:
Fixed a problem where the maximum sleep time for the Sleep() operator was
intended to be limited to two seconds, but was inadvertently limited to 20
seconds instead.
Linux and Unix makefiles: Added header file dependencies to ensure correct
generation of ACPICA core code and utilities. Also simplified the makefiles
considerably through the use of the vpath variable to specify search paths.
ACPICA BZ 924.
2) iASL Compiler/Disassembler and Tools:
iASL: Implemented support to check the access length for all fields created to
access named Resource Descriptor fields. For example, if a resource field is
defined to be two bits, a warning is issued if a CreateXxxxField() is used
with an incorrect bit length. This is implemented for all current resource
descriptor names. ACPICA BZ 930.
Disassembler: Fixed a byte ordering problem with the output of 24-bit and 56-
bit integers.
iASL: Fixed a couple of issues associated with variable-length package
objects. 1) properly handle constants like One, Ones, Zero -- do not make a
VAR_PACKAGE when these are used as a package length. 2) Allow the VAR_PACKAGE
opcode (in addition to PACKAGE) when validating object types for predefined
names.
iASL: Emit statistics for all output files (instead of just the ASL input and
AML output). Includes listings, hex files, etc.
iASL: Added -G option to the table compiler to allow the compilation of custom
ACPI tables. The only part of a table that is required is the standard 36-byte
ACPI header.
AcpiXtract: Ported to the standard ACPICA environment (with ACPICA headers),
which also adds correct 64-bit support. Also, now all output filenames are
completely lower case.
AcpiExec: Ignore any non-AML tables (tables other than DSDT or SSDT) when
loading table files. A warning is issued for any such tables. The only
exception is an FADT. This also fixes a possible fault when attempting to load
non-AML tables. ACPICA BZ 932.
AcpiHelp: Added the AccessAs and Offset operators. Fixed a problem where a
missing table terminator could cause a fault when using the -p option.
AcpiSrc: Fixed a possible divide-by-zero fault when generating file
statistics.
3) Example Code and Data Size
These are the sizes for the OS-independent acpica.lib produced by the
Microsoft Visual C++ 9.0 32-bit compiler. The debug version of the code
includes the debug output trace mechanism and has a much larger code and data
size.
Previous Release (VC 9.0):
Non-Debug Version: 90.2K Code, 23.9K Data, 114.1K Total
Debug Version: 165.6K Code, 68.4K Data, 234.0K Total
Current Release (VC 9.0):
Non-Debug Version: 90.2K Code, 23.9K Data, 114.1K Total
Debug Version: 165.6K Code, 68.4K Data, 234.0K Total
----------------------------------------
23 June 2011. Summary of changes for version 20110623:
1) ACPI CA Core Subsystem:
Updated the predefined name repair mechanism to not attempt repair of a _TSS
return object if a _PSS object is present. We can only sort the _TSS return
package if there is no _PSS within the same scope. This is because if _PSS is
present, the ACPI specification dictates that the _TSS Power Dissipation field
is to be ignored, and therefore some BIOSs leave garbage values in the _TSS
Power field(s). In this case, it is best to just return the _TSS package as-
is. Reported by, and fixed with assistance from Fenghua Yu.
Added an option to globally disable the control method return value validation
and repair. This runtime option can be used to disable return value repair if
this is causing a problem on a particular machine. Also added an option to
AcpiExec (-dr) to set this disable flag.
All makefiles and project files: Major changes to improve generation of ACPICA
tools. ACPICA BZ 912:
Reduce default optimization levels to improve compatibility
For Linux, add strict-aliasing=0 for gcc 4
Cleanup and simplify use of command line defines
Cleanup multithread library support
Improve usage messages
Linux-specific header: update handling of THREAD_ID and pthread. For the 32-
bit case, improve casting to eliminate possible warnings, especially with the
acpica tools.
Example Code and Data Size: These are the sizes for the OS-independent
acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The debug
version of the code includes the debug output trace mechanism and has a much
larger code and data size.
Previous Release (VC 9.0):
Non-Debug Version: 90.1K Code, 23.9K Data, 114.0K Total
Debug Version: 165.6K Code, 68.4K Data, 234.0K Total
Current Release (VC 9.0):
Non-Debug Version: 90.2K Code, 23.9K Data, 114.1K Total
Debug Version: 165.6K Code, 68.4K Data, 234.0K Total
2) iASL Compiler/Disassembler and Tools:
With this release, a new utility named "acpihelp" has been added to the ACPICA
package. This utility summarizes the ACPI specification chapters for the ASL
and AML languages. It generates under Linux/Unix as well as Windows, and
provides the following functionality:
Find/display ASL operator(s) -- with description and syntax.
Find/display ASL keyword(s) -- with exact spelling and descriptions.
Find/display ACPI predefined name(s) -- with description, number
of arguments, and the return value data type.
Find/display AML opcode name(s) -- with opcode, arguments, and grammar.
Decode/display AML opcode -- with opcode name, arguments, and grammar.
Service Layers: Make multi-thread support configurable. Conditionally compile
the multi-thread support so that threading libraries will not be linked if not
necessary. The only tool that requires multi-thread support is AcpiExec.
iASL: Update yyerrror/AslCompilerError for "const" errors. Newer versions of
Bison appear to want the interface to yyerror to be a const char * (or at
least this is a problem when generating iASL on some systems.) ACPICA BZ 923
Pierre Lejeune.
Tools: Fix for systems where O_BINARY is not defined. Only used for Windows
versions of the tools.
----------------------------------------
27 May 2011. Summary of changes for version 20110527:
1) ACPI CA Core Subsystem:

View File

@ -868,6 +868,7 @@ AdParseDeferredOps (
break;
case AML_REGION_OP:
case AML_DATA_REGION_OP:
case AML_CREATE_QWORD_FIELD_OP:
case AML_CREATE_DWORD_FIELD_OP:
case AML_CREATE_WORD_FIELD_OP:

View File

@ -378,6 +378,10 @@ AcpiDmDumpDescending (
AcpiOsPrintf ("%X", (UINT32) Op->Common.Value.Integer);
break;
case AML_QWORD_OP:
AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
break;
case AML_INT_NAMEPATH_OP:
if (Op->Common.Value.String)
{

View File

@ -63,7 +63,7 @@ AcpiDmUpdateResourceName (
static char *
AcpiDmSearchTagList (
UINT32 BitIndex,
ACPI_RESOURCE_TAG *TagList);
const ACPI_RESOURCE_TAG *TagList);
static char *
AcpiDmGetResourceTag (
@ -108,7 +108,7 @@ AcpiDmAddResourcesToNamespace (
*
******************************************************************************/
static ACPI_RESOURCE_TAG AcpiDmIrqTags[] =
static const ACPI_RESOURCE_TAG AcpiDmIrqTags[] =
{
{( 1 * 8), ACPI_RESTAG_INTERRUPT},
{( 3 * 8) + 0, ACPI_RESTAG_INTERRUPTTYPE},
@ -117,7 +117,7 @@ static ACPI_RESOURCE_TAG AcpiDmIrqTags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmDmaTags[] =
static const ACPI_RESOURCE_TAG AcpiDmDmaTags[] =
{
{( 1 * 8), ACPI_RESTAG_DMA},
{( 2 * 8) + 0, ACPI_RESTAG_XFERTYPE},
@ -126,7 +126,7 @@ static ACPI_RESOURCE_TAG AcpiDmDmaTags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmIoTags[] =
static const ACPI_RESOURCE_TAG AcpiDmIoTags[] =
{
{( 1 * 8) + 0, ACPI_RESTAG_DECODE},
{( 2 * 8), ACPI_RESTAG_MINADDR},
@ -136,14 +136,22 @@ static ACPI_RESOURCE_TAG AcpiDmIoTags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmFixedIoTags[] =
static const ACPI_RESOURCE_TAG AcpiDmFixedIoTags[] =
{
{( 1 * 8), ACPI_RESTAG_BASEADDRESS},
{( 3 * 8), ACPI_RESTAG_LENGTH},
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmMemory24Tags[] =
static const ACPI_RESOURCE_TAG AcpiDmFixedDmaTags[] =
{
{( 1 * 8), ACPI_RESTAG_DMA},
{( 3 * 8), ACPI_RESTAG_DMATYPE},
{( 5 * 8), ACPI_RESTAG_XFERTYPE},
{0, NULL}
};
static const ACPI_RESOURCE_TAG AcpiDmMemory24Tags[] =
{
{( 3 * 8) + 0, ACPI_RESTAG_READWRITETYPE},
{( 4 * 8), ACPI_RESTAG_MINADDR},
@ -153,7 +161,7 @@ static ACPI_RESOURCE_TAG AcpiDmMemory24Tags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmRegisterTags[] =
static const ACPI_RESOURCE_TAG AcpiDmRegisterTags[] =
{
{( 3 * 8), ACPI_RESTAG_ADDRESSSPACE},
{( 4 * 8), ACPI_RESTAG_REGISTERBITWIDTH},
@ -163,7 +171,7 @@ static ACPI_RESOURCE_TAG AcpiDmRegisterTags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmMemory32Tags[] =
static const ACPI_RESOURCE_TAG AcpiDmMemory32Tags[] =
{
{( 3 * 8) + 0, ACPI_RESTAG_READWRITETYPE},
{( 4 * 8), ACPI_RESTAG_MINADDR},
@ -173,7 +181,7 @@ static ACPI_RESOURCE_TAG AcpiDmMemory32Tags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmFixedMemory32Tags[] =
static const ACPI_RESOURCE_TAG AcpiDmFixedMemory32Tags[] =
{
{( 3 * 8) + 0, ACPI_RESTAG_READWRITETYPE},
{( 4 * 8), ACPI_RESTAG_BASEADDRESS},
@ -181,7 +189,7 @@ static ACPI_RESOURCE_TAG AcpiDmFixedMemory32Tags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmInterruptTags[] =
static const ACPI_RESOURCE_TAG AcpiDmInterruptTags[] =
{
{( 3 * 8) + 1, ACPI_RESTAG_INTERRUPTTYPE},
{( 3 * 8) + 2, ACPI_RESTAG_INTERRUPTLEVEL},
@ -190,7 +198,7 @@ static ACPI_RESOURCE_TAG AcpiDmInterruptTags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmAddress16Tags[] =
static const ACPI_RESOURCE_TAG AcpiDmAddress16Tags[] =
{
{( 4 * 8) + 1, ACPI_RESTAG_DECODE},
{( 4 * 8) + 2, ACPI_RESTAG_MINTYPE},
@ -203,7 +211,7 @@ static ACPI_RESOURCE_TAG AcpiDmAddress16Tags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmAddress32Tags[] =
static const ACPI_RESOURCE_TAG AcpiDmAddress32Tags[] =
{
{( 4 * 8) + 1, ACPI_RESTAG_DECODE},
{( 4 * 8) + 2, ACPI_RESTAG_MINTYPE},
@ -216,7 +224,7 @@ static ACPI_RESOURCE_TAG AcpiDmAddress32Tags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmAddress64Tags[] =
static const ACPI_RESOURCE_TAG AcpiDmAddress64Tags[] =
{
{( 4 * 8) + 1, ACPI_RESTAG_DECODE},
{( 4 * 8) + 2, ACPI_RESTAG_MINTYPE},
@ -229,7 +237,7 @@ static ACPI_RESOURCE_TAG AcpiDmAddress64Tags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmExtendedAddressTags[] =
static const ACPI_RESOURCE_TAG AcpiDmExtendedAddressTags[] =
{
{( 4 * 8) + 1, ACPI_RESTAG_DECODE},
{( 4 * 8) + 2, ACPI_RESTAG_MINTYPE},
@ -243,9 +251,71 @@ static ACPI_RESOURCE_TAG AcpiDmExtendedAddressTags[] =
{0, NULL}
};
/* Special-case tables for the type-specific flags */
/* Subtype tables for GPIO descriptors */
static ACPI_RESOURCE_TAG AcpiDmMemoryFlagTags[] =
static const ACPI_RESOURCE_TAG AcpiDmGpioIntTags[] =
{
{( 7 * 8) + 0, ACPI_RESTAG_MODE},
{( 7 * 8) + 1, ACPI_RESTAG_POLARITY},
{( 7 * 8) + 3, ACPI_RESTAG_INTERRUPTSHARE},
{( 9 * 8), ACPI_RESTAG_PINCONFIG},
{(10 * 8), ACPI_RESTAG_DRIVESTRENGTH},
{(12 * 8), ACPI_RESTAG_DEBOUNCETIME},
{0, NULL}
};
static const ACPI_RESOURCE_TAG AcpiDmGpioIoTags[] =
{
{( 7 * 8) + 0, ACPI_RESTAG_IORESTRICTION},
{( 7 * 8) + 3, ACPI_RESTAG_INTERRUPTSHARE},
{( 9 * 8), ACPI_RESTAG_PINCONFIG},
{(10 * 8), ACPI_RESTAG_DRIVESTRENGTH},
{(12 * 8), ACPI_RESTAG_DEBOUNCETIME},
{0, NULL}
};
/* Subtype tables for SerialBus descriptors */
static const ACPI_RESOURCE_TAG AcpiDmI2cSerialBusTags[] =
{
{( 6 * 8) + 0, ACPI_RESTAG_SLAVEMODE},
{( 7 * 8) + 0, ACPI_RESTAG_MODE},
{(12 * 8), ACPI_RESTAG_SPEED},
{(16 * 8), ACPI_RESTAG_ADDRESS},
{0, NULL}
};
static const ACPI_RESOURCE_TAG AcpiDmSpiSerialBusTags[] =
{
{( 6 * 8) + 0, ACPI_RESTAG_SLAVEMODE},
{( 7 * 8) + 0, ACPI_RESTAG_MODE},
{( 7 * 8) + 1, ACPI_RESTAG_DEVICEPOLARITY},
{(12 * 8), ACPI_RESTAG_SPEED},
{(16 * 8), ACPI_RESTAG_LENGTH},
{(17 * 8), ACPI_RESTAG_PHASE},
{(18 * 8), ACPI_RESTAG_POLARITY},
{(19 * 8), ACPI_RESTAG_ADDRESS},
{0, NULL}
};
static const ACPI_RESOURCE_TAG AcpiDmUartSerialBusTags[] =
{
{( 6 * 8) + 0, ACPI_RESTAG_SLAVEMODE}, /* Note: not part of original macro */
{( 7 * 8) + 0, ACPI_RESTAG_FLOWCONTROL},
{( 7 * 8) + 2, ACPI_RESTAG_STOPBITS},
{( 7 * 8) + 4, ACPI_RESTAG_LENGTH},
{( 7 * 8) + 7, ACPI_RESTAG_ENDIANNESS},
{(12 * 8), ACPI_RESTAG_SPEED},
{(16 * 8), ACPI_RESTAG_LENGTH_RX},
{(18 * 8), ACPI_RESTAG_LENGTH_TX},
{(20 * 8), ACPI_RESTAG_PARITY},
{(21 * 8), ACPI_RESTAG_LINE},
{0, NULL}
};
/* Subtype tables for Address descriptor type-specific flags */
static const ACPI_RESOURCE_TAG AcpiDmMemoryFlagTags[] =
{
{( 5 * 8) + 0, ACPI_RESTAG_READWRITETYPE},
{( 5 * 8) + 1, ACPI_RESTAG_MEMTYPE},
@ -254,7 +324,7 @@ static ACPI_RESOURCE_TAG AcpiDmMemoryFlagTags[] =
{0, NULL}
};
static ACPI_RESOURCE_TAG AcpiDmIoFlagTags[] =
static const ACPI_RESOURCE_TAG AcpiDmIoFlagTags[] =
{
{( 5 * 8) + 0, ACPI_RESTAG_RANGETYPE},
{( 5 * 8) + 4, ACPI_RESTAG_TYPE},
@ -263,9 +333,15 @@ static ACPI_RESOURCE_TAG AcpiDmIoFlagTags[] =
};
/* Dispatch table used to obtain the correct tag table for a descriptor */
static ACPI_RESOURCE_TAG *AcpiGbl_ResourceTags [] =
/*
* Dispatch table used to obtain the correct tag table for a descriptor.
*
* A NULL in this table means one of three things:
* 1) The descriptor ID is reserved and invalid
* 2) The descriptor has no tags associated with it
* 3) The descriptor has subtypes and a separate table will be used.
*/
static const ACPI_RESOURCE_TAG *AcpiGbl_ResourceTags[] =
{
/* Small descriptors */
@ -279,7 +355,7 @@ static ACPI_RESOURCE_TAG *AcpiGbl_ResourceTags [] =
NULL, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
AcpiDmIoTags, /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
AcpiDmFixedIoTags, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
NULL, /* 0x0A, Reserved */
AcpiDmFixedDmaTags, /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */
NULL, /* 0x0B, Reserved */
NULL, /* 0x0C, Reserved */
NULL, /* 0x0D, Reserved */
@ -299,9 +375,29 @@ static ACPI_RESOURCE_TAG *AcpiGbl_ResourceTags [] =
AcpiDmAddress16Tags, /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
AcpiDmInterruptTags, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
AcpiDmAddress64Tags, /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
AcpiDmExtendedAddressTags /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
AcpiDmExtendedAddressTags, /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
NULL, /* 0x0C, ACPI_RESOURCE_NAME_GPIO - Use Subtype table below */
NULL, /* 0x0D, Reserved */
NULL /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS - Use Subtype table below */
};
/* GPIO Subtypes */
static const ACPI_RESOURCE_TAG *AcpiGbl_GpioResourceTags[] =
{
AcpiDmGpioIntTags, /* 0x00 Interrupt Connection */
AcpiDmGpioIoTags /* 0x01 I/O Connection */
};
/* Serial Bus Subtypes */
static const ACPI_RESOURCE_TAG *AcpiGbl_SerialResourceTags[] =
{
NULL, /* 0x00 Reserved */
AcpiDmI2cSerialBusTags, /* 0x01 I2C SerialBus */
AcpiDmSpiSerialBusTags, /* 0x02 SPI SerialBus */
AcpiDmUartSerialBusTags /* 0x03 UART SerialBus */
};
/*
* Globals used to generate unique resource descriptor names. We use names that
@ -666,6 +762,9 @@ AcpiDmUpdateResourceName (
*
* DESCRIPTION: Convert a BitIndex into a symbolic resource tag.
*
* Note: ResourceIndex should be previously validated and guaranteed to ve
* valid.
*
******************************************************************************/
static char *
@ -674,23 +773,16 @@ AcpiDmGetResourceTag (
AML_RESOURCE *Resource,
UINT8 ResourceIndex)
{
ACPI_RESOURCE_TAG *TagList;
const ACPI_RESOURCE_TAG *TagList;
char *Tag = NULL;
/* Get the tag list for this resource descriptor type */
TagList = AcpiGbl_ResourceTags[ResourceIndex];
if (!TagList)
{
/* There are no tags for this resource type */
return (NULL);
}
/*
* Handle the type-specific flags field for the address descriptors.
* Kindof brute force, but just blindly search for an index match.
* Handle descriptors that have multiple subtypes
*/
switch (Resource->DescriptorType)
{
@ -699,6 +791,10 @@ AcpiDmGetResourceTag (
case ACPI_RESOURCE_NAME_ADDRESS64:
case ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64:
/*
* Subtype differentiation is the flags.
* Kindof brute force, but just blindly search for an index match
*/
if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_MEMORY_RANGE)
{
Tag = AcpiDmSearchTagList (BitIndex, AcpiDmMemoryFlagTags);
@ -716,13 +812,42 @@ AcpiDmGetResourceTag (
}
break;
case ACPI_RESOURCE_NAME_GPIO:
/* GPIO connection has 2 subtypes: Interrupt and I/O */
if (Resource->Gpio.ConnectionType > AML_RESOURCE_MAX_GPIOTYPE)
{
return (NULL);
}
TagList = AcpiGbl_GpioResourceTags[Resource->Gpio.ConnectionType];
break;
case ACPI_RESOURCE_NAME_SERIAL_BUS:
/* SerialBus has 3 subtypes: I2C, SPI, and UART */
if ((Resource->CommonSerialBus.Type == 0) ||
(Resource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE))
{
return (NULL);
}
TagList = AcpiGbl_SerialResourceTags[Resource->CommonSerialBus.Type];
break;
default:
break;
}
/* Search the tag list for this descriptor type */
/* Search for a match against the BitIndex */
if (TagList)
{
Tag = AcpiDmSearchTagList (BitIndex, TagList);
}
Tag = AcpiDmSearchTagList (BitIndex, TagList);
return (Tag);
}
@ -744,7 +869,7 @@ AcpiDmGetResourceTag (
static char *
AcpiDmSearchTagList (
UINT32 BitIndex,
ACPI_RESOURCE_TAG *TagList)
const ACPI_RESOURCE_TAG *TagList)
{
/*

View File

@ -196,6 +196,16 @@ static const char *AcpiDmMadtSubnames[] =
"Platform Interrupt Sources", /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */
"Processor Local x2APIC", /* ACPI_MADT_TYPE_LOCAL_X2APIC */
"Local x2APIC NMI", /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */
"Generic Interrupt Controller", /* ACPI_MADT_GENERIC_INTERRUPT */
"Generic Interrupt Distributor",/* ACPI_MADT_GENERIC_DISTRIBUTOR */
"Unknown SubTable Type" /* Reserved */
};
static const char *AcpiDmPmttSubnames[] =
{
"Socket", /* ACPI_PMTT_TYPE_SOCKET */
"Memory Controller", /* ACPI_PMTT_TYPE_CONTROLLER */
"Physical Component (DIMM)", /* ACPI_PMTT_TYPE_DIMM */
"Unknown SubTable Type" /* Reserved */
};
@ -268,6 +278,7 @@ ACPI_DMTABLE_DATA AcpiDmTableData[] =
{ACPI_SIG_ASF, NULL, AcpiDmDumpAsf, DtCompileAsf, TemplateAsf, "Alert Standard Format table"},
{ACPI_SIG_BOOT, AcpiDmTableInfoBoot, NULL, NULL, TemplateBoot, "Simple Boot Flag Table"},
{ACPI_SIG_BERT, AcpiDmTableInfoBert, NULL, NULL, TemplateBert, "Boot Error Record Table"},
{ACPI_SIG_BGRT, AcpiDmTableInfoBgrt, NULL, NULL, TemplateBgrt, "Boot Graphics Resource Table"},
{ACPI_SIG_CPEP, NULL, AcpiDmDumpCpep, DtCompileCpep, TemplateCpep, "Corrected Platform Error Polling table"},
{ACPI_SIG_DBGP, AcpiDmTableInfoDbgp, NULL, NULL, TemplateDbgp, "Debug Port table"},
{ACPI_SIG_DMAR, NULL, AcpiDmDumpDmar, DtCompileDmar, TemplateDmar, "DMA Remapping table"},
@ -275,14 +286,20 @@ ACPI_DMTABLE_DATA AcpiDmTableData[] =
{ACPI_SIG_EINJ, NULL, AcpiDmDumpEinj, DtCompileEinj, TemplateEinj, "Error Injection table"},
{ACPI_SIG_ERST, NULL, AcpiDmDumpErst, DtCompileErst, TemplateErst, "Error Record Serialization Table"},
{ACPI_SIG_FADT, NULL, AcpiDmDumpFadt, DtCompileFadt, TemplateFadt, "Fixed ACPI Description Table"},
{ACPI_SIG_FPDT, NULL, AcpiDmDumpFpdt, DtCompileFpdt, TemplateFpdt, "Firmware Performance Data Table"},
{ACPI_SIG_GTDT, AcpiDmTableInfoGtdt, NULL, NULL, TemplateGtdt, "Generic Timer Description Table"},
{ACPI_SIG_HEST, NULL, AcpiDmDumpHest, DtCompileHest, TemplateHest, "Hardware Error Source Table"},
{ACPI_SIG_HPET, AcpiDmTableInfoHpet, NULL, NULL, TemplateHpet, "High Precision Event Timer table"},
{ACPI_SIG_IVRS, NULL, AcpiDmDumpIvrs, DtCompileIvrs, TemplateIvrs, "I/O Virtualization Reporting Structure"},
{ACPI_SIG_MADT, NULL, AcpiDmDumpMadt, DtCompileMadt, TemplateMadt, "Multiple APIC Description Table"},
{ACPI_SIG_MCFG, NULL, AcpiDmDumpMcfg, DtCompileMcfg, TemplateMcfg, "Memory Mapped Configuration table"},
{ACPI_SIG_MCHI, AcpiDmTableInfoMchi, NULL, NULL, TemplateMchi, "Management Controller Host Interface table"},
{ACPI_SIG_MPST, AcpiDmTableInfoMpst, AcpiDmDumpMpst, DtCompileMpst, TemplateMpst, "Memory Power State Table"},
{ACPI_SIG_MSCT, NULL, AcpiDmDumpMsct, DtCompileMsct, TemplateMsct, "Maximum System Characteristics Table"},
{ACPI_SIG_PCCT, NULL, AcpiDmDumpPcct, NULL, NULL, "Platform Communications Channel Table"},
{ACPI_SIG_PMTT, NULL, AcpiDmDumpPmtt, DtCompilePmtt, TemplatePmtt, "Platform Memory Topology Table"},
{ACPI_SIG_RSDT, NULL, AcpiDmDumpRsdt, DtCompileRsdt, TemplateRsdt, "Root System Description Table"},
{ACPI_SIG_S3PT, NULL, NULL, NULL, TemplateS3pt, "S3 Performance Table"},
{ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, NULL, TemplateSbst, "Smart Battery Specification Table"},
{ACPI_SIG_SLIC, NULL, AcpiDmDumpSlic, DtCompileSlic, TemplateSlic, "Software Licensing Description Table"},
{ACPI_SIG_SLIT, NULL, AcpiDmDumpSlit, DtCompileSlit, TemplateSlit, "System Locality Information Table"},
@ -400,7 +417,7 @@ AcpiDmDumpDataTable (
/*
* Handle tables that don't use the common ACPI table header structure.
* Currently, these are the FACS and RSDP.
* Currently, these are the FACS, RSDP, and S3PT.
*/
if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
{
@ -411,6 +428,10 @@ AcpiDmDumpDataTable (
{
Length = AcpiDmDumpRsdp (Table);
}
else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_S3PT))
{
Length = AcpiDmDumpS3pt (Table);
}
else
{
/*
@ -646,6 +667,7 @@ AcpiDmDumpTable (
case ACPI_DMT_ACCWIDTH:
case ACPI_DMT_IVRS:
case ACPI_DMT_MADT:
case ACPI_DMT_PMTT:
case ACPI_DMT_SRAT:
case ACPI_DMT_ASF:
case ACPI_DMT_HESTNTYP:
@ -670,6 +692,10 @@ AcpiDmDumpTable (
case ACPI_DMT_SLIC:
ByteLength = 4;
break;
case ACPI_DMT_UINT40:
ByteLength = 5;
break;
case ACPI_DMT_UINT48:
case ACPI_DMT_NAME6:
ByteLength = 6;
break;
@ -718,6 +744,12 @@ AcpiDmDumpTable (
return (AE_BAD_DATA);
}
if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
{
AcpiOsPrintf ("%s", Info->Name);
continue;
}
/* Start a new line and decode the opcode */
AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
@ -745,49 +777,42 @@ AcpiDmDumpTable (
AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
break;
case ACPI_DMT_FLAGS1:
AcpiOsPrintf ("%1.1X\n", (*Target >> 1) & 0x03);
break;
case ACPI_DMT_FLAGS2:
AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
break;
/* Standard Data Types */
case ACPI_DMT_FLAGS4:
AcpiOsPrintf ("%1.1X\n", (*Target >> 4) & 0x03);
break;
/* Integer Data Types */
case ACPI_DMT_UINT8:
AcpiOsPrintf ("%2.2X\n", *Target);
break;
case ACPI_DMT_UINT16:
AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target));
break;
case ACPI_DMT_UINT24:
AcpiOsPrintf ("%2.2X%2.2X%2.2X\n",
*Target, *(Target + 1), *(Target + 2));
break;
case ACPI_DMT_UINT32:
AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target));
break;
case ACPI_DMT_UINT40:
case ACPI_DMT_UINT48:
case ACPI_DMT_UINT56:
for (Temp8 = 0; Temp8 < 7; Temp8++)
case ACPI_DMT_UINT64:
/*
* Dump bytes - high byte first, low byte last.
* Note: All ACPI tables are little-endian.
*/
for (Temp8 = (UINT8) ByteLength; Temp8 > 0; Temp8--)
{
AcpiOsPrintf ("%2.2X", Target[Temp8]);
AcpiOsPrintf ("%2.2X", Target[Temp8 - 1]);
}
AcpiOsPrintf ("\n");
break;
case ACPI_DMT_UINT64:
AcpiOsPrintf ("%8.8X%8.8X\n",
ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
break;
case ACPI_DMT_BUF7:
case ACPI_DMT_BUF16:
case ACPI_DMT_BUF128:
@ -1040,6 +1065,19 @@ AcpiDmDumpTable (
AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmMadtSubnames[Temp8]);
break;
case ACPI_DMT_PMTT:
/* PMTT subtable types */
Temp8 = *Target;
if (Temp8 > ACPI_PMTT_TYPE_RESERVED)
{
Temp8 = ACPI_PMTT_TYPE_RESERVED;
}
AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmPmttSubnames[Temp8]);
break;
case ACPI_DMT_SLIC:
/* SLIC subtable types */

View File

@ -230,11 +230,18 @@ AcpiDmDumpFadt (
AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt2);
}
/* Check for FADT revision 3 fields and up (ACPI 2.0+ extended data) */
/* Check for FADT revision 3/4 fields and up (ACPI 2.0+ extended data) */
else if (Table->Length > ACPI_FADT_V2_SIZE)
{
AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt3);
/* Check for FADT revision 5 fields and up (ACPI 5.0+) */
if (Table->Length > ACPI_FADT_V3_SIZE)
{
AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt5);
}
}
/* Validate various fields in the FADT, including length */
@ -290,6 +297,10 @@ AcpiDmValidateFadtLength (
ExpectedLength = ACPI_FADT_V3_SIZE;
break;
case 5:
ExpectedLength = ACPI_FADT_V5_SIZE;
break;
default:
return;
}
@ -749,6 +760,84 @@ AcpiDmDumpErst (
}
/*******************************************************************************
*
* FUNCTION: AcpiDmDumpFpdt
*
* PARAMETERS: Table - A FPDT table
*
* RETURN: None
*
* DESCRIPTION: Format the contents of a FPDT. This table type consists
* of an open-ended number of subtables.
*
******************************************************************************/
void
AcpiDmDumpFpdt (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
ACPI_FPDT_HEADER *SubTable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_FPDT);
ACPI_DMTABLE_INFO *InfoTable;
/* There is no main table (other than the standard ACPI header) */
/* Sub-tables */
SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset);
while (Offset < Table->Length)
{
/* Common sub-table header */
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (Length, Offset, SubTable,
SubTable->Length, AcpiDmTableInfoFpdtHdr);
if (ACPI_FAILURE (Status))
{
return;
}
switch (SubTable->Type)
{
case ACPI_FPDT_TYPE_BOOT:
InfoTable = AcpiDmTableInfoFpdt0;
break;
case ACPI_FPDT_TYPE_S3PERF:
InfoTable = AcpiDmTableInfoFpdt1;
break;
default:
AcpiOsPrintf ("\n**** Unknown FPDT sub-table type 0x%X\n\n", SubTable->Type);
/* Attempt to continue */
if (!SubTable->Length)
{
AcpiOsPrintf ("Invalid zero length subtable\n");
return;
}
goto NextSubTable;
}
Status = AcpiDmDumpTable (Length, Offset, SubTable,
SubTable->Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
}
NextSubTable:
/* Point to next sub-table */
Offset += SubTable->Length;
SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, SubTable, SubTable->Length);
}
}
/*******************************************************************************
*
* FUNCTION: AcpiDmDumpHest
@ -1134,6 +1223,12 @@ AcpiDmDumpMadt (
case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
InfoTable = AcpiDmTableInfoMadt10;
break;
case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
InfoTable = AcpiDmTableInfoMadt11;
break;
case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
InfoTable = AcpiDmTableInfoMadt12;
break;
default:
AcpiOsPrintf ("\n**** Unknown MADT sub-table type 0x%X\n\n", SubTable->Type);
@ -1221,6 +1316,150 @@ AcpiDmDumpMcfg (
}
/*******************************************************************************
*
* FUNCTION: AcpiDmDumpMpst
*
* PARAMETERS: Table - A MPST Table
*
* RETURN: None
*
* DESCRIPTION: Format the contents of a MPST table
*
******************************************************************************/
void
AcpiDmDumpMpst (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
UINT32 Offset = sizeof (ACPI_TABLE_MPST);
ACPI_MPST_POWER_NODE *SubTable0;
ACPI_MPST_POWER_STATE *SubTable0A;
ACPI_MPST_COMPONENT *SubTable0B;
ACPI_MPST_DATA_HDR *SubTable1;
ACPI_MPST_POWER_DATA *SubTable2;
UINT16 SubtableCount;
UINT8 PowerStateCount;
UINT8 ComponentCount;
/* Main table */
Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMpst);
if (ACPI_FAILURE (Status))
{
return;
}
/* Subtable: Memory Power Node(s) */
SubtableCount = (ACPI_CAST_PTR (ACPI_TABLE_MPST, Table))->PowerNodeCount;
SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset);
while ((Offset < Table->Length) && SubtableCount)
{
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0,
sizeof (ACPI_MPST_POWER_NODE), AcpiDmTableInfoMpst0);
if (ACPI_FAILURE (Status))
{
return;
}
/* Extract the sub-subtable counts */
PowerStateCount = SubTable0->NumPowerStates;
ComponentCount = SubTable0->NumPhysicalComponents;
Offset += sizeof (ACPI_MPST_POWER_NODE);
/* Sub-subtables - Memory Power State Structure(s) */
SubTable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, SubTable0,
sizeof (ACPI_MPST_POWER_NODE));
while (PowerStateCount)
{
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0A,
sizeof (ACPI_MPST_POWER_STATE), AcpiDmTableInfoMpst0A);
if (ACPI_FAILURE (Status))
{
return;
}
SubTable0A++;
PowerStateCount--;
Offset += sizeof (ACPI_MPST_POWER_STATE);
}
/* Sub-subtables - Physical Component ID Structure(s) */
SubTable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, SubTable0A);
if (ComponentCount)
{
AcpiOsPrintf ("\n");
}
while (ComponentCount)
{
Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0B,
sizeof (ACPI_MPST_COMPONENT), AcpiDmTableInfoMpst0B);
if (ACPI_FAILURE (Status))
{
return;
}
SubTable0B++;
ComponentCount--;
Offset += sizeof (ACPI_MPST_COMPONENT);
}
/* Point to next Memory Power Node subtable */
SubtableCount--;
SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, SubTable0,
sizeof (ACPI_MPST_POWER_NODE) +
(sizeof (ACPI_MPST_POWER_STATE) * SubTable0->NumPowerStates) +
(sizeof (ACPI_MPST_COMPONENT) * SubTable0->NumPhysicalComponents));
}
/* Subtable: Count of Memory Power State Characteristic structures */
AcpiOsPrintf ("\n");
SubTable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, SubTable0);
Status = AcpiDmDumpTable (Table->Length, Offset, SubTable1,
sizeof (ACPI_MPST_DATA_HDR), AcpiDmTableInfoMpst1);
if (ACPI_FAILURE (Status))
{
return;
}
SubtableCount = SubTable1->CharacteristicsCount;
Offset += sizeof (ACPI_MPST_DATA_HDR);
/* Subtable: Memory Power State Characteristics structure(s) */
SubTable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, SubTable1, sizeof (ACPI_MPST_DATA_HDR));
while ((Offset < Table->Length) && SubtableCount)
{
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (Table->Length, Offset, SubTable2,
sizeof (ACPI_MPST_POWER_DATA), AcpiDmTableInfoMpst2);
if (ACPI_FAILURE (Status))
{
return;
}
SubTable2++;
SubtableCount--;
Offset += sizeof (ACPI_MPST_POWER_DATA);
}
}
/*******************************************************************************
*
* FUNCTION: AcpiDmDumpMsct
@ -1273,6 +1512,349 @@ AcpiDmDumpMsct (
}
/*******************************************************************************
*
* FUNCTION: AcpiDmDumpPcct
*
* PARAMETERS: Table - A PCCT table
*
* RETURN: None
*
* DESCRIPTION: Format the contents of a PCCT. This table type consists
* of an open-ended number of subtables.
*
******************************************************************************/
void
AcpiDmDumpPcct (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
ACPI_PCCT_SUBSPACE *SubTable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_PCCT);
/* Main table */
Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPcct);
if (ACPI_FAILURE (Status))
{
return;
}
/* Sub-tables */
SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset);
while (Offset < Table->Length)
{
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (Length, Offset, SubTable,
SubTable->Header.Length, AcpiDmTableInfoPcct0);
if (ACPI_FAILURE (Status))
{
return;
}
/* Point to next sub-table */
Offset += SubTable->Header.Length;
SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, SubTable,
SubTable->Header.Length);
}
}
/*******************************************************************************
*
* FUNCTION: AcpiDmDumpPmtt
*
* PARAMETERS: Table - A PMTT table
*
* RETURN: None
*
* DESCRIPTION: Format the contents of a PMTT. This table type consists
* of an open-ended number of subtables.
*
******************************************************************************/
void
AcpiDmDumpPmtt (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
ACPI_PMTT_HEADER *SubTable;
ACPI_PMTT_HEADER *MemSubTable;
ACPI_PMTT_HEADER *DimmSubTable;
ACPI_PMTT_DOMAIN *DomainArray;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_PMTT);
UINT32 MemOffset;
UINT32 DimmOffset;
UINT32 DomainOffset;
UINT32 DomainCount;
/* Main table */
Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPmtt);
if (ACPI_FAILURE (Status))
{
return;
}
/* Subtables */
SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (Length, Offset, SubTable,
SubTable->Length, AcpiDmTableInfoPmttHdr);
if (ACPI_FAILURE (Status))
{
return;
}
/* Only Socket subtables are expected at this level */
if (SubTable->Type != ACPI_PMTT_TYPE_SOCKET)
{
AcpiOsPrintf (
"\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
SubTable->Type);
return;
}
/* Dump the fixed-length portion of the subtable */
Status = AcpiDmDumpTable (Length, Offset, SubTable,
SubTable->Length, AcpiDmTableInfoPmtt0);
if (ACPI_FAILURE (Status))
{
return;
}
/* Walk the memory controller subtables */
MemOffset = sizeof (ACPI_PMTT_SOCKET);
MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, SubTable,
sizeof (ACPI_PMTT_SOCKET));
while (((Offset + MemOffset) < Table->Length) &&
(MemOffset < SubTable->Length))
{
/* Common subtable header */
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (Length,
Offset + MemOffset, MemSubTable,
MemSubTable->Length, AcpiDmTableInfoPmttHdr);
if (ACPI_FAILURE (Status))
{
return;
}
/* Only memory controller subtables are expected at this level */
if (MemSubTable->Type != ACPI_PMTT_TYPE_CONTROLLER)
{
AcpiOsPrintf (
"\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
MemSubTable->Type);
return;
}
/* Dump the fixed-length portion of the controller subtable */
Status = AcpiDmDumpTable (Length,
Offset + MemOffset, MemSubTable,
MemSubTable->Length, AcpiDmTableInfoPmtt1);
if (ACPI_FAILURE (Status))
{
return;
}
/* Walk the variable count of proximity domains */
DomainCount = ((ACPI_PMTT_CONTROLLER *) MemSubTable)->DomainCount;
DomainOffset = sizeof (ACPI_PMTT_CONTROLLER);
DomainArray = ACPI_ADD_PTR (ACPI_PMTT_DOMAIN, MemSubTable,
sizeof (ACPI_PMTT_CONTROLLER));
while (((Offset + MemOffset + DomainOffset) < Table->Length) &&
((MemOffset + DomainOffset) < SubTable->Length) &&
DomainCount)
{
Status = AcpiDmDumpTable (Length,
Offset + MemOffset + DomainOffset, DomainArray,
sizeof (ACPI_PMTT_DOMAIN), AcpiDmTableInfoPmtt1a);
if (ACPI_FAILURE (Status))
{
return;
}
DomainOffset += sizeof (ACPI_PMTT_DOMAIN);
DomainArray++;
DomainCount--;
}
if (DomainCount)
{
AcpiOsPrintf (
"\n**** DomainCount exceeds subtable length\n\n",
MemSubTable->Type);
}
/* Walk the physical component (DIMM) subtables */
DimmOffset = DomainOffset;
DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, MemSubTable,
DomainOffset);
while (((Offset + MemOffset + DimmOffset) < Table->Length) &&
(DimmOffset < MemSubTable->Length))
{
/* Common subtable header */
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (Length,
Offset + MemOffset + DimmOffset, DimmSubTable,
DimmSubTable->Length, AcpiDmTableInfoPmttHdr);
if (ACPI_FAILURE (Status))
{
return;
}
/* Only DIMM subtables are expected at this level */
if (DimmSubTable->Type != ACPI_PMTT_TYPE_DIMM)
{
AcpiOsPrintf (
"\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
DimmSubTable->Type);
return;
}
/* Dump the fixed-length DIMM subtable */
Status = AcpiDmDumpTable (Length,
Offset + MemOffset + DimmOffset, DimmSubTable,
DimmSubTable->Length, AcpiDmTableInfoPmtt2);
if (ACPI_FAILURE (Status))
{
return;
}
/* Point to next DIMM subtable */
DimmOffset += DimmSubTable->Length;
DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
DimmSubTable, DimmSubTable->Length);
}
/* Point to next Controller subtable */
MemOffset += MemSubTable->Length;
MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
MemSubTable, MemSubTable->Length);
}
/* Point to next Socket subtable */
Offset += SubTable->Length;
SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
SubTable, SubTable->Length);
}
}
/*******************************************************************************
*
* FUNCTION: AcpiDmDumpS3pt
*
* PARAMETERS: Table - A S3PT table
*
* RETURN: Length of the table
*
* DESCRIPTION: Format the contents of a S3PT
*
******************************************************************************/
UINT32
AcpiDmDumpS3pt (
ACPI_TABLE_HEADER *Tables)
{
ACPI_STATUS Status;
UINT32 Offset = sizeof (ACPI_TABLE_S3PT);
ACPI_S3PT_HEADER *SubTable;
ACPI_DMTABLE_INFO *InfoTable;
ACPI_TABLE_S3PT *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables);
/* Main table */
Status = AcpiDmDumpTable (Offset, 0, S3ptTable, 0, AcpiDmTableInfoS3pt);
if (ACPI_FAILURE (Status))
{
return 0;
}
SubTable = ACPI_ADD_PTR (ACPI_S3PT_HEADER, S3ptTable, Offset);
while (Offset < S3ptTable->Length)
{
/* Common sub-table header */
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable,
SubTable->Length, AcpiDmTableInfoS3ptHdr);
if (ACPI_FAILURE (Status))
{
return 0;
}
switch (SubTable->Type)
{
case ACPI_S3PT_TYPE_RESUME:
InfoTable = AcpiDmTableInfoS3pt0;
break;
case ACPI_S3PT_TYPE_SUSPEND:
InfoTable = AcpiDmTableInfoS3pt1;
break;
default:
AcpiOsPrintf ("\n**** Unknown S3PT sub-table type 0x%X\n", SubTable->Type);
/* Attempt to continue */
if (!SubTable->Length)
{
AcpiOsPrintf ("Invalid zero length subtable\n");
return 0;
}
goto NextSubTable;
}
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable,
SubTable->Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return 0;
}
NextSubTable:
/* Point to next sub-table */
Offset += SubTable->Length;
SubTable = ACPI_ADD_PTR (ACPI_S3PT_HEADER, SubTable, SubTable->Length);
}
return (S3ptTable->Length);
}
/*******************************************************************************
*
* FUNCTION: AcpiDmDumpSlic

View File

@ -82,21 +82,28 @@
#define ACPI_GAS_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_GENERIC_ADDRESS,f)
#define ACPI_HDR_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_HEADER,f)
#define ACPI_RSDP_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_RSDP,f)
#define ACPI_BOOT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_BOOT,f)
#define ACPI_BERT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_BERT,f)
#define ACPI_BGRT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_BGRT,f)
#define ACPI_BOOT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_BOOT,f)
#define ACPI_CPEP_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_CPEP,f)
#define ACPI_DBGP_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_DBGP,f)
#define ACPI_DMAR_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_DMAR,f)
#define ACPI_DRTM_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_DRTM,f)
#define ACPI_ECDT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_ECDT,f)
#define ACPI_EINJ_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_EINJ,f)
#define ACPI_ERST_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_ERST,f)
#define ACPI_GTDT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_GTDT,f)
#define ACPI_HEST_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_HEST,f)
#define ACPI_HPET_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_HPET,f)
#define ACPI_IVRS_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_IVRS,f)
#define ACPI_MADT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MADT,f)
#define ACPI_MCFG_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MCFG,f)
#define ACPI_MCHI_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MCHI,f)
#define ACPI_MPST_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MPST,f)
#define ACPI_MSCT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MSCT,f)
#define ACPI_PCCT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_PCCT,f)
#define ACPI_PMTT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_PMTT,f)
#define ACPI_S3PT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_S3PT,f)
#define ACPI_SBST_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SBST,f)
#define ACPI_SLIT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SLIT,f)
#define ACPI_SPCR_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SPCR,f)
@ -126,6 +133,9 @@
#define ACPI_DMAR3_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_DMAR_RHSA,f)
#define ACPI_EINJ0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_WHEA_HEADER,f)
#define ACPI_ERST0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_WHEA_HEADER,f)
#define ACPI_FPDTH_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_FPDT_HEADER,f)
#define ACPI_FPDT0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_FPDT_BOOT,f)
#define ACPI_FPDT1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_FPDT_S3PT_PTR,f)
#define ACPI_HEST0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_IA_MACHINE_CHECK,f)
#define ACPI_HEST1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_IA_CORRECTED,f)
#define ACPI_HEST2_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_HEST_IA_NMI,f)
@ -153,9 +163,25 @@
#define ACPI_MADT8_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MADT_INTERRUPT_SOURCE,f)
#define ACPI_MADT9_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MADT_LOCAL_X2APIC,f)
#define ACPI_MADT10_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MADT_LOCAL_X2APIC_NMI,f)
#define ACPI_MADT11_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MADT_GENERIC_INTERRUPT,f)
#define ACPI_MADT12_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MADT_GENERIC_DISTRIBUTOR,f)
#define ACPI_MADTH_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_SUBTABLE_HEADER,f)
#define ACPI_MCFG0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MCFG_ALLOCATION,f)
#define ACPI_MPST0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MPST_POWER_NODE,f)
#define ACPI_MPST0A_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MPST_POWER_STATE,f)
#define ACPI_MPST0B_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MPST_COMPONENT,f)
#define ACPI_MPST1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MPST_DATA_HDR,f)
#define ACPI_MPST2_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MPST_POWER_DATA,f)
#define ACPI_MSCT0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MSCT_PROXIMITY,f)
#define ACPI_PCCT0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_PCCT_SUBSPACE,f)
#define ACPI_PMTT0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_PMTT_SOCKET,f)
#define ACPI_PMTT1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_PMTT_CONTROLLER,f)
#define ACPI_PMTT1A_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_PMTT_DOMAIN,f)
#define ACPI_PMTT2_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_PMTT_PHYSICAL_COMPONENT,f)
#define ACPI_PMTTH_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_PMTT_HEADER,f)
#define ACPI_S3PTH_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_S3PT_HEADER,f)
#define ACPI_S3PT0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_S3PT_RESUME,f)
#define ACPI_S3PT1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_S3PT_SUSPEND,f)
#define ACPI_SLICH_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_SLIC_HEADER,f)
#define ACPI_SLIC0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_SLIC_KEY,f)
#define ACPI_SLIC1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_SLIC_MARKER,f)
@ -178,6 +204,7 @@
#define ACPI_SRAT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SRAT_CPU_AFFINITY,f,o)
#define ACPI_SRAT1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SRAT_MEM_AFFINITY,f,o)
#define ACPI_SRAT2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SRAT_X2APIC_CPU_AFFINITY,f,o)
#define ACPI_GTDT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_GTDT,f,o)
#define ACPI_MADT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_MADT,f,o)
#define ACPI_MADT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_APIC,f,o)
#define ACPI_MADT2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_INTERRUPT_OVERRIDE,f,o)
@ -187,6 +214,11 @@
#define ACPI_MADT8_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_INTERRUPT_SOURCE,f,o)
#define ACPI_MADT9_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_X2APIC,f,o)
#define ACPI_MADT10_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_X2APIC_NMI,f,o)
#define ACPI_MADT11_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_GENERIC_INTERRUPT,f,o)
#define ACPI_MPST0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MPST_POWER_NODE,f,o)
#define ACPI_MPST2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MPST_POWER_DATA,f,o)
#define ACPI_PCCT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_PCCT,f,o)
#define ACPI_PMTTH_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PMTT_HEADER,f,o)
#define ACPI_WDDT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_WDDT,f,o)
#define ACPI_EINJ0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_WHEA_HEADER,f,o)
#define ACPI_ERST0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_WHEA_HEADER,f,o)
@ -198,6 +230,7 @@
* Required terminator for all tables below
*/
#define ACPI_DMT_TERMINATOR {ACPI_DMT_EXIT, 0, NULL, 0}
#define ACPI_DMT_NEW_LINE {ACPI_DMT_EXTRA_TEXT, 0, "\n", 0}
/*
@ -383,6 +416,9 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoFadt1[] =
{ACPI_DMT_FLAG1, ACPI_FADT_FLAG_OFFSET (Flags,2), "Remote Power-on capable (V4)", 0},
{ACPI_DMT_FLAG2, ACPI_FADT_FLAG_OFFSET (Flags,2), "Use APIC Cluster Model (V4)", 0},
{ACPI_DMT_FLAG3, ACPI_FADT_FLAG_OFFSET (Flags,2), "Use APIC Physical Destination Mode (V4)", 0},
{ACPI_DMT_FLAG4, ACPI_FADT_FLAG_OFFSET (Flags,2), "Hardware Reduced (V5)", 0},
{ACPI_DMT_FLAG5, ACPI_FADT_FLAG_OFFSET (Flags,2), "Prefer S0 Idle (V5)", 0},
{ACPI_DMT_FLAG6, ACPI_FADT_FLAG_OFFSET (Flags,2), "Use Sleep Register (V5)", 0},
ACPI_DMT_TERMINATOR
};
@ -396,7 +432,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoFadt2[] =
ACPI_DMT_TERMINATOR
};
/* ACPI 2.0+ Extensions (FADT version 3+) */
/* ACPI 2.0+ Extensions (FADT version 3 and 4) */
ACPI_DMTABLE_INFO AcpiDmTableInfoFadt3[] =
{
@ -416,6 +452,14 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoFadt3[] =
ACPI_DMT_TERMINATOR
};
/* ACPI 5.0 Extensions (FADT version 5) */
ACPI_DMTABLE_INFO AcpiDmTableInfoFadt5[] =
{
{ACPI_DMT_GAS, ACPI_FADT_OFFSET (SleepRegister), "Sleep Register", 0},
ACPI_DMT_TERMINATOR
};
/*
* Remaining tables are not consumed directly by the ACPICA subsystem
@ -539,6 +583,24 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoBert[] =
};
/*******************************************************************************
*
* BGRT - Boot Graphics Resource Table (ACPI 5.0)
*
******************************************************************************/
ACPI_DMTABLE_INFO AcpiDmTableInfoBgrt[] =
{
{ACPI_DMT_UINT16, ACPI_BGRT_OFFSET (Version), "Version", 0},
{ACPI_DMT_UINT8, ACPI_BGRT_OFFSET (Status), "Status", 0},
{ACPI_DMT_UINT8, ACPI_BGRT_OFFSET (ImageType), "Image Type", 0},
{ACPI_DMT_UINT64, ACPI_BGRT_OFFSET (ImageAddress), "Image Address", 0},
{ACPI_DMT_UINT32, ACPI_BGRT_OFFSET (ImageOffsetX), "Image OffsetX", 0},
{ACPI_DMT_UINT32, ACPI_BGRT_OFFSET (ImageOffsetY), "Image OffsetY", 0},
ACPI_DMT_TERMINATOR
};
/*******************************************************************************
*
* BOOT - Simple Boot Flag Table
@ -670,6 +732,19 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoDmar3[] =
};
/*******************************************************************************
*
* DRTM - Dynamic Root of Trust for Measurement table
*
******************************************************************************/
ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm[] =
{
ACPI_DMT_TERMINATOR
};
/*******************************************************************************
*
* ECDT - Embedded Controller Boot Resources Table
@ -746,6 +821,82 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoErst0[] =
};
/*******************************************************************************
*
* FPDT - Firmware Performance Data Table (ACPI 5.0)
*
******************************************************************************/
/* Main table consists of only the standard ACPI header - subtables follow */
/* FPDT subtable header */
ACPI_DMTABLE_INFO AcpiDmTableInfoFpdtHdr[] =
{
{ACPI_DMT_UINT16, ACPI_FPDTH_OFFSET (Type), "Subtable Type", 0},
{ACPI_DMT_UINT8, ACPI_FPDTH_OFFSET (Length), "Length", DT_LENGTH},
{ACPI_DMT_UINT8, ACPI_FPDTH_OFFSET (Revision), "Revision", 0},
ACPI_DMT_TERMINATOR
};
/* 0: Firmware Basic Boot Performance Record */
ACPI_DMTABLE_INFO AcpiDmTableInfoFpdt0[] =
{
{ACPI_DMT_UINT32, ACPI_FPDT0_OFFSET (Reserved), "Reserved", 0},
{ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (ResetEnd), "Reset End", 0},
{ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (LoadStart), "Load Image Start", 0},
{ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (StartupStart), "Start Image Start", 0},
{ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (ExitServicesEntry), "Exit Services Entry", 0},
{ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (ExitServicesExit), "Exit Services Exit", 0},
ACPI_DMT_TERMINATOR
};
/* 1: S3 Performance Table Pointer Record */
ACPI_DMTABLE_INFO AcpiDmTableInfoFpdt1[] =
{
{ACPI_DMT_UINT32, ACPI_FPDT1_OFFSET (Reserved), "Reserved", 0},
{ACPI_DMT_UINT64, ACPI_FPDT1_OFFSET (Address), "S3PT Address", 0},
ACPI_DMT_TERMINATOR
};
/*******************************************************************************
*
* GTDT - Generic Timer Description Table
*
******************************************************************************/
ACPI_DMTABLE_INFO AcpiDmTableInfoGtdt[] =
{
{ACPI_DMT_UINT64, ACPI_GTDT_OFFSET (Address), "Timer Address", 0},
{ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
{ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (Flags,0), "Memory Present", 0},
ACPI_DMT_NEW_LINE,
{ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (SecurePl1Interrupt), "Secure PL1 Interrupt", 0},
{ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (SecurePl1Flags), "SPL1 Flags (decoded below)", DT_FLAG},
{ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (SecurePl1Flags,0), "Trigger Mode", 0},
{ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (SecurePl1Flags,0), "Polarity", 0},
ACPI_DMT_NEW_LINE,
{ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecurePl1Interrupt), "Non-Secure PL1 Interrupt", 0},
{ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecurePl1Flags), "NSPL1 Flags (decoded below)", DT_FLAG},
{ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (NonSecurePl1Flags,0),"Trigger Mode", 0},
{ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (NonSecurePl1Flags,0),"Polarity", 0},
ACPI_DMT_NEW_LINE,
{ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (VirtualTimerInterrupt), "Virtual Timer Interrupt", 0},
{ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (VirtualTimerFlags), "VT Flags (decoded below)", DT_FLAG},
{ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (VirtualTimerFlags,0),"Trigger Mode", 0},
{ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (VirtualTimerFlags,0),"Polarity", 0},
ACPI_DMT_NEW_LINE,
{ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecurePl2Interrupt), "Non-Secure PL2 Interrupt", 0},
{ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecurePl2Flags), "NSPL2 Flags (decoded below)", DT_FLAG},
{ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (NonSecurePl2Flags,0),"Trigger Mode", 0},
{ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (NonSecurePl2Flags,0),"Polarity", 0},
ACPI_DMT_TERMINATOR
};
/*******************************************************************************
*
* HEST - Hardware Error Source table
@ -1190,6 +1341,34 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMadt10[] =
ACPI_DMT_TERMINATOR
};
/* 11: Generic Interrupt Controller (ACPI 5.0) */
ACPI_DMTABLE_INFO AcpiDmTableInfoMadt11[] =
{
{ACPI_DMT_UINT16, ACPI_MADT11_OFFSET (Reserved), "Reserved", 0},
{ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (GicId), "Local GIC Hardware ID", 0},
{ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (Uid), "Processor UID", 0},
{ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
{ACPI_DMT_FLAG0, ACPI_MADT11_FLAG_OFFSET (Flags,0), "Processor Enabled", 0},
{ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (ParkingVersion), "Parking Protocol Version", 0},
{ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (PerformanceInterrupt), "Performance Interrupt", 0},
{ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (ParkedAddress), "Parked Address", 0},
{ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (BaseAddress), "Base Address", 0},
ACPI_DMT_TERMINATOR
};
/* 12: Generic Interrupt Distributor (ACPI 5.0) */
ACPI_DMTABLE_INFO AcpiDmTableInfoMadt12[] =
{
{ACPI_DMT_UINT16, ACPI_MADT12_OFFSET (Reserved), "Reserved", 0},
{ACPI_DMT_UINT32, ACPI_MADT12_OFFSET (GicId), "Local GIC Hardware ID", 0},
{ACPI_DMT_UINT64, ACPI_MADT12_OFFSET (BaseAddress), "Base Address", 0},
{ACPI_DMT_UINT32, ACPI_MADT12_OFFSET (GlobalIrqBase), "Interrupt Base", 0},
{ACPI_DMT_UINT32, ACPI_MADT12_OFFSET (Reserved2), "Reserved", 0},
ACPI_DMT_TERMINATOR
};
/*******************************************************************************
*
@ -1238,6 +1417,87 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMchi[] =
};
/*******************************************************************************
*
* MPST - Memory Power State Table
*
******************************************************************************/
ACPI_DMTABLE_INFO AcpiDmTableInfoMpst[] =
{
{ACPI_DMT_UINT16, ACPI_MPST_OFFSET (Reserved1), "Reserved", 0},
{ACPI_DMT_UINT8, ACPI_MPST_OFFSET (ChannelId), "Channel ID", 0},
{ACPI_DMT_UINT8, ACPI_MPST_OFFSET (Reserved2), "Reserved", 0},
{ACPI_DMT_UINT16, ACPI_MPST_OFFSET (PowerNodeCount), "Power Node Count", 0},
ACPI_DMT_TERMINATOR
};
/* MPST subtables */
/* 0: Memory Power Node Structure */
ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0[] =
{
{ACPI_DMT_UINT8, ACPI_MPST0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
{ACPI_DMT_FLAG0, ACPI_MPST0_FLAG_OFFSET (Flags,0), "Node Enabled", 0},
{ACPI_DMT_FLAG1, ACPI_MPST0_FLAG_OFFSET (Flags,0), "Power Managed", 0},
{ACPI_DMT_FLAG2, ACPI_MPST0_FLAG_OFFSET (Flags,0), "Hot Plug Capable", 0},
{ACPI_DMT_UINT8, ACPI_MPST0_OFFSET (Reserved1), "Reserved", 0},
{ACPI_DMT_UINT16, ACPI_MPST0_OFFSET (NodeId), "Node ID", 0},
{ACPI_DMT_UINT32, ACPI_MPST0_OFFSET (Length), "Length", DT_LENGTH},
{ACPI_DMT_UINT64, ACPI_MPST0_OFFSET (RangeAddress), "Range Address", 0},
{ACPI_DMT_UINT64, ACPI_MPST0_OFFSET (RangeLength), "Range Length", 0},
{ACPI_DMT_UINT8, ACPI_MPST0_OFFSET (NumPowerStates), "Num Power States", 0},
{ACPI_DMT_UINT8, ACPI_MPST0_OFFSET (NumPhysicalComponents), "Num Physical Components", 0},
{ACPI_DMT_UINT16, ACPI_MPST0_OFFSET (Reserved2), "Reserved", 0},
ACPI_DMT_TERMINATOR
};
/* 0A: Sub-subtable - Memory Power State Structure (follows Memory Power Node above) */
ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0A[] =
{
{ACPI_DMT_UINT8, ACPI_MPST0A_OFFSET (PowerState), "Power State", 0},
{ACPI_DMT_UINT8, ACPI_MPST0A_OFFSET (InfoIndex), "InfoIndex", 0},
ACPI_DMT_TERMINATOR
};
/* 0B: Sub-subtable - Physical Component ID Structure (follows Memory Power State(s) above) */
ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0B[] =
{
{ACPI_DMT_UINT16, ACPI_MPST0B_OFFSET (ComponentId), "Component Id", 0},
ACPI_DMT_TERMINATOR
};
/* 01: Power Characteristics Count (follows all Power Node(s) above) */
ACPI_DMTABLE_INFO AcpiDmTableInfoMpst1[] =
{
{ACPI_DMT_UINT16, ACPI_MPST1_OFFSET (CharacteristicsCount), "Characteristics Count", 0},
ACPI_DMT_TERMINATOR
};
/* 02: Memory Power State Characteristics Structure */
ACPI_DMTABLE_INFO AcpiDmTableInfoMpst2[] =
{
{ACPI_DMT_UINT8, ACPI_MPST2_OFFSET (Revision), "Revision", 0},
{ACPI_DMT_UINT8, ACPI_MPST2_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
{ACPI_DMT_FLAG0, ACPI_MPST2_FLAG_OFFSET (Flags,0), "Memory Preserved", 0},
{ACPI_DMT_FLAG1, ACPI_MPST2_FLAG_OFFSET (Flags,0), "Auto Entry", 0},
{ACPI_DMT_FLAG2, ACPI_MPST2_FLAG_OFFSET (Flags,0), "Auto Exit", 0},
{ACPI_DMT_UINT16, ACPI_MPST2_OFFSET (Reserved1), "Reserved", 0},
{ACPI_DMT_UINT32, ACPI_MPST2_OFFSET (AveragePower), "Average Power", 0},
{ACPI_DMT_UINT32, ACPI_MPST2_OFFSET (PowerSaving), "Power Saving", 0},
{ACPI_DMT_UINT64, ACPI_MPST2_OFFSET (ExitLatency), "Exit Latency", 0},
{ACPI_DMT_UINT64, ACPI_MPST2_OFFSET (Reserved2), "Reserved", 0},
ACPI_DMT_TERMINATOR
};
/*******************************************************************************
*
* MSCT - Maximum System Characteristics Table (ACPI 4.0)
@ -1267,6 +1527,155 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMsct0[] =
};
/*******************************************************************************
*
* PCCT - Platform Communications Channel Table (ACPI 5.0)
*
******************************************************************************/
ACPI_DMTABLE_INFO AcpiDmTableInfoPcct[] =
{
{ACPI_DMT_UINT32, ACPI_PCCT_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
{ACPI_DMT_FLAG0, ACPI_PCCT_FLAG_OFFSET (Flags,0), "Doorbell", 0},
{ACPI_DMT_UINT32, ACPI_PCCT_OFFSET (Latency), "Command Latency", 0},
{ACPI_DMT_UINT32, ACPI_PCCT_OFFSET (Reserved), "Reserved", 0},
ACPI_DMT_TERMINATOR
};
/* PCCT subtables */
/* 0: Generic Communications Subspace */
ACPI_DMTABLE_INFO AcpiDmTableInfoPcct0[] =
{
{ACPI_DMT_UINT8, ACPI_PCCT0_OFFSET (Header.Type), "Subtable Type", 0},
{ACPI_DMT_UINT8, ACPI_PCCT0_OFFSET (Header.Length), "Length", DT_LENGTH},
{ACPI_DMT_UINT48, ACPI_PCCT0_OFFSET (Reserved[0]), "Reserved", 0},
{ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (BaseAddress), "Base Address", 0},
{ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (Length), "Address Length", 0},
{ACPI_DMT_GAS, ACPI_PCCT0_OFFSET (DoorbellRegister), "Doorbell Register", 0},
{ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (PreserveMask), "Preserve Mask", 0},
{ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (WriteMask), "Write Mask", 0},
ACPI_DMT_TERMINATOR
};
/*******************************************************************************
*
* PMTT - Platform Memory Topology Table
*
******************************************************************************/
ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt[] =
{
{ACPI_DMT_UINT32, ACPI_PMTT_OFFSET (Reserved), "Reserved", 0},
ACPI_DMT_TERMINATOR
};
/* Common Subtable header (one per Subtable) */
ACPI_DMTABLE_INFO AcpiDmTableInfoPmttHdr[] =
{
{ACPI_DMT_PMTT, ACPI_PMTTH_OFFSET (Type), "Subtable Type", 0},
{ACPI_DMT_UINT8, ACPI_PMTTH_OFFSET (Reserved1), "Reserved", 0},
{ACPI_DMT_UINT16, ACPI_PMTTH_OFFSET (Length), "Length", DT_LENGTH},
{ACPI_DMT_UINT16, ACPI_PMTTH_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
{ACPI_DMT_FLAG0, ACPI_PMTTH_FLAG_OFFSET (Flags,0), "Top-level Device", 0},
{ACPI_DMT_FLAG1, ACPI_PMTTH_FLAG_OFFSET (Flags,0), "Physical Element", 0},
{ACPI_DMT_FLAGS2, ACPI_PMTTH_FLAG_OFFSET (Flags,0), "Memory Type", 0},
{ACPI_DMT_UINT16, ACPI_PMTTH_OFFSET (Reserved2), "Reserved", 0},
ACPI_DMT_TERMINATOR
};
/* PMTT Subtables */
/* 0: Socket */
ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt0[] =
{
{ACPI_DMT_UINT16, ACPI_PMTT0_OFFSET (SocketId), "Socket ID", 0},
{ACPI_DMT_UINT16, ACPI_PMTT0_OFFSET (Reserved), "Reserved", 0},
ACPI_DMT_TERMINATOR
};
/* 1: Memory Controller */
ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt1[] =
{
{ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (ReadLatency), "Read Latency", 0},
{ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (WriteLatency), "Write Latency", 0},
{ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (ReadBandwidth), "Read Bandwidth", 0},
{ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (WriteBandwidth), "Write Bandwidth", 0},
{ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (AccessWidth), "Access Width", 0},
{ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (Alignment), "Alignment", 0},
{ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (Reserved), "Reserved", 0},
{ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (DomainCount), "Domain Count", 0},
ACPI_DMT_TERMINATOR
};
/* 1a: Proximity Domain */
ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt1a[] =
{
{ACPI_DMT_UINT32, ACPI_PMTT1A_OFFSET (ProximityDomain), "Proximity Domain", 0},
ACPI_DMT_TERMINATOR
};
/* 2: Physical Component */
ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt2[] =
{
{ACPI_DMT_UINT16, ACPI_PMTT2_OFFSET (ComponentId), "Component ID", 0},
{ACPI_DMT_UINT16, ACPI_PMTT2_OFFSET (Reserved), "Reserved", 0},
{ACPI_DMT_UINT32, ACPI_PMTT2_OFFSET (MemorySize), "Memory Size", 0},
{ACPI_DMT_UINT32, ACPI_PMTT2_OFFSET (BiosHandle), "Bios Handle", 0},
ACPI_DMT_TERMINATOR
};
/*******************************************************************************
*
* S3PT - S3 Performance Table
*
******************************************************************************/
ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt[] =
{
{ACPI_DMT_SIG, ACPI_S3PT_OFFSET (Signature[0]), "Signature", 0},
{ACPI_DMT_UINT32, ACPI_S3PT_OFFSET (Length), "Length", DT_LENGTH},
ACPI_DMT_TERMINATOR
};
/* S3PT subtable header */
ACPI_DMTABLE_INFO AcpiDmTableInfoS3ptHdr[] =
{
{ACPI_DMT_UINT16, ACPI_S3PTH_OFFSET (Type), "Type", 0},
{ACPI_DMT_UINT8, ACPI_S3PTH_OFFSET (Length), "Length", DT_LENGTH},
{ACPI_DMT_UINT8, ACPI_S3PTH_OFFSET (Revision), "Revision", 0},
ACPI_DMT_TERMINATOR
};
/* 0: Basic S3 Resume Performance Record */
ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt0[] =
{
{ACPI_DMT_UINT32, ACPI_S3PT0_OFFSET (ResumeCount), "Resume Count", 0},
{ACPI_DMT_UINT64, ACPI_S3PT0_OFFSET (FullResume), "Full Resume", 0},
{ACPI_DMT_UINT64, ACPI_S3PT0_OFFSET (AverageResume), "Average Resume", 0},
ACPI_DMT_TERMINATOR
};
/* 1: Basic S3 Suspend Performance Record */
ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt1[] =
{
{ACPI_DMT_UINT64, ACPI_S3PT1_OFFSET (SuspendStart), "Suspend Start", 0},
{ACPI_DMT_UINT64, ACPI_S3PT1_OFFSET (SuspendEnd), "Suspend End", 0},
ACPI_DMT_TERMINATOR
};
/*******************************************************************************
*
* SBST - Smart Battery Specification Table
@ -1609,8 +2018,10 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoWdrt[] =
ACPI_DMT_TERMINATOR
};
/*! [Begin] no source code translation */
/*
* Generic types (used in UEFI)
* Generic types (used in UEFI and custom tables)
*
* Examples:
*
@ -1629,7 +2040,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoWdrt[] =
* DevicePath : "\PciRoot(0)\Pci(0x1f,1)\Usb(0,0)"
*/
#define ACPI_DM_GENERIC_ENTRY(FieldType, FieldName)\
#define ACPI_DM_GENERIC_ENTRY(FieldType, FieldName) \
{{FieldType, 0, FieldName, 0}, ACPI_DMT_TERMINATOR}
ACPI_DMTABLE_INFO AcpiDmTableInfoGeneric[][2] =
@ -1638,6 +2049,8 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoGeneric[][2] =
ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT16, "UINT16"),
ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT24, "UINT24"),
ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT32, "UINT32"),
ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT40, "UINT40"),
ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT48, "UINT48"),
ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT56, "UINT56"),
ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT64, "UINT64"),
ACPI_DM_GENERIC_ENTRY (ACPI_DMT_STRING, "String"),
@ -1648,3 +2061,4 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoGeneric[][2] =
ACPI_DM_GENERIC_ENTRY (ACPI_DMT_LABEL, "Label"),
{ACPI_DMT_TERMINATOR}
};
/*! [End] no source code translation !*/

View File

@ -126,7 +126,6 @@ AnCheckId (
{
UINT32 i;
ACPI_SIZE Length;
UINT32 AlphaPrefixLength;
/* Only care about string versions of _HID/_CID (integers are legal) */
@ -174,12 +173,18 @@ AnCheckId (
{
AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
Op, Op->Asl.Value.String);
break;
return;
}
}
/* _HID String must be of the form "XXX####" or "ACPI####" */
/*
* _HID String must be one of these forms:
*
* "AAA####" A is an uppercase letter and # is a hex digit
* "ACPI####" # is a hex digit
* "NNNN####" N is an uppercase letter or decimal digit (0-9)
* # is a hex digit (ACPI 5.0)
*/
if ((Length < 7) || (Length > 8))
{
AslError (ASL_ERROR, ASL_MSG_HID_LENGTH,
@ -187,22 +192,48 @@ AnCheckId (
return;
}
/* _HID Length is valid, now check for uppercase (first 3 or 4 chars) */
/* _HID Length is valid (7 or 8), now check the prefix (first 3 or 4 chars) */
AlphaPrefixLength = 3;
if (Length >= 8)
if (Length == 7)
{
AlphaPrefixLength = 4;
/* AAA####: Ensure the alphabetic prefix is all uppercase */
for (i = 0; i < 3; i++)
{
if (!isupper ((int) Op->Asl.Value.String[i]))
{
AslError (ASL_ERROR, ASL_MSG_UPPER_CASE,
Op, &Op->Asl.Value.String[i]);
return;
}
}
}
else /* Length == 8 */
{
/*
* ACPI#### or NNNN####:
* Ensure the prefix contains only uppercase alpha or decimal digits
*/
for (i = 0; i < 4; i++)
{
if (!isupper ((int) Op->Asl.Value.String[i]) &&
!isdigit ((int) Op->Asl.Value.String[i]))
{
AslError (ASL_ERROR, ASL_MSG_HID_PREFIX,
Op, &Op->Asl.Value.String[i]);
return;
}
}
}
/* Ensure the alphabetic prefix is all uppercase */
/* Remaining characters (suffix) must be hex digits */
for (i = 0; (i < AlphaPrefixLength) && Op->Asl.Value.String[i]; i++)
for (; i < Length; i++)
{
if (!isupper ((int) Op->Asl.Value.String[i]))
if (!isxdigit ((int) Op->Asl.Value.String[i]))
{
AslError (ASL_ERROR, ASL_MSG_UPPER_CASE,
Op, &Op->Asl.Value.String[i]);
AslError (ASL_ERROR, ASL_MSG_HID_SUFFIX,
Op, &Op->Asl.Value.String[i]);
break;
}
}

View File

@ -271,12 +271,17 @@ CgWriteAmlOpcode (
/* Special opcodes for within a field definition */
Aml.Opcode = 0x00;
Aml.Opcode = AML_FIELD_OFFSET_OP;
break;
case AML_INT_ACCESSFIELD_OP:
Aml.Opcode = 0x01;
Aml.Opcode = AML_FIELD_ACCESS_OP;
break;
case AML_INT_CONNECTION_OP:
Aml.Opcode = AML_FIELD_CONNECTION_OP;
break;
default:

View File

@ -472,6 +472,8 @@ CmDoCompile (
if (!RootNode)
{
AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
NULL, "- Could not resolve parse tree root node");
CmCleanupAndExit ();
return -1;
}

View File

@ -289,7 +289,7 @@ AslCoreSubsystemError (
int
AslCompilererror(
char *s);
const char *s);
void
AslCommonError (
@ -829,17 +829,12 @@ RsAllocateResourceNode (
UINT32 Size);
void
RsCreateBitField (
RsCreateResourceField (
ACPI_PARSE_OBJECT *Op,
char *Name,
UINT32 ByteOffset,
UINT32 BitOffset);
void
RsCreateByteField (
ACPI_PARSE_OBJECT *Op,
char *Name,
UINT32 ByteOffset);
UINT32 BitOffset,
UINT32 BitLength);
void
RsSetFlagBits (
@ -848,6 +843,13 @@ RsSetFlagBits (
UINT8 Position,
UINT8 DefaultBit);
void
RsSetFlagBits16 (
UINT16 *Flags,
ACPI_PARSE_OBJECT *Op,
UINT8 Position,
UINT8 DefaultBit);
ACPI_PARSE_OBJECT *
RsCompleteNodeAndGetNext (
ACPI_PARSE_OBJECT *Op);
@ -930,6 +932,11 @@ RsDoDmaDescriptor (
ACPI_PARSE_OBJECT *Op,
UINT32 CurrentByteOffset);
ASL_RESOURCE_NODE *
RsDoFixedDmaDescriptor (
ACPI_PARSE_OBJECT *Op,
UINT32 CurrentByteOffset);
ASL_RESOURCE_NODE *
RsDoFixedIoDescriptor (
ACPI_PARSE_OBJECT *Op,
@ -969,6 +976,30 @@ RsDoGeneralRegisterDescriptor (
ACPI_PARSE_OBJECT *Op,
UINT32 CurrentByteOffset);
ASL_RESOURCE_NODE *
RsDoGpioIntDescriptor (
ACPI_PARSE_OBJECT *Op,
UINT32 CurrentByteOffset);
ASL_RESOURCE_NODE *
RsDoGpioIoDescriptor (
ACPI_PARSE_OBJECT *Op,
UINT32 CurrentByteOffset);
ASL_RESOURCE_NODE *
RsDoI2cSerialBusDescriptor (
ACPI_PARSE_OBJECT *Op,
UINT32 CurrentByteOffset);
ASL_RESOURCE_NODE *
RsDoSpiSerialBusDescriptor (
ACPI_PARSE_OBJECT *Op,
UINT32 CurrentByteOffset);
ASL_RESOURCE_NODE *
RsDoUartSerialBusDescriptor (
ACPI_PARSE_OBJECT *Op,
UINT32 CurrentByteOffset);
/*
* aslrestype2d - DWord address descriptors

View File

@ -1,8 +1,7 @@
%{
/******************************************************************************
*
* Module Name: aslcompiler.l - Flex input file
* Module Name: aslcompiler.l - Flex/lex input file
*
*****************************************************************************/
@ -60,6 +59,9 @@ YYSTYPE AslCompilerlval;
#define _COMPONENT ACPI_COMPILER
ACPI_MODULE_NAME ("aslscan")
/* Local prototypes */
char
comment (void);
char
@ -74,7 +76,7 @@ copy (void);
/*! [Begin] no source code translation */
%}
/* Definitions */
LeadNameChar [A-Za-z_]
DigitChar [0-9]
@ -94,6 +96,7 @@ NonEmptyNamePath {NameSeg}{NamePathTail}*
NamePathTail [.]{NameSeg}
%%
/* Rules */
[ ] { count (0); }
[\n] { count (0); } /* Handle files with both LF and CR/LF */
@ -105,6 +108,7 @@ NamePathTail [.]{NameSeg}
"//" { if (!comment2 ()) yyterminate (); }
"\"" { if (literal ()) return (PARSEOP_STRING_LITERAL); else yyterminate (); }
";" { count (0); return(';'); }
0[xX]{HexDigitChar}+ |
@ -116,15 +120,28 @@ NamePathTail [.]{NameSeg}
"#line" { count (1); return (PARSEOP_LINE_CSTYLE); }
"External" { count (1); return (PARSEOP_EXTERNAL); }
/****************************************************************************
*
* Main ASL operators
*
****************************************************************************/
"Ones" { count (1); return (PARSEOP_ONES); }
"One" { count (1); return (PARSEOP_ONE); }
"Zero" { count (1); return (PARSEOP_ZERO); }
"Revision" { count (1); return (PARSEOP_REVISION); }
"Offset" { count (1); return (PARSEOP_OFFSET); }
"AccessAs" { count (1); return (PARSEOP_ACCESSAS); }
"Acquire" { count (3); return (PARSEOP_ACQUIRE); }
"Add" { count (3); return (PARSEOP_ADD); }
"Alias" { count (2); return (PARSEOP_ALIAS); }
"And" { count (3); return (PARSEOP_AND); }
"BankField" { count (2); return (PARSEOP_BANKFIELD); }
"Break" { count (3); return (PARSEOP_BREAK); }
"BreakPoint" { count (3); return (PARSEOP_BREAKPOINT); }
"Buffer" { count (1); return (PARSEOP_BUFFER); }
"Case" { count (3); return (PARSEOP_CASE); }
"Concatenate" { count (3); return (PARSEOP_CONCATENATE); }
"ConcatenateResTemplate" { count (3); return (PARSEOP_CONCATENATERESTEMPLATE); }
"CondRefOf" { count (3); return (PARSEOP_CONDREFOF); }
"Connection" { count (2); return (PARSEOP_CONNECTION); }
"Continue" { count (3); return (PARSEOP_CONTINUE); }
"CopyObject" { count (3); return (PARSEOP_COPYOBJECT); }
"CreateBitField" { count (2); return (PARSEOP_CREATEBITFIELD); }
"CreateByteField" { count (2); return (PARSEOP_CREATEBYTEFIELD); }
"CreateDWordField" { count (2); return (PARSEOP_CREATEDWORDFIELD); }
@ -132,57 +149,27 @@ NamePathTail [.]{NameSeg}
"CreateQWordField" { count (2); return (PARSEOP_CREATEQWORDFIELD); }
"CreateWordField" { count (2); return (PARSEOP_CREATEWORDFIELD); }
"DataTableRegion" { count (2); return (PARSEOP_DATATABLEREGION); }
"Debug" { count (1); return (PARSEOP_DEBUG); }
"Decrement" { count (3); return (PARSEOP_DECREMENT); }
"Default" { count (3); return (PARSEOP_DEFAULT); }
"DefinitionBlock" { count (1); return (PARSEOP_DEFINITIONBLOCK); }
"DeRefOf" { count (3); return (PARSEOP_DEREFOF); }
"Device" { count (2); return (PARSEOP_DEVICE); }
"Event" { count (2); return (PARSEOP_EVENT); }
"Field" { count (2); return (PARSEOP_FIELD); }
"Function" { count (2); return (PARSEOP_FUNCTION); }
"IndexField" { count (2); return (PARSEOP_INDEXFIELD); }
"Method" { count (2); return (PARSEOP_METHOD); }
"Mutex" { count (2); return (PARSEOP_MUTEX); }
"OperationRegion" { count (2); return (PARSEOP_OPERATIONREGION); }
"PowerResource" { count (2); return (PARSEOP_POWERRESOURCE); }
"Processor" { count (2); return (PARSEOP_PROCESSOR); }
"ThermalZone" { count (2); return (PARSEOP_THERMALZONE); }
"Alias" { count (2); return (PARSEOP_ALIAS); }
"Name" { count (2); return (PARSEOP_NAME); }
"Scope" { count (2); return (PARSEOP_SCOPE); }
"Break" { count (3); return (PARSEOP_BREAK); }
"BreakPoint" { count (3); return (PARSEOP_BREAKPOINT); }
"Continue" { count (3); return (PARSEOP_CONTINUE); }
"Fatal" { count (3); return (PARSEOP_FATAL); }
"If" { count (3); return (PARSEOP_IF); }
"Divide" { count (3); return (PARSEOP_DIVIDE); }
"Eisaid" { count (1); return (PARSEOP_EISAID); }
"Else" { count (3); return (PARSEOP_ELSE); }
"ElseIf" { count (3); return (PARSEOP_ELSEIF); }
"Load" { count (3); return (PARSEOP_LOAD); }
"Noop" { count (3); return (PARSEOP_NOOP); }
"Notify" { count (3); return (PARSEOP_NOTIFY); }
"Release" { count (3); return (PARSEOP_RELEASE); }
"Reset" { count (3); return (PARSEOP_RESET); }
"Return" { count (3); return (PARSEOP_RETURN); }
"Signal" { count (3); return (PARSEOP_SIGNAL); }
"Sleep" { count (3); return (PARSEOP_SLEEP); }
"Stall" { count (3); return (PARSEOP_STALL); }
"Switch" { count (3); return (PARSEOP_SWITCH); }
"Case" { count (3); return (PARSEOP_CASE); }
"Default" { count (3); return (PARSEOP_DEFAULT); }
"Unload" { count (3); return (PARSEOP_UNLOAD); }
"While" { count (3); return (PARSEOP_WHILE); }
"Acquire" { count (3); return (PARSEOP_ACQUIRE); }
"Add" { count (3); return (PARSEOP_ADD); }
"And" { count (3); return (PARSEOP_AND); }
"Concatenate" { count (3); return (PARSEOP_CONCATENATE); }
"ConcatenateResTemplate" { count (3); return (PARSEOP_CONCATENATERESTEMPLATE); }
"CondRefOf" { count (3); return (PARSEOP_CONDREFOF); }
"CopyObject" { count (3); return (PARSEOP_COPYOBJECT); }
"Decrement" { count (3); return (PARSEOP_DECREMENT); }
"DeRefOf" { count (3); return (PARSEOP_DEREFOF); }
"Divide" { count (3); return (PARSEOP_DIVIDE); }
"Event" { count (2); return (PARSEOP_EVENT); }
"Fatal" { count (3); return (PARSEOP_FATAL); }
"Field" { count (2); return (PARSEOP_FIELD); }
"FindSetLeftBit" { count (3); return (PARSEOP_FINDSETLEFTBIT); }
"FindSetRightBit" { count (3); return (PARSEOP_FINDSETRIGHTBIT); }
"FromBCD" { count (3); return (PARSEOP_FROMBCD); }
"FromBcd" { count (3); return (PARSEOP_FROMBCD); }
"Function" { count (2); return (PARSEOP_FUNCTION); }
"If" { count (3); return (PARSEOP_IF); }
"Increment" { count (3); return (PARSEOP_INCREMENT); }
"Index" { count (3); return (PARSEOP_INDEX); }
"IndexField" { count (2); return (PARSEOP_INDEXFIELD); }
"LAnd" { count (3); return (PARSEOP_LAND); }
"LEqual" { count (3); return (PARSEOP_LEQUAL); }
"LGreater" { count (3); return (PARSEOP_LGREATER); }
@ -191,32 +178,62 @@ NamePathTail [.]{NameSeg}
"LLessEqual" { count (3); return (PARSEOP_LLESSEQUAL); }
"LNot" { count (3); return (PARSEOP_LNOT); }
"LNotEqual" { count (3); return (PARSEOP_LNOTEQUAL); }
"Load" { count (3); return (PARSEOP_LOAD); }
"LoadTable" { count (3); return (PARSEOP_LOADTABLE); }
"LOr" { count (3); return (PARSEOP_LOR); }
"Match" { count (3); return (PARSEOP_MATCH); }
"Method" { count (2); return (PARSEOP_METHOD); }
"Mid" { count (3); return (PARSEOP_MID); }
"Mod" { count (3); return (PARSEOP_MOD); }
"Multiply" { count (3); return (PARSEOP_MULTIPLY); }
"Mutex" { count (2); return (PARSEOP_MUTEX); }
"Name" { count (2); return (PARSEOP_NAME); }
"NAnd" { count (3); return (PARSEOP_NAND); }
"Noop" { count (3); return (PARSEOP_NOOP); }
"NOr" { count (3); return (PARSEOP_NOR); }
"Not" { count (3); return (PARSEOP_NOT); }
"Notify" { count (3); return (PARSEOP_NOTIFY); }
"ObjectType" { count (3); return (PARSEOP_OBJECTTYPE); }
"Offset" { count (1); return (PARSEOP_OFFSET); }
"One" { count (1); return (PARSEOP_ONE); }
"Ones" { count (1); return (PARSEOP_ONES); }
"OperationRegion" { count (2); return (PARSEOP_OPERATIONREGION); }
"Or" { count (3); return (PARSEOP_OR); }
"Package" { count (1); return (PARSEOP_PACKAGE); }
"PowerResource" { count (2); return (PARSEOP_POWERRESOURCE); }
"Processor" { count (2); return (PARSEOP_PROCESSOR); }
"RefOf" { count (3); return (PARSEOP_REFOF); }
"Release" { count (3); return (PARSEOP_RELEASE); }
"Reset" { count (3); return (PARSEOP_RESET); }
"Return" { count (3); return (PARSEOP_RETURN); }
"Revision" { count (1); return (PARSEOP_REVISION); }
"Scope" { count (2); return (PARSEOP_SCOPE); }
"ShiftLeft" { count (3); return (PARSEOP_SHIFTLEFT); }
"ShiftRight" { count (3); return (PARSEOP_SHIFTRIGHT); }
"Signal" { count (3); return (PARSEOP_SIGNAL); }
"SizeOf" { count (3); return (PARSEOP_SIZEOF); }
"Sleep" { count (3); return (PARSEOP_SLEEP); }
"Stall" { count (3); return (PARSEOP_STALL); }
"Store" { count (3); return (PARSEOP_STORE); }
"Subtract" { count (3); return (PARSEOP_SUBTRACT); }
"Switch" { count (3); return (PARSEOP_SWITCH); }
"ThermalZone" { count (2); return (PARSEOP_THERMALZONE); }
"Timer" { count (3); return (PARSEOP_TIMER); }
"ToBCD" { count (3); return (PARSEOP_TOBCD); }
"ToBcd" { count (3); return (PARSEOP_TOBCD); }
"ToBuffer" { count (3); return (PARSEOP_TOBUFFER); }
"ToDecimalString" { count (3); return (PARSEOP_TODECIMALSTRING); }
"ToHexString" { count (3); return (PARSEOP_TOHEXSTRING); }
"ToInteger" { count (3); return (PARSEOP_TOINTEGER); }
"ToString" { count (3); return (PARSEOP_TOSTRING); }
"ToUuid" { count (1); return (PARSEOP_TOUUID); }
"Unicode" { count (1); return (PARSEOP_UNICODE); }
"Unload" { count (3); return (PARSEOP_UNLOAD); }
"Wait" { count (3); return (PARSEOP_WAIT); }
"While" { count (3); return (PARSEOP_WHILE); }
"XOr" { count (3); return (PARSEOP_XOR); }
"Zero" { count (1); return (PARSEOP_ZERO); }
/* Control method arguments and locals */
"Arg0" { count (1); return (PARSEOP_ARG0); }
"Arg1" { count (1); return (PARSEOP_ARG1); }
@ -225,7 +242,6 @@ NamePathTail [.]{NameSeg}
"Arg4" { count (1); return (PARSEOP_ARG4); }
"Arg5" { count (1); return (PARSEOP_ARG5); }
"Arg6" { count (1); return (PARSEOP_ARG6); }
"Local0" { count (1); return (PARSEOP_LOCAL0); }
"Local1" { count (1); return (PARSEOP_LOCAL1); }
"Local2" { count (1); return (PARSEOP_LOCAL2); }
@ -235,16 +251,16 @@ NamePathTail [.]{NameSeg}
"Local6" { count (1); return (PARSEOP_LOCAL6); }
"Local7" { count (1); return (PARSEOP_LOCAL7); }
"Debug" { count (1); return (PARSEOP_DEBUG); }
"DefinitionBlock" { count (1); return (PARSEOP_DEFINITIONBLOCK); }
"Buffer" { count (1); return (PARSEOP_BUFFER); }
"Package" { count (1); return (PARSEOP_PACKAGE); }
/****************************************************************************
*
* Resource Descriptor macros
*
****************************************************************************/
"EISAID" { count (1); return (PARSEOP_EISAID); }
"ResourceTemplate" { count (1); return (PARSEOP_RESOURCETEMPLATE); }
"ToUUID" { count (1); return (PARSEOP_TOUUID); }
"Unicode" { count (1); return (PARSEOP_UNICODE); }
"RawDataBuffer" { count (1); return (PARSEOP_DATABUFFER); }
"DMA" { count (1); return (PARSEOP_DMA); }
"DWordIO" { count (1); return (PARSEOP_DWORDIO); }
"DWordMemory" { count (1); return (PARSEOP_DWORDMEMORY); }
@ -253,26 +269,188 @@ NamePathTail [.]{NameSeg}
"ExtendedIO" { count (1); return (PARSEOP_EXTENDEDIO); }
"ExtendedMemory" { count (1); return (PARSEOP_EXTENDEDMEMORY); }
"ExtendedSpace" { count (1); return (PARSEOP_EXTENDEDSPACE); }
"FixedDma" { count (1); return (PARSEOP_FIXEDDMA); }
"FixedIO" { count (1); return (PARSEOP_FIXEDIO); }
"GpioInt" { count (1); return (PARSEOP_GPIO_INT); }
"GpioIo" { count (1); return (PARSEOP_GPIO_IO); }
"I2cSerialBus" { count (1); return (PARSEOP_I2C_SERIALBUS); }
"Interrupt" { count (1); return (PARSEOP_INTERRUPT); }
"IO" { count (1); return (PARSEOP_IO); }
"IRQNoFlags" { count (1); return (PARSEOP_IRQNOFLAGS); }
"IRQ" { count (1); return (PARSEOP_IRQ); }
"IRQNoFlags" { count (1); return (PARSEOP_IRQNOFLAGS); }
"Memory24" { count (1); return (PARSEOP_MEMORY24); }
"Memory32Fixed" { count (1); return (PARSEOP_MEMORY32FIXED); }
"Memory32" { count (1); return (PARSEOP_MEMORY32); }
"Memory32Fixed" { count (1); return (PARSEOP_MEMORY32FIXED); }
"QWordIO" { count (1); return (PARSEOP_QWORDIO); }
"QWordMemory" { count (1); return (PARSEOP_QWORDMEMORY); }
"QWordSpace" { count (1); return (PARSEOP_QWORDSPACE); }
"Register" { count (1); return (PARSEOP_REGISTER); }
"SpiSerialBus" { count (1); return (PARSEOP_SPI_SERIALBUS); }
"StartDependentFn" { count (1); return (PARSEOP_STARTDEPENDENTFN); }
"StartDependentFnNoPri" { count (1); return (PARSEOP_STARTDEPENDENTFN_NOPRI); }
"UartSerialBus" { count (1); return (PARSEOP_UART_SERIALBUS); }
"VendorLong" { count (1); return (PARSEOP_VENDORLONG); }
"VendorShort" { count (1); return (PARSEOP_VENDORSHORT); }
"WordBusNumber" { count (1); return (PARSEOP_WORDBUSNUMBER); }
"WordIO" { count (1); return (PARSEOP_WORDIO); }
"WordSpace" { count (1); return (PARSEOP_WORDSPACE); }
/****************************************************************************
*
* Keywords used as arguments to ASL operators and macros
*
****************************************************************************/
/* AccessAttribKeyword: Serial Bus Attributes (ACPI 5.0) */
"AttribQuick" { count (0); return (PARSEOP_ACCESSATTRIB_QUICK); }
"AttribSendReceive" { count (0); return (PARSEOP_ACCESSATTRIB_SND_RCV); }
"AttribByte" { count (0); return (PARSEOP_ACCESSATTRIB_BYTE); }
"AttribWord" { count (0); return (PARSEOP_ACCESSATTRIB_WORD); }
"AttribBlock" { count (0); return (PARSEOP_ACCESSATTRIB_BLOCK); }
"AttribProcessCall" { count (0); return (PARSEOP_ACCESSATTRIB_WORD_CALL); }
"AttribBlockProcessCall" { count (0); return (PARSEOP_ACCESSATTRIB_BLOCK_CALL); }
/* AccessAttribKeyword: Legacy synonyms for above (pre-ACPI 5.0) */
"SMBQuick" { count (0); return (PARSEOP_ACCESSATTRIB_QUICK); }
"SMBSendReceive" { count (0); return (PARSEOP_ACCESSATTRIB_SND_RCV); }
"SMBByte" { count (0); return (PARSEOP_ACCESSATTRIB_BYTE); }
"SMBWord" { count (0); return (PARSEOP_ACCESSATTRIB_WORD); }
"SMBBlock" { count (0); return (PARSEOP_ACCESSATTRIB_BLOCK); }
"SMBProcessCall" { count (0); return (PARSEOP_ACCESSATTRIB_WORD_CALL); }
"SMBBlockProcessCall" { count (0); return (PARSEOP_ACCESSATTRIB_BLOCK_CALL); }
/* AccessTypeKeyword: Field Access Types */
"AnyAcc" { count (0); return (PARSEOP_ACCESSTYPE_ANY); }
"ByteAcc" { count (0); return (PARSEOP_ACCESSTYPE_BYTE); }
"WordAcc" { count (0); return (PARSEOP_ACCESSTYPE_WORD); }
"DWordAcc" { count (0); return (PARSEOP_ACCESSTYPE_DWORD); }
"QWordAcc" { count (0); return (PARSEOP_ACCESSTYPE_QWORD); }
"BufferAcc" { count (0); return (PARSEOP_ACCESSTYPE_BUF); }
/* AddressingModeKeyword: Mode - Resource Descriptors (ACPI 5.0) */
"AddressingMode7Bit" { count (0); return (PARSEOP_ADDRESSINGMODE_7BIT); }
"AddressingMode10Bit" { count (0); return (PARSEOP_ADDRESSINGMODE_10BIT); }
/* AddressKeyword: ACPI memory range types */
"AddressRangeMemory" { count (0); return (PARSEOP_ADDRESSTYPE_MEMORY); }
"AddressRangeReserved" { count (0); return (PARSEOP_ADDRESSTYPE_RESERVED); }
"AddressRangeNVS" { count (0); return (PARSEOP_ADDRESSTYPE_NVS); }
"AddressRangeACPI" { count (0); return (PARSEOP_ADDRESSTYPE_ACPI); }
/* BusMasterKeyword: DMA Bus Mastering */
"BusMaster" { count (0); return (PARSEOP_BUSMASTERTYPE_MASTER); }
"NotBusMaster" { count (0); return (PARSEOP_BUSMASTERTYPE_NOTMASTER); }
/* ByteLengthKeyword: Bits per Byte - Resource Descriptors (ACPI 5.0) */
"DataBitsFive" { count (0); return (PARSEOP_BITSPERBYTE_FIVE); }
"DataBitsSix" { count (0); return (PARSEOP_BITSPERBYTE_SIX); }
"DataBitsSeven" { count (0); return (PARSEOP_BITSPERBYTE_SEVEN); }
"DataBitsEight" { count (0); return (PARSEOP_BITSPERBYTE_EIGHT); }
"DataBitsNine" { count (0); return (PARSEOP_BITSPERBYTE_NINE); }
/* ClockPhaseKeyword: Resource Descriptors (ACPI 5.0) */
"ClockPhaseFirst" { count (0); return (PARSEOP_CLOCKPHASE_FIRST); }
"ClockPhaseSecond" { count (0); return (PARSEOP_CLOCKPHASE_SECOND); }
/* ClockPolarityKeyword: Resource Descriptors (ACPI 5.0) */
"ClockPolarityLow" { count (0); return (PARSEOP_CLOCKPOLARITY_LOW); }
"ClockPolarityHigh" { count (0); return (PARSEOP_CLOCKPOLARITY_HIGH); }
/* DecodeKeyword: Type of Memory Decoding - Resource Descriptors */
"PosDecode" { count (0); return (PARSEOP_DECODETYPE_POS); }
"SubDecode" { count (0); return (PARSEOP_DECODETYPE_SUB); }
/* DmaTypeKeyword: DMA Types - DMA Resource Descriptor */
"Compatibility" { count (0); return (PARSEOP_DMATYPE_COMPATIBILITY); }
"TypeA" { count (0); return (PARSEOP_DMATYPE_A); }
"TypeB" { count (0); return (PARSEOP_DMATYPE_B); }
"TypeF" { count (0); return (PARSEOP_DMATYPE_F); }
/* EndianKeyword: Endian type - Resource Descriptor (ACPI 5.0) */
"LittleEndian" { count (0); return (PARSEOP_ENDIAN_LITTLE); }
"BigEndian" { count (0); return (PARSEOP_ENDIAN_BIG); }
/* ExtendedAttribKeyword: Bus attributes, AccessAs operator (ACPI 5.0) */
"AttribBytes" { count (0); return (PARSEOP_ACCESSATTRIB_MULTIBYTE); }
"AttribRawBytes" { count (0); return (PARSEOP_ACCESSATTRIB_RAW_BYTES); }
"AttribRawProcessBytes" { count (0); return (PARSEOP_ACCESSATTRIB_RAW_PROCESS); }
/* FlowControlKeyword: Resource Descriptors (ACPI 5.0) */
"FlowControlHardware" { count (0); return (PARSEOP_FLOWCONTROL_HW); }
"FlowControlNone" { count (0); return (PARSEOP_FLOWCONTROL_NONE); }
"FlowControlXon" { count (0); return (PARSEOP_FLOWCONTROL_SW); }
/* InterruptLevelKeyword: Interrupt Active Types */
"ActiveBoth" { count (0); return (PARSEOP_INTLEVEL_ACTIVEBOTH); }
"ActiveHigh" { count (0); return (PARSEOP_INTLEVEL_ACTIVEHIGH); }
"ActiveLow" { count (0); return (PARSEOP_INTLEVEL_ACTIVELOW); }
/* InterruptTypeKeyword: Interrupt Types */
"Edge" { count (0); return (PARSEOP_INTTYPE_EDGE); }
"Level" { count (0); return (PARSEOP_INTTYPE_LEVEL); }
/* IoDecodeKeyword: Type of Memory Decoding - Resource Descriptors */
"Decode10" { count (0); return (PARSEOP_IODECODETYPE_10); }
"Decode16" { count (0); return (PARSEOP_IODECODETYPE_16); }
/* IoRestrictionKeyword: I/O Restriction - GPIO Resource Descriptors (ACPI 5.0) */
"IoRestrictionNone" { count (0); return (PARSEOP_IORESTRICT_NONE); }
"IoRestrictionInputOnly" { count (0); return (PARSEOP_IORESTRICT_IN); }
"IoRestrictionOutputOnly" { count (0); return (PARSEOP_IORESTRICT_OUT); }
"IoRestrictionNoneAndPreserve" { count (0); return (PARSEOP_IORESTRICT_PRESERVE); }
/* LockRuleKeyword: Global Lock use for Field Operator */
"Lock" { count (0); return (PARSEOP_LOCKRULE_LOCK); }
"NoLock" { count (0); return (PARSEOP_LOCKRULE_NOLOCK); }
/* MatchOpKeyword: Types for Match Operator */
"MTR" { count (0); return (PARSEOP_MATCHTYPE_MTR); }
"MEQ" { count (0); return (PARSEOP_MATCHTYPE_MEQ); }
"MLE" { count (0); return (PARSEOP_MATCHTYPE_MLE); }
"MLT" { count (0); return (PARSEOP_MATCHTYPE_MLT); }
"MGE" { count (0); return (PARSEOP_MATCHTYPE_MGE); }
"MGT" { count (0); return (PARSEOP_MATCHTYPE_MGT); }
/* MaxKeyword: Max Range Type - Resource Descriptors */
"MaxFixed" { count (0); return (PARSEOP_MAXTYPE_FIXED); }
"MaxNotFixed" { count (0); return (PARSEOP_MAXTYPE_NOTFIXED); }
/* MemTypeKeyword: Memory Types - Resource Descriptors */
"Cacheable" { count (0); return (PARSEOP_MEMTYPE_CACHEABLE); }
"WriteCombining" { count (0); return (PARSEOP_MEMTYPE_WRITECOMBINING); }
"Prefetchable" { count (0); return (PARSEOP_MEMTYPE_PREFETCHABLE); }
"NonCacheable" { count (0); return (PARSEOP_MEMTYPE_NONCACHEABLE); }
/* MinKeyword: Min Range Type - Resource Descriptors */
"MinFixed" { count (0); return (PARSEOP_MINTYPE_FIXED); }
"MinNotFixed" { count (0); return (PARSEOP_MINTYPE_NOTFIXED); }
/* ObjectTypeKeyword: ACPI Object Types */
"UnknownObj" { count (0); return (PARSEOP_OBJECTTYPE_UNK); }
"IntObj" { count (0); return (PARSEOP_OBJECTTYPE_INT); }
"StrObj" { count (0); return (PARSEOP_OBJECTTYPE_STR); }
@ -290,22 +468,38 @@ NamePathTail [.]{NameSeg}
"BuffFieldObj" { count (0); return (PARSEOP_OBJECTTYPE_BFF); }
"DDBHandleObj" { count (0); return (PARSEOP_OBJECTTYPE_DDB); }
"AnyAcc" { count (0); return (PARSEOP_ACCESSTYPE_ANY); }
"ByteAcc" { count (0); return (PARSEOP_ACCESSTYPE_BYTE); }
"WordAcc" { count (0); return (PARSEOP_ACCESSTYPE_WORD); }
"DWordAcc" { count (0); return (PARSEOP_ACCESSTYPE_DWORD); }
"QWordAcc" { count (0); return (PARSEOP_ACCESSTYPE_QWORD); }
"BufferAcc" { count (0); return (PARSEOP_ACCESSTYPE_BUF); }
/* ParityKeyword: Resource Descriptors (ACPI 5.0) */
"Lock" { count (0); return (PARSEOP_LOCKRULE_LOCK); }
"NoLock" { count (0); return (PARSEOP_LOCKRULE_NOLOCK); }
"ParityTypeSpace" { count (0); return (PARSEOP_PARITYTYPE_SPACE); }
"ParityTypeMark" { count (0); return (PARSEOP_PARITYTYPE_MARK); }
"ParityTypeOdd" { count (0); return (PARSEOP_PARITYTYPE_ODD); }
"ParityTypeEven" { count (0); return (PARSEOP_PARITYTYPE_EVEN); }
"ParityTypeNone" { count (0); return (PARSEOP_PARITYTYPE_NONE); }
"Preserve" { count (0); return (PARSEOP_UPDATERULE_PRESERVE); }
"WriteAsOnes" { count (0); return (PARSEOP_UPDATERULE_ONES); }
"WriteAsZeros" { count (0); return (PARSEOP_UPDATERULE_ZEROS); }
/* PinConfigKeyword: Pin Configuration - GPIO Resource Descriptors (ACPI 5.0) */
"Serialized" { count (0); return (PARSEOP_SERIALIZERULE_SERIAL); }
"NotSerialized" { count (0); return (PARSEOP_SERIALIZERULE_NOTSERIAL); }
"PullDefault" { count (0); return (PARSEOP_PIN_PULLDEFAULT); }
"PullUp" { count (0); return (PARSEOP_PIN_PULLUP); }
"PullDown" { count (0); return (PARSEOP_PIN_PULLDOWN); }
"PullNone" { count (0); return (PARSEOP_PIN_NOPULL); }
/* PolarityKeyword: Resource Descriptors (ACPI 5.0) */
"PolarityLow" { count (0); return (PARSEOP_DEVICEPOLARITY_LOW); }
"PolarityHigh" { count (0); return (PARSEOP_DEVICEPOLARITY_HIGH); }
/* RangeTypeKeyword: I/O Range Types - Resource Descriptors */
"ISAOnlyRanges" { count (0); return (PARSEOP_RANGETYPE_ISAONLY); }
"NonISAOnlyRanges" { count (0); return (PARSEOP_RANGETYPE_NONISAONLY); }
"EntireRange" { count (0); return (PARSEOP_RANGETYPE_ENTIRE); }
/* ReadWriteKeyword: Memory Access Types - Resource Descriptors */
"ReadWrite" { count (0); return (PARSEOP_READWRITETYPE_BOTH); }
"ReadOnly" { count (0); return (PARSEOP_READWRITETYPE_READONLY); }
/* RegionSpaceKeyword: Operation Region Address Space Types */
"SystemIO" { count (0); return (PARSEOP_REGIONSPACE_IO); }
"SystemMemory" { count (0); return (PARSEOP_REGIONSPACE_MEM); }
@ -315,86 +509,82 @@ NamePathTail [.]{NameSeg}
"SystemCMOS" { count (0); return (PARSEOP_REGIONSPACE_CMOS); }
"PciBarTarget" { count (0); return (PARSEOP_REGIONSPACE_PCIBAR); }
"IPMI" { count (0); return (PARSEOP_REGIONSPACE_IPMI); }
"GeneralPurposeIo" { count (0); return (PARSEOP_REGIONSPACE_GPIO); } /* ACPI 5.0 */
"GenericSerialBus" { count (0); return (PARSEOP_REGIONSPACE_GSBUS); } /* ACPI 5.0 */
"FFixedHW" { count (0); return (PARSEOP_REGIONSPACE_FFIXEDHW); }
"FFixedHW" { count (0); return (PARSEOP_ADDRESSSPACE_FFIXEDHW); }
/* ResourceTypeKeyword: Resource Usage - Resource Descriptors */
"SMBQuick" { count (0); return (PARSEOP_ACCESSATTRIB_QUICK); }
"SMBSendReceive" { count (0); return (PARSEOP_ACCESSATTRIB_SND_RCV); }
"SMBByte" { count (0); return (PARSEOP_ACCESSATTRIB_BYTE); }
"SMBWord" { count (0); return (PARSEOP_ACCESSATTRIB_WORD); }
"SMBBlock" { count (0); return (PARSEOP_ACCESSATTRIB_BLOCK); }
"SMBProcessCall" { count (0); return (PARSEOP_ACCESSATTRIB_WORD_CALL); }
"SMBBlockProcessCall" { count (0); return (PARSEOP_ACCESSATTRIB_BLOCK_CALL); }
"ResourceConsumer" { count (0); return (PARSEOP_RESOURCETYPE_CONSUMER); }
"ResourceProducer" { count (0); return (PARSEOP_RESOURCETYPE_PRODUCER); }
"MTR" { count (0); return (PARSEOP_MATCHTYPE_MTR); }
"MEQ" { count (0); return (PARSEOP_MATCHTYPE_MEQ); }
"MLE" { count (0); return (PARSEOP_MATCHTYPE_MLE); }
"MLT" { count (0); return (PARSEOP_MATCHTYPE_MLT); }
"MGE" { count (0); return (PARSEOP_MATCHTYPE_MGE); }
"MGT" { count (0); return (PARSEOP_MATCHTYPE_MGT); }
/* SerializeRuleKeyword: Control Method Serialization */
"Compatibility" { count (0); return (PARSEOP_DMATYPE_COMPATIBILITY); }
"TypeA" { count (0); return (PARSEOP_DMATYPE_A); }
"TypeB" { count (0); return (PARSEOP_DMATYPE_B); }
"TypeF" { count (0); return (PARSEOP_DMATYPE_F); }
"Serialized" { count (0); return (PARSEOP_SERIALIZERULE_SERIAL); }
"NotSerialized" { count (0); return (PARSEOP_SERIALIZERULE_NOTSERIAL); }
"BusMaster" { count (0); return (PARSEOP_BUSMASTERTYPE_MASTER); }
"NotBusMaster" { count (0); return (PARSEOP_BUSMASTERTYPE_NOTMASTER); }
/* ShareTypeKeyword: Interrupt Sharing - Resource Descriptors */
"Shared" { count (0); return (PARSEOP_SHARETYPE_SHARED); }
"Exclusive" { count (0); return (PARSEOP_SHARETYPE_EXCLUSIVE); }
"SharedAndWake" { count (0); return (PARSEOP_SHARETYPE_SHAREDWAKE); } /* ACPI 5.0 */
"ExclusiveAndWake" { count (0); return (PARSEOP_SHARETYPE_EXCLUSIVEWAKE); } /* ACPI 5.0 */
/* SlaveModeKeyword: Resource Descriptors (ACPI 5.0) */
"ControllerInitiated" { count (0); return (PARSEOP_SLAVEMODE_CONTROLLERINIT); }
"DeviceInitiated" { count (0); return (PARSEOP_SLAVEMODE_DEVICEINIT); }
/* StopBitsKeyword: Resource Descriptors (ACPI 5.0) */
"StopBitsOne" { count (0); return (PARSEOP_STOPBITS_ONE); }
"StopBitsOnePlusHalf" { count (0); return (PARSEOP_STOPBITS_ONEPLUSHALF); }
"StopBitsTwo" { count (0); return (PARSEOP_STOPBITS_TWO); }
"StopBitsZero" { count (0); return (PARSEOP_STOPBITS_ZERO); }
/* TransferWidthKeyword: DMA Widths - Fixed DMA Resource Descriptor (ACPI 5.0) */
"Width8bit" { count (0); return (PARSEOP_XFERSIZE_8); }
"Width16bit" { count (0); return (PARSEOP_XFERSIZE_16); }
"Width32bit" { count (0); return (PARSEOP_XFERSIZE_32); }
"Width64bit" { count (0); return (PARSEOP_XFERSIZE_64); }
"Width128bit" { count (0); return (PARSEOP_XFERSIZE_128); }
"Width256bit" { count (0); return (PARSEOP_XFERSIZE_256); }
/* TranslationKeyword: Translation Density Types - Resource Descriptors */
"SparseTranslation" { count (0); return (PARSEOP_TRANSLATIONTYPE_SPARSE); }
"DenseTranslation" { count (0); return (PARSEOP_TRANSLATIONTYPE_DENSE); }
/* TypeKeyword: Translation Types - Resource Descriptors */
"TypeTranslation" { count (0); return (PARSEOP_TYPE_TRANSLATION); }
"TypeStatic" { count (0); return (PARSEOP_TYPE_STATIC); }
/* UpdateRuleKeyword: Field Update Rules */
"Preserve" { count (0); return (PARSEOP_UPDATERULE_PRESERVE); }
"WriteAsOnes" { count (0); return (PARSEOP_UPDATERULE_ONES); }
"WriteAsZeros" { count (0); return (PARSEOP_UPDATERULE_ZEROS); }
/* WireModeKeyword: SPI Wire Mode - Resource Descriptors (ACPI 5.0) */
"FourWireMode" { count (0); return (PARSEOP_WIREMODE_FOUR); }
"ThreeWireMode" { count (0); return (PARSEOP_WIREMODE_THREE); }
/* XferTypeKeyword: DMA Transfer Types */
"Transfer8" { count (0); return (PARSEOP_XFERTYPE_8); }
"Transfer8_16" { count (0); return (PARSEOP_XFERTYPE_8_16); }
"Transfer16" { count (0); return (PARSEOP_XFERTYPE_16); }
"ResourceConsumer" { count (0); return (PARSEOP_RESOURCETYPE_CONSUMER); }
"ResourceProducer" { count (0); return (PARSEOP_RESOURCETYPE_PRODUCER); }
"MinFixed" { count (0); return (PARSEOP_MINTYPE_FIXED); }
"MinNotFixed" { count (0); return (PARSEOP_MINTYPE_NOTFIXED); }
"MaxFixed" { count (0); return (PARSEOP_MAXTYPE_FIXED); }
"MaxNotFixed" { count (0); return (PARSEOP_MAXTYPE_NOTFIXED); }
"PosDecode" { count (0); return (PARSEOP_DECODETYPE_POS); }
"SubDecode" { count (0); return (PARSEOP_DECODETYPE_SUB); }
"ISAOnlyRanges" { count (0); return (PARSEOP_RANGETYPE_ISAONLY); }
"NonISAOnlyRanges" { count (0); return (PARSEOP_RANGETYPE_NONISAONLY); }
"EntireRange" { count (0); return (PARSEOP_RANGETYPE_ENTIRE); }
"Cacheable" { count (0); return (PARSEOP_MEMTYPE_CACHEABLE); }
"WriteCombining" { count (0); return (PARSEOP_MEMTYPE_WRITECOMBINING); }
"Prefetchable" { count (0); return (PARSEOP_MEMTYPE_PREFETCHABLE); }
"NonCacheable" { count (0); return (PARSEOP_MEMTYPE_NONCACHEABLE); }
"ReadWrite" { count (0); return (PARSEOP_READWRITETYPE_BOTH); }
"ReadOnly" { count (0); return (PARSEOP_READWRITETYPE_READONLY); }
"Edge" { count (0); return (PARSEOP_INTTYPE_EDGE); }
"Level" { count (0); return (PARSEOP_INTTYPE_LEVEL); }
"ActiveHigh" { count (0); return (PARSEOP_INTLEVEL_ACTIVEHIGH); }
"ActiveLow" { count (0); return (PARSEOP_INTLEVEL_ACTIVELOW); }
"Shared" { count (0); return (PARSEOP_SHARETYPE_SHARED); }
"Exclusive" { count (0); return (PARSEOP_SHARETYPE_EXCLUSIVE); }
"Decode10" { count (0); return (PARSEOP_IODECODETYPE_10); }
"Decode16" { count (0); return (PARSEOP_IODECODETYPE_16); }
"TypeTranslation" { count (0); return (PARSEOP_TYPE_TRANSLATION); }
"TypeStatic" { count (0); return (PARSEOP_TYPE_STATIC); }
"SparseTranslation" { count (0); return (PARSEOP_TRANSLATIONTYPE_SPARSE); }
"DenseTranslation" { count (0); return (PARSEOP_TRANSLATIONTYPE_DENSE); }
"AddressRangeMemory" { count (0); return (PARSEOP_ADDRESSTYPE_MEMORY); }
"AddressRangeReserved" { count (0); return (PARSEOP_ADDRESSTYPE_RESERVED); }
"AddressRangeNVS" { count (0); return (PARSEOP_ADDRESSTYPE_NVS); }
"AddressRangeACPI" { count (0); return (PARSEOP_ADDRESSTYPE_ACPI); }
/* Predefined compiler names */
"__DATE__" { count (0); return (PARSEOP___DATE__); }
"__FILE__" { count (0); return (PARSEOP___FILE__); }
"__LINE__" { count (0); return (PARSEOP___LINE__); }
"__PATH__" { count (0); return (PARSEOP___PATH__); }
"{" { count (0); return('{'); }
"}" { count (0); return('}'); }
@ -402,7 +592,6 @@ NamePathTail [.]{NameSeg}
"(" { count (0); return('('); }
")" { count (0); return(')'); }
{NameSeg} { char *s;
count (0);
s=malloc (ACPI_NAME_SIZE + 1);
@ -478,7 +667,6 @@ AslPopInputFileStack (
void)
{
ASL_FILE_NODE *Fnode;
FILE *InputFile = NULL;
Fnode = InputStack;
@ -497,7 +685,6 @@ AslPopInputFileStack (
/* Update the top-of-stack */
InputStack = Fnode->Next;
InputFile = Fnode->File;
/* Reset global line counter and filename */

File diff suppressed because it is too large Load Diff

View File

@ -56,7 +56,7 @@
#define ASL_INVOCATION_NAME "iasl"
#define ASL_CREATOR_ID "INTL"
#define ASL_COMPLIANCE "Supports ACPI Specification Revision 4.0a"
#define ASL_COMPLIANCE "Supports ACPI Specification Revision 5.0"
/* Configuration constants */
@ -153,5 +153,25 @@
#define POSITIVE 0
/* Helper macros for resource tag creation */
#define RsCreateMultiBitField \
RsCreateResourceField
#define RsCreateBitField(Op, Name, ByteOffset, BitOffset) \
RsCreateResourceField (Op, Name, ByteOffset, BitOffset, 1)
#define RsCreateByteField(Op, Name, ByteOffset) \
RsCreateResourceField (Op, Name, ByteOffset, 0, 8);
#define RsCreateWordField(Op, Name, ByteOffset) \
RsCreateResourceField (Op, Name, ByteOffset, 0, 16);
#define RsCreateDwordField(Op, Name, ByteOffset) \
RsCreateResourceField (Op, Name, ByteOffset, 0, 32);
#define RsCreateQwordField(Op, Name, ByteOffset) \
RsCreateResourceField (Op, Name, ByteOffset, 0, 64);
#endif /* ASLDEFINE.H */

View File

@ -319,10 +319,23 @@ AePrintException (
if (Enode->LineNumber)
{
/* Main message: try to use string from AslMessages first */
if (!MainMessage)
{
MainMessage = "";
}
MsgLength = strlen (MainMessage);
if (MsgLength == 0)
{
/* Use the secondary/extra message as main message */
MainMessage = Enode->Message;
if (!MainMessage)
{
MainMessage = "";
}
MsgLength = strlen (MainMessage);
ExtraMessage = NULL;
@ -620,13 +633,13 @@ AslCoreSubsystemError (
int
AslCompilererror (
char *CompilerMessage)
const char *CompilerMessage)
{
AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
CompilerMessage);
Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
ACPI_CAST_PTR (char, CompilerMessage));
return 0;
}

View File

@ -174,14 +174,18 @@ FlGetFileSize (
{
FILE *fp;
UINT32 FileSize;
long Offset;
fp = Gbl_Files[FileId].Handle;
Offset = ftell (fp);
fseek (fp, 0, SEEK_END);
FileSize = (UINT32) ftell (fp);
fseek (fp, 0, SEEK_SET);
/* Restore file pointer */
fseek (fp, Offset, SEEK_SET);
return (FileSize);
}

View File

@ -128,6 +128,7 @@ ASL_EXTERN UINT8 ASL_INIT_GLOBAL (Gbl_WarningLevel, ASL_WARNI
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_UseOriginalCompilerId, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_VerboseTemplates, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DoTemplates, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_CompileGeneric, FALSE);
#define HEX_OUTPUT_NONE 0

View File

@ -850,9 +850,9 @@ LsFinishSourceListing (
FlPrintFile (FileId, "\n\nSummary of errors and warnings\n\n");
AePrintErrorLog (FileId);
FlPrintFile (FileId, "\n\n");
FlPrintFile (FileId, "\n");
UtDisplaySummary (FileId);
FlPrintFile (FileId, "\n\n");
FlPrintFile (FileId, "\n");
}
}
@ -1309,6 +1309,7 @@ LsDoHexOutputC (
/* Get AML size, seek back to start */
AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
FlPrintFile (ASL_FILE_HEX_OUTPUT, " * C source code output\n");
FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n",
@ -1365,7 +1366,6 @@ LsDoHexOutputC (
}
FlPrintFile (ASL_FILE_HEX_OUTPUT, "};\n");
FlCloseFile (ASL_FILE_HEX_OUTPUT);
}
@ -1397,6 +1397,7 @@ LsDoHexOutputAsl (
/* Get AML size, seek back to start */
AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
FlPrintFile (ASL_FILE_HEX_OUTPUT, " * ASL source code output\n");
FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n",
@ -1453,7 +1454,6 @@ LsDoHexOutputAsl (
}
FlPrintFile (ASL_FILE_HEX_OUTPUT, " })\n");
FlCloseFile (ASL_FILE_HEX_OUTPUT);
}
@ -1485,6 +1485,7 @@ LsDoHexOutputAsm (
/* Get AML size, seek back to start */
AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT);
FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
FlPrintFile (ASL_FILE_HEX_OUTPUT, "; Assembly code source output\n");
FlPrintFile (ASL_FILE_HEX_OUTPUT, "; AML code block contains 0x%X bytes\n;\n",
@ -1536,7 +1537,6 @@ LsDoHexOutputAsm (
}
FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
FlCloseFile (ASL_FILE_HEX_OUTPUT);
}

View File

@ -189,7 +189,7 @@ LdLoadFieldElements (
{
case AML_INT_RESERVEDFIELD_OP:
case AML_INT_ACCESSFIELD_OP:
case AML_INT_CONNECTION_OP:
break;
default:
@ -224,8 +224,10 @@ LdLoadFieldElements (
}
break;
}
Child = Child->Asl.Next;
}
return (AE_OK);
}
@ -290,7 +292,6 @@ LdLoadResourceElements (
InitializerOp = ASL_GET_CHILD_NODE (Op);
while (InitializerOp)
{
if (InitializerOp->Asl.ExternalName)
{
Status = AcpiNsLookup (WalkState->ScopeInfo,
@ -305,20 +306,15 @@ LdLoadResourceElements (
}
/*
* Store the field offset in the namespace node so it
* can be used when the field is referenced
* Store the field offset and length in the namespace node
* so it can be used when the field is referenced
*/
Node->Value = (UINT32) InitializerOp->Asl.Value.Integer;
Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
InitializerOp->Asl.Node = Node;
Node->Op = InitializerOp;
/* Pass thru the field type (Bitfield or Bytefield) */
if (InitializerOp->Asl.CompileFlags & NODE_IS_BIT_OFFSET)
{
Node->Flags |= ANOBJ_IS_BIT_OFFSET;
}
}
InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
}

Some files were not shown because too many files have changed in this diff Show More