MFC
This commit is contained in:
commit
b2701fb716
@ -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}
|
||||
|
4
UPDATING
4
UPDATING
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
462
cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
Normal file
462
cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
Normal 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));
|
||||
}
|
@ -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
@ -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,
|
||||
|
@ -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 \
|
||||
|
@ -27,7 +27,7 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
# PROVIDE: kld
|
||||
# REQUIRE: FILESYSTEMS
|
||||
# REQUIRE: kldxref
|
||||
# KEYWORD: nojail
|
||||
|
||||
. /etc/rc.subr
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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 ,
|
||||
|
@ -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 ,
|
||||
|
@ -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
|
||||
|
@ -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 ,
|
||||
|
@ -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 ,
|
||||
|
@ -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
|
||||
|
@ -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 .
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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 -
|
||||
|
@ -2,6 +2,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
INCS= readline.h history.h
|
||||
INCSLINKS= readline.h ${INCSDIR}/tilde.h
|
||||
|
||||
INCSDIR= ${INCLUDEDIR}/edit/readline
|
||||
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -123,6 +123,7 @@ MAN= aac.4 \
|
||||
fdc.4 \
|
||||
fdt.4 \
|
||||
fdtbus.4 \
|
||||
ffclock.4 \
|
||||
firewire.4 \
|
||||
fpa.4 \
|
||||
fwe.4 \
|
||||
|
@ -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
|
||||
|
@ -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
128
share/man/man4/ffclock.4
Normal 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 .
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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>__)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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).
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
/*
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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}" ;;
|
||||
|
@ -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"
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 !*/
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user