mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Compare commits
9 Commits
ef83e07db5
...
52bad4f23d
| Author | SHA1 | Date | |
|---|---|---|---|
| 52bad4f23d | |||
| 2b8b89c6b3 | |||
| 90abfdf8ee | |||
| 847d03060f | |||
| 9e3619c535 | |||
| 421750672b | |||
| 275c756730 | |||
| 0bebcbcf5e | |||
| 7b215d93bc |
@@ -1,10 +1,10 @@
|
||||
Meta: 1
|
||||
Name: zfs
|
||||
Branch: 1.0
|
||||
Version: 2.1.3
|
||||
Version: 2.1.4
|
||||
Release: 1
|
||||
Release-Tags: relext
|
||||
License: CDDL
|
||||
Author: OpenZFS
|
||||
Linux-Maximum: 5.16
|
||||
Linux-Maximum: 5.17
|
||||
Linux-Minimum: 3.10
|
||||
|
||||
+163
-16
@@ -183,14 +183,14 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
||||
nvlist_t *nvroot, *newvd;
|
||||
pendingdev_t *device;
|
||||
uint64_t wholedisk = 0ULL;
|
||||
uint64_t offline = 0ULL;
|
||||
uint64_t offline = 0ULL, faulted = 0ULL;
|
||||
uint64_t guid = 0ULL;
|
||||
char *physpath = NULL, *new_devid = NULL, *enc_sysfs_path = NULL;
|
||||
char rawpath[PATH_MAX], fullpath[PATH_MAX];
|
||||
char devpath[PATH_MAX];
|
||||
int ret;
|
||||
boolean_t is_dm = B_FALSE;
|
||||
boolean_t is_sd = B_FALSE;
|
||||
boolean_t is_mpath_wholedisk = B_FALSE;
|
||||
uint_t c;
|
||||
vdev_stat_t *vs;
|
||||
|
||||
@@ -211,15 +211,73 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
||||
&enc_sysfs_path);
|
||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
|
||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_OFFLINE, &offline);
|
||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_FAULTED, &faulted);
|
||||
|
||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_GUID, &guid);
|
||||
|
||||
if (offline)
|
||||
return; /* don't intervene if it was taken offline */
|
||||
/*
|
||||
* Special case:
|
||||
*
|
||||
* We've seen times where a disk won't have a ZPOOL_CONFIG_PHYS_PATH
|
||||
* entry in their config. For example, on this force-faulted disk:
|
||||
*
|
||||
* children[0]:
|
||||
* type: 'disk'
|
||||
* id: 0
|
||||
* guid: 14309659774640089719
|
||||
* path: '/dev/disk/by-vdev/L28'
|
||||
* whole_disk: 0
|
||||
* DTL: 654
|
||||
* create_txg: 4
|
||||
* com.delphix:vdev_zap_leaf: 1161
|
||||
* faulted: 1
|
||||
* aux_state: 'external'
|
||||
* children[1]:
|
||||
* type: 'disk'
|
||||
* id: 1
|
||||
* guid: 16002508084177980912
|
||||
* path: '/dev/disk/by-vdev/L29'
|
||||
* devid: 'dm-uuid-mpath-35000c500a61d68a3'
|
||||
* phys_path: 'L29'
|
||||
* vdev_enc_sysfs_path: '/sys/class/enclosure/0:0:1:0/SLOT 30 32'
|
||||
* whole_disk: 0
|
||||
* DTL: 1028
|
||||
* create_txg: 4
|
||||
* com.delphix:vdev_zap_leaf: 131
|
||||
*
|
||||
* If the disk's path is a /dev/disk/by-vdev/ path, then we can infer
|
||||
* the ZPOOL_CONFIG_PHYS_PATH from the by-vdev disk name.
|
||||
*/
|
||||
if (physpath == NULL && path != NULL) {
|
||||
/* If path begins with "/dev/disk/by-vdev/" ... */
|
||||
if (strncmp(path, DEV_BYVDEV_PATH,
|
||||
strlen(DEV_BYVDEV_PATH)) == 0) {
|
||||
/* Set physpath to the char after "/dev/disk/by-vdev" */
|
||||
physpath = &path[strlen(DEV_BYVDEV_PATH)];
|
||||
}
|
||||
}
|
||||
|
||||
is_dm = zfs_dev_is_dm(path);
|
||||
/*
|
||||
* We don't want to autoreplace offlined disks. However, we do want to
|
||||
* replace force-faulted disks (`zpool offline -f`). Force-faulted
|
||||
* disks have both offline=1 and faulted=1 in the nvlist.
|
||||
*/
|
||||
if (offline && !faulted) {
|
||||
zed_log_msg(LOG_INFO, "%s: %s is offline, skip autoreplace",
|
||||
__func__, path);
|
||||
return;
|
||||
}
|
||||
|
||||
is_mpath_wholedisk = is_mpath_whole_disk(path);
|
||||
zed_log_msg(LOG_INFO, "zfs_process_add: pool '%s' vdev '%s', phys '%s'"
|
||||
" wholedisk %d, %s dm (guid %llu)", zpool_get_name(zhp), path,
|
||||
physpath ? physpath : "NULL", wholedisk, is_dm ? "is" : "not",
|
||||
" %s blank disk, %s mpath blank disk, %s labeled, enc sysfs '%s', "
|
||||
"(guid %llu)",
|
||||
zpool_get_name(zhp), path,
|
||||
physpath ? physpath : "NULL",
|
||||
wholedisk ? "is" : "not",
|
||||
is_mpath_wholedisk? "is" : "not",
|
||||
labeled ? "is" : "not",
|
||||
enc_sysfs_path,
|
||||
(long long unsigned int)guid);
|
||||
|
||||
/*
|
||||
@@ -253,8 +311,9 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
||||
ZFS_ONLINE_CHECKREMOVE | ZFS_ONLINE_UNSPARE, &newstate) == 0 &&
|
||||
(newstate == VDEV_STATE_HEALTHY ||
|
||||
newstate == VDEV_STATE_DEGRADED)) {
|
||||
zed_log_msg(LOG_INFO, " zpool_vdev_online: vdev %s is %s",
|
||||
fullpath, (newstate == VDEV_STATE_HEALTHY) ?
|
||||
zed_log_msg(LOG_INFO,
|
||||
" zpool_vdev_online: vdev '%s' ('%s') is "
|
||||
"%s", fullpath, physpath, (newstate == VDEV_STATE_HEALTHY) ?
|
||||
"HEALTHY" : "DEGRADED");
|
||||
return;
|
||||
}
|
||||
@@ -271,11 +330,12 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
||||
* vdev online to trigger a FMA fault by posting an ereport.
|
||||
*/
|
||||
if (!zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOREPLACE, NULL) ||
|
||||
!(wholedisk || is_dm) || (physpath == NULL)) {
|
||||
!(wholedisk || is_mpath_wholedisk) || (physpath == NULL)) {
|
||||
(void) zpool_vdev_online(zhp, fullpath, ZFS_ONLINE_FORCEFAULT,
|
||||
&newstate);
|
||||
zed_log_msg(LOG_INFO, "Pool's autoreplace is not enabled or "
|
||||
"not a whole disk for '%s'", fullpath);
|
||||
"not a blank disk for '%s' ('%s')", fullpath,
|
||||
physpath);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -287,7 +347,7 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
||||
(void) snprintf(rawpath, sizeof (rawpath), "%s%s",
|
||||
is_sd ? DEV_BYVDEV_PATH : DEV_BYPATH_PATH, physpath);
|
||||
|
||||
if (realpath(rawpath, devpath) == NULL && !is_dm) {
|
||||
if (realpath(rawpath, devpath) == NULL && !is_mpath_wholedisk) {
|
||||
zed_log_msg(LOG_INFO, " realpath: %s failed (%s)",
|
||||
rawpath, strerror(errno));
|
||||
|
||||
@@ -303,12 +363,14 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
||||
if ((vs->vs_state != VDEV_STATE_DEGRADED) &&
|
||||
(vs->vs_state != VDEV_STATE_FAULTED) &&
|
||||
(vs->vs_state != VDEV_STATE_CANT_OPEN)) {
|
||||
zed_log_msg(LOG_INFO, " not autoreplacing since disk isn't in "
|
||||
"a bad state (currently %d)", vs->vs_state);
|
||||
return;
|
||||
}
|
||||
|
||||
nvlist_lookup_string(vdev, "new_devid", &new_devid);
|
||||
|
||||
if (is_dm) {
|
||||
if (is_mpath_wholedisk) {
|
||||
/* Don't label device mapper or multipath disks. */
|
||||
} else if (!labeled) {
|
||||
/*
|
||||
@@ -522,8 +584,11 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
||||
* the dp->dd_compare value.
|
||||
*/
|
||||
if (nvlist_lookup_string(nvl, dp->dd_prop, &path) != 0 ||
|
||||
strcmp(dp->dd_compare, path) != 0)
|
||||
strcmp(dp->dd_compare, path) != 0) {
|
||||
zed_log_msg(LOG_INFO, " %s: no match (%s != vdev %s)",
|
||||
__func__, dp->dd_compare, path);
|
||||
return;
|
||||
}
|
||||
|
||||
zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched %s on %s",
|
||||
dp->dd_prop, path);
|
||||
@@ -571,6 +636,8 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data)
|
||||
ZPOOL_CONFIG_VDEV_TREE, &nvl);
|
||||
zfs_iter_vdev(zhp, nvl, data);
|
||||
}
|
||||
} else {
|
||||
zed_log_msg(LOG_INFO, "%s: no config\n", __func__);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -619,6 +686,72 @@ devphys_iter(const char *physical, const char *devid, zfs_process_func_t func,
|
||||
return (data.dd_found);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a device identifier, find any vdevs with a matching by-vdev
|
||||
* path. Normally we shouldn't need this as the comparison would be
|
||||
* made earlier in the devphys_iter(). For example, if we were replacing
|
||||
* /dev/disk/by-vdev/L28, normally devphys_iter() would match the
|
||||
* ZPOOL_CONFIG_PHYS_PATH of "L28" from the old disk config to "L28"
|
||||
* of the new disk config. However, we've seen cases where
|
||||
* ZPOOL_CONFIG_PHYS_PATH was not in the config for the old disk. Here's
|
||||
* an example of a real 2-disk mirror pool where one disk was force
|
||||
* faulted:
|
||||
*
|
||||
* com.delphix:vdev_zap_top: 129
|
||||
* children[0]:
|
||||
* type: 'disk'
|
||||
* id: 0
|
||||
* guid: 14309659774640089719
|
||||
* path: '/dev/disk/by-vdev/L28'
|
||||
* whole_disk: 0
|
||||
* DTL: 654
|
||||
* create_txg: 4
|
||||
* com.delphix:vdev_zap_leaf: 1161
|
||||
* faulted: 1
|
||||
* aux_state: 'external'
|
||||
* children[1]:
|
||||
* type: 'disk'
|
||||
* id: 1
|
||||
* guid: 16002508084177980912
|
||||
* path: '/dev/disk/by-vdev/L29'
|
||||
* devid: 'dm-uuid-mpath-35000c500a61d68a3'
|
||||
* phys_path: 'L29'
|
||||
* vdev_enc_sysfs_path: '/sys/class/enclosure/0:0:1:0/SLOT 30 32'
|
||||
* whole_disk: 0
|
||||
* DTL: 1028
|
||||
* create_txg: 4
|
||||
* com.delphix:vdev_zap_leaf: 131
|
||||
*
|
||||
* So in the case above, the only thing we could compare is the path.
|
||||
*
|
||||
* We can do this because we assume by-vdev paths are authoritative as physical
|
||||
* paths. We could not assume this for normal paths like /dev/sda since the
|
||||
* physical location /dev/sda points to could change over time.
|
||||
*/
|
||||
static boolean_t
|
||||
by_vdev_path_iter(const char *by_vdev_path, const char *devid,
|
||||
zfs_process_func_t func, boolean_t is_slice)
|
||||
{
|
||||
dev_data_t data = { 0 };
|
||||
|
||||
data.dd_compare = by_vdev_path;
|
||||
data.dd_func = func;
|
||||
data.dd_prop = ZPOOL_CONFIG_PATH;
|
||||
data.dd_found = B_FALSE;
|
||||
data.dd_islabeled = is_slice;
|
||||
data.dd_new_devid = devid;
|
||||
|
||||
if (strncmp(by_vdev_path, DEV_BYVDEV_PATH,
|
||||
strlen(DEV_BYVDEV_PATH)) != 0) {
|
||||
/* by_vdev_path doesn't start with "/dev/disk/by-vdev/" */
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
(void) zpool_iter(g_zfshdl, zfs_iter_pool, &data);
|
||||
|
||||
return (data.dd_found);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a device identifier, find any vdevs with a matching devid.
|
||||
* On Linux we can match devid directly which is always a whole disk.
|
||||
@@ -683,15 +816,17 @@ guid_iter(uint64_t pool_guid, uint64_t vdev_guid, const char *devid,
|
||||
static int
|
||||
zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
|
||||
{
|
||||
char *devpath = NULL, *devid;
|
||||
char *devpath = NULL, *devid = NULL;
|
||||
uint64_t pool_guid = 0, vdev_guid = 0;
|
||||
boolean_t is_slice;
|
||||
|
||||
/*
|
||||
* Expecting a devid string and an optional physical location and guid
|
||||
*/
|
||||
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid) != 0)
|
||||
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid) != 0) {
|
||||
zed_log_msg(LOG_INFO, "%s: no dev identifier\n", __func__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
(void) nvlist_lookup_string(nvl, DEV_PHYS_PATH, &devpath);
|
||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &pool_guid);
|
||||
@@ -707,6 +842,8 @@ zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
|
||||
* 1. ZPOOL_CONFIG_DEVID (identifies the unique disk)
|
||||
* 2. ZPOOL_CONFIG_PHYS_PATH (identifies disk physical location).
|
||||
* 3. ZPOOL_CONFIG_GUID (identifies unique vdev).
|
||||
* 4. ZPOOL_CONFIG_PATH for /dev/disk/by-vdev devices only (since
|
||||
* by-vdev paths represent physical paths).
|
||||
*/
|
||||
if (devid_iter(devid, zfs_process_add, is_slice))
|
||||
return (0);
|
||||
@@ -717,6 +854,16 @@ zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
|
||||
(void) guid_iter(pool_guid, vdev_guid, devid, zfs_process_add,
|
||||
is_slice);
|
||||
|
||||
if (devpath != NULL) {
|
||||
/* Can we match a /dev/disk/by-vdev/ path? */
|
||||
char by_vdev_path[MAXPATHLEN];
|
||||
snprintf(by_vdev_path, sizeof (by_vdev_path),
|
||||
"/dev/disk/by-vdev/%s", devpath);
|
||||
if (by_vdev_path_iter(by_vdev_path, devid, zfs_process_add,
|
||||
is_slice))
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -215,6 +215,11 @@ zed_udev_monitor(void *arg)
|
||||
if (type != NULL && type[0] != '\0' &&
|
||||
strcmp(type, "disk") == 0 &&
|
||||
part != NULL && part[0] != '\0') {
|
||||
zed_log_msg(LOG_INFO,
|
||||
"%s: skip %s since it has a %s partition already",
|
||||
__func__,
|
||||
udev_device_get_property_value(dev, "DEVNAME"),
|
||||
part);
|
||||
/* skip and wait for partition event */
|
||||
udev_device_unref(dev);
|
||||
continue;
|
||||
@@ -229,6 +234,11 @@ zed_udev_monitor(void *arg)
|
||||
sectors = udev_device_get_sysattr_value(dev, "size");
|
||||
if (sectors != NULL &&
|
||||
strtoull(sectors, NULL, 10) < MINIMUM_SECTORS) {
|
||||
zed_log_msg(LOG_INFO,
|
||||
"%s: %s sectors %s < %llu (minimum)",
|
||||
__func__,
|
||||
udev_device_get_property_value(dev, "DEVNAME"),
|
||||
sectors, MINIMUM_SECTORS);
|
||||
udev_device_unref(dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ KERNEL_H = \
|
||||
inttypes.h \
|
||||
isa_defs.h \
|
||||
kmem_cache.h \
|
||||
kidmap.h \
|
||||
kmem.h \
|
||||
kstat.h \
|
||||
list_impl.h \
|
||||
|
||||
@@ -48,138 +48,20 @@ extern "C" {
|
||||
typedef struct ucred cred_t;
|
||||
|
||||
#define CRED() curthread->td_ucred
|
||||
|
||||
/*
|
||||
* kcred is used when you need all privileges.
|
||||
*/
|
||||
#define kcred (thread0.td_ucred)
|
||||
|
||||
#define KUID_TO_SUID(x) (x)
|
||||
#define KGID_TO_SGID(x) (x)
|
||||
#define crgetuid(cred) ((cred)->cr_uid)
|
||||
#define crgetruid(cred) ((cred)->cr_ruid)
|
||||
#define crgetgid(cred) ((cred)->cr_gid)
|
||||
#define crgetgroups(cred) ((cred)->cr_groups)
|
||||
#define crgetngroups(cred) ((cred)->cr_ngroups)
|
||||
#define crgetsid(cred, i) (NULL)
|
||||
|
||||
struct proc; /* cred.h is included in proc.h */
|
||||
struct prcred;
|
||||
struct ksid;
|
||||
struct ksidlist;
|
||||
struct credklpd;
|
||||
struct credgrp;
|
||||
|
||||
struct auditinfo_addr; /* cred.h is included in audit.h */
|
||||
|
||||
extern int ngroups_max;
|
||||
/*
|
||||
* kcred is used when you need all privileges.
|
||||
*/
|
||||
|
||||
extern void cred_init(void);
|
||||
extern void crfree(cred_t *);
|
||||
extern cred_t *cralloc(void); /* all but ref uninitialized */
|
||||
extern cred_t *cralloc_ksid(void); /* cralloc() + ksid alloc'ed */
|
||||
extern cred_t *crget(void); /* initialized */
|
||||
extern void crcopy_to(cred_t *, cred_t *);
|
||||
extern cred_t *crdup(cred_t *);
|
||||
extern void crdup_to(cred_t *, cred_t *);
|
||||
extern cred_t *crgetcred(void);
|
||||
extern void crset(struct proc *, cred_t *);
|
||||
extern void crset_zone_privall(cred_t *);
|
||||
extern int supgroupmember(gid_t, const cred_t *);
|
||||
extern int hasprocperm(const cred_t *, const cred_t *);
|
||||
extern int prochasprocperm(struct proc *, struct proc *, const cred_t *);
|
||||
extern int crcmp(const cred_t *, const cred_t *);
|
||||
extern cred_t *zone_kcred(void);
|
||||
|
||||
extern gid_t crgetrgid(const cred_t *);
|
||||
extern gid_t crgetsgid(const cred_t *);
|
||||
|
||||
#define crgetzoneid(cr) ((cr)->cr_prison->pr_id)
|
||||
extern projid_t crgetprojid(const cred_t *);
|
||||
|
||||
extern cred_t *crgetmapped(const cred_t *);
|
||||
|
||||
|
||||
extern const struct auditinfo_addr *crgetauinfo(const cred_t *);
|
||||
extern struct auditinfo_addr *crgetauinfo_modifiable(cred_t *);
|
||||
|
||||
extern uint_t crgetref(const cred_t *);
|
||||
|
||||
extern const gid_t *crgetggroups(const struct credgrp *);
|
||||
|
||||
|
||||
/*
|
||||
* Sets real, effective and/or saved uid/gid;
|
||||
* -1 argument accepted as "no change".
|
||||
*/
|
||||
extern int crsetresuid(cred_t *, uid_t, uid_t, uid_t);
|
||||
extern int crsetresgid(cred_t *, gid_t, gid_t, gid_t);
|
||||
|
||||
/*
|
||||
* Sets real, effective and saved uids/gids all to the same
|
||||
* values. Both values must be non-negative and <= MAXUID
|
||||
*/
|
||||
extern int crsetugid(cred_t *, uid_t, gid_t);
|
||||
|
||||
/*
|
||||
* Functions to handle the supplemental group list.
|
||||
*/
|
||||
extern struct credgrp *crgrpcopyin(int, gid_t *);
|
||||
extern void crgrprele(struct credgrp *);
|
||||
extern void crsetcredgrp(cred_t *, struct credgrp *);
|
||||
|
||||
/*
|
||||
* Private interface for setting zone association of credential.
|
||||
*/
|
||||
struct zone;
|
||||
extern void crsetzone(cred_t *, struct zone *);
|
||||
extern struct zone *crgetzone(const cred_t *);
|
||||
|
||||
/*
|
||||
* Private interface for setting project id in credential.
|
||||
*/
|
||||
extern void crsetprojid(cred_t *, projid_t);
|
||||
|
||||
/*
|
||||
* Private interface for nfs.
|
||||
*/
|
||||
extern cred_t *crnetadjust(cred_t *);
|
||||
|
||||
/*
|
||||
* Private interface for procfs.
|
||||
*/
|
||||
extern void cred2prcred(const cred_t *, struct prcred *);
|
||||
|
||||
/*
|
||||
* Private interfaces for Rampart Trusted Solaris.
|
||||
*/
|
||||
struct ts_label_s;
|
||||
extern struct ts_label_s *crgetlabel(const cred_t *);
|
||||
extern boolean_t crisremote(const cred_t *);
|
||||
|
||||
/*
|
||||
* Private interfaces for ephemeral uids.
|
||||
*/
|
||||
#define VALID_UID(id, zn) \
|
||||
((id) <= MAXUID || valid_ephemeral_uid((zn), (id)))
|
||||
|
||||
#define VALID_GID(id, zn) \
|
||||
((id) <= MAXUID || valid_ephemeral_gid((zn), (id)))
|
||||
|
||||
extern boolean_t valid_ephemeral_uid(struct zone *, uid_t);
|
||||
extern boolean_t valid_ephemeral_gid(struct zone *, gid_t);
|
||||
|
||||
extern int eph_uid_alloc(struct zone *, int, uid_t *, int);
|
||||
extern int eph_gid_alloc(struct zone *, int, gid_t *, int);
|
||||
|
||||
extern void crsetsid(cred_t *, struct ksid *, int);
|
||||
extern void crsetsidlist(cred_t *, struct ksidlist *);
|
||||
|
||||
extern struct ksidlist *crgetsidlist(const cred_t *);
|
||||
|
||||
extern int crsetpriv(cred_t *, ...);
|
||||
|
||||
extern struct credklpd *crgetcrklpd(const cred_t *);
|
||||
extern void crsetcrklpd(cred_t *, struct credklpd *);
|
||||
#define crgetuid(cr) ((cr)->cr_uid)
|
||||
#define crgetruid(cr) ((cr)->cr_ruid)
|
||||
#define crgetgid(cr) ((cr)->cr_gid)
|
||||
#define crgetgroups(cr) ((cr)->cr_groups)
|
||||
#define crgetngroups(cr) ((cr)->cr_ngroups)
|
||||
#define crgetzoneid(cr) ((cr)->cr_prison->pr_id)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _OPENSOLARIS_SYS_KIDMAP_H_
|
||||
#define _OPENSOLARIS_SYS_KIDMAP_H_
|
||||
|
||||
#include <sys/idmap.h>
|
||||
|
||||
typedef int32_t idmap_stat;
|
||||
typedef void idmap_get_handle_t;
|
||||
|
||||
#define kidmap_get_create() (NULL)
|
||||
#define kidmap_get_destroy(hdl) do { } while (0)
|
||||
#define kidmap_get_mappings(hdl) (NULL)
|
||||
|
||||
#endif /* _OPENSOLARIS_SYS_KIDMAP_H_ */
|
||||
@@ -29,7 +29,6 @@
|
||||
#ifndef _OPENSOLARIS_SYS_SID_H_
|
||||
#define _OPENSOLARIS_SYS_SID_H_
|
||||
#include <sys/idmap.h>
|
||||
#include <sys/kidmap.h>
|
||||
|
||||
typedef struct ksiddomain {
|
||||
char *kd_name; /* Domain part of SID */
|
||||
@@ -59,28 +58,4 @@ ksiddomain_rele(ksiddomain_t *kd)
|
||||
kmem_free(kd, sizeof (*kd));
|
||||
}
|
||||
|
||||
static __inline uint_t
|
||||
ksid_getid(ksid_t *ks)
|
||||
{
|
||||
|
||||
panic("%s has been unexpectedly called", __func__);
|
||||
}
|
||||
|
||||
static __inline const char *
|
||||
ksid_getdomain(ksid_t *ks)
|
||||
{
|
||||
|
||||
panic("%s has been unexpectedly called", __func__);
|
||||
}
|
||||
|
||||
static __inline uint_t
|
||||
ksid_getrid(ksid_t *ks)
|
||||
{
|
||||
|
||||
panic("%s has been unexpectedly called", __func__);
|
||||
}
|
||||
|
||||
#define kidmap_getsidbyuid(zone, uid, sid_prefix, rid) (1)
|
||||
#define kidmap_getsidbygid(zone, gid, sid_prefix, rid) (1)
|
||||
|
||||
#endif /* _OPENSOLARIS_SYS_SID_H_ */
|
||||
|
||||
@@ -420,9 +420,9 @@ kfpu_end(void)
|
||||
if (static_cpu_has(X86_FEATURE_XSAVE)) {
|
||||
kfpu_do_xrstor("xrstor", &state->xsave, ~0);
|
||||
} else if (static_cpu_has(X86_FEATURE_FXSR)) {
|
||||
kfpu_save_fxsr(&state->fxsave);
|
||||
kfpu_restore_fxsr(&state->fxsave);
|
||||
} else {
|
||||
kfpu_save_fsave(&state->fsave);
|
||||
kfpu_restore_fsave(&state->fsave);
|
||||
}
|
||||
out:
|
||||
local_irq_enable();
|
||||
|
||||
@@ -49,12 +49,7 @@ extern void crhold(cred_t *cr);
|
||||
extern void crfree(cred_t *cr);
|
||||
extern uid_t crgetuid(const cred_t *cr);
|
||||
extern uid_t crgetruid(const cred_t *cr);
|
||||
extern uid_t crgetsuid(const cred_t *cr);
|
||||
extern uid_t crgetfsuid(const cred_t *cr);
|
||||
extern gid_t crgetgid(const cred_t *cr);
|
||||
extern gid_t crgetrgid(const cred_t *cr);
|
||||
extern gid_t crgetsgid(const cred_t *cr);
|
||||
extern gid_t crgetfsgid(const cred_t *cr);
|
||||
extern int crgetngroups(const cred_t *cr);
|
||||
extern gid_t *crgetgroups(const cred_t *cr);
|
||||
extern int groupmember(gid_t gid, const cred_t *cr);
|
||||
|
||||
@@ -606,7 +606,6 @@ get_key_material_https(libzfs_handle_t *hdl, const char *uri,
|
||||
kfdok:
|
||||
if ((key = fdopen(kfd, "r+")) == NULL) {
|
||||
ret = errno;
|
||||
free(path);
|
||||
(void) close(kfd);
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"Couldn't reopen temporary file: %s"), strerror(ret));
|
||||
|
||||
@@ -527,7 +527,7 @@ zfs_dev_is_dm(const char *dev_name)
|
||||
boolean_t
|
||||
zfs_dev_is_whole_disk(const char *dev_name)
|
||||
{
|
||||
struct dk_gpt *label;
|
||||
struct dk_gpt *label = NULL;
|
||||
int fd;
|
||||
|
||||
if ((fd = open(dev_name, O_RDONLY | O_DIRECT | O_CLOEXEC)) < 0)
|
||||
@@ -613,22 +613,24 @@ zfs_get_underlying_path(const char *dev_name)
|
||||
/*
|
||||
* A disk is considered a multipath whole disk when:
|
||||
* DEVNAME key value has "dm-"
|
||||
* DM_NAME key value has "mpath" prefix
|
||||
* DM_UUID key exists
|
||||
* DM_UUID key exists and starts with 'mpath-'
|
||||
* ID_PART_TABLE_TYPE key does not exist or is not gpt
|
||||
* ID_FS_LABEL key does not exist (disk isn't labeled)
|
||||
*/
|
||||
static boolean_t
|
||||
udev_mpath_whole_disk(struct udev_device *dev)
|
||||
is_mpath_udev_sane(struct udev_device *dev)
|
||||
{
|
||||
const char *devname, *type, *uuid;
|
||||
const char *devname, *type, *uuid, *label;
|
||||
|
||||
devname = udev_device_get_property_value(dev, "DEVNAME");
|
||||
type = udev_device_get_property_value(dev, "ID_PART_TABLE_TYPE");
|
||||
uuid = udev_device_get_property_value(dev, "DM_UUID");
|
||||
label = udev_device_get_property_value(dev, "ID_FS_LABEL");
|
||||
|
||||
if ((devname != NULL && strncmp(devname, "/dev/dm-", 8) == 0) &&
|
||||
((type == NULL) || (strcmp(type, "gpt") != 0)) &&
|
||||
(uuid != NULL)) {
|
||||
((uuid != NULL) && (strncmp(uuid, "mpath-", 6) == 0)) &&
|
||||
(label == NULL)) {
|
||||
return (B_TRUE);
|
||||
}
|
||||
|
||||
@@ -636,7 +638,11 @@ udev_mpath_whole_disk(struct udev_device *dev)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a disk is effectively a multipath whole disk
|
||||
* Check if a disk is a multipath "blank" disk:
|
||||
*
|
||||
* 1. The disk has udev values that suggest it's a multipath disk
|
||||
* 2. The disk is not currently labeled with a filesystem of any type
|
||||
* 3. There are no partitions on the disk
|
||||
*/
|
||||
boolean_t
|
||||
is_mpath_whole_disk(const char *path)
|
||||
@@ -645,7 +651,6 @@ is_mpath_whole_disk(const char *path)
|
||||
struct udev_device *dev = NULL;
|
||||
char nodepath[MAXPATHLEN];
|
||||
char *sysname;
|
||||
boolean_t wholedisk = B_FALSE;
|
||||
|
||||
if (realpath(path, nodepath) == NULL)
|
||||
return (B_FALSE);
|
||||
@@ -660,10 +665,11 @@ is_mpath_whole_disk(const char *path)
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
wholedisk = udev_mpath_whole_disk(dev);
|
||||
|
||||
/* Sanity check some udev values */
|
||||
boolean_t is_sane = is_mpath_udev_sane(dev);
|
||||
udev_device_unref(dev);
|
||||
return (wholedisk);
|
||||
|
||||
return (is_sane);
|
||||
}
|
||||
|
||||
#else /* HAVE_LIBUDEV */
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ CFLAGS+= -include ${INCDIR}/os/freebsd/spl/sys/ccompile.h
|
||||
|
||||
CFLAGS+= -D__KERNEL__ -DFREEBSD_NAMECACHE -DBUILDING_ZFS -D__BSD_VISIBLE=1 \
|
||||
-DHAVE_UIO_ZEROCOPY -DWITHOUT_NETDUMP -D__KERNEL -D_SYS_CONDVAR_H_ \
|
||||
-D_SYS_VMEM_H_ -DKDTRACE_HOOKS -DSMP -DHAVE_KSID -DCOMPAT_FREEBSD11
|
||||
-D_SYS_VMEM_H_ -DKDTRACE_HOOKS -DSMP -DCOMPAT_FREEBSD11
|
||||
|
||||
.if ${MACHINE_ARCH} == "amd64"
|
||||
CFLAGS+= -DHAVE_AVX2 -DHAVE_AVX -D__x86_64 -DHAVE_SSE2 -DHAVE_AVX512F -DHAVE_SSSE3
|
||||
|
||||
@@ -250,7 +250,17 @@ sysevent_worker(void *arg __unused)
|
||||
nvlist_free(event);
|
||||
}
|
||||
}
|
||||
zfs_zevent_destroy(ze);
|
||||
|
||||
/*
|
||||
* We avoid zfs_zevent_destroy() here because we're otherwise racing
|
||||
* against fm_fini() destroying the zevent_lock. zfs_zevent_destroy()
|
||||
* will currently only clear `ze->ze_zevent` from an event list then
|
||||
* free `ze`, so just inline the free() here -- events have already
|
||||
* been drained.
|
||||
*/
|
||||
VERIFY3P(ze->ze_zevent, ==, NULL);
|
||||
kmem_free(ze, sizeof (zfs_zevent_t));
|
||||
|
||||
kthread_exit();
|
||||
}
|
||||
|
||||
|
||||
@@ -1653,8 +1653,10 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
ZFS_GROUP, &acl_ids->z_fuidp);
|
||||
gid = vap->va_gid;
|
||||
} else {
|
||||
acl_ids->z_fuid = zfs_fuid_create_cred(zfsvfs, ZFS_OWNER,
|
||||
cr, &acl_ids->z_fuidp);
|
||||
uid_t id = crgetuid(cr);
|
||||
if (IS_EPHEMERAL(id))
|
||||
id = UID_NOBODY;
|
||||
acl_ids->z_fuid = (uint64_t)id;
|
||||
acl_ids->z_fgid = 0;
|
||||
if (vap->va_mask & AT_GID) {
|
||||
acl_ids->z_fgid = zfs_fuid_create(zfsvfs,
|
||||
|
||||
@@ -1060,8 +1060,7 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
|
||||
objset_t *os;
|
||||
dmu_tx_t *tx;
|
||||
int error;
|
||||
ksid_t *ksid;
|
||||
uid_t uid;
|
||||
uid_t uid = crgetuid(cr);
|
||||
gid_t gid = crgetgid(cr);
|
||||
uint64_t projid = ZFS_DEFAULT_PROJID;
|
||||
zfs_acl_ids_t acl_ids;
|
||||
@@ -1075,13 +1074,6 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
|
||||
* If we have an ephemeral id, ACL, or XVATTR then
|
||||
* make sure file system is at proper version
|
||||
*/
|
||||
|
||||
ksid = crgetsid(cr, KSID_OWNER);
|
||||
if (ksid)
|
||||
uid = ksid_getid(ksid);
|
||||
else
|
||||
uid = crgetuid(cr);
|
||||
|
||||
if (zfsvfs->z_use_fuids == B_FALSE &&
|
||||
(vsecp || (vap->va_mask & AT_XVATTR) ||
|
||||
IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid)))
|
||||
@@ -1415,8 +1407,7 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
|
||||
uint64_t txtype;
|
||||
dmu_tx_t *tx;
|
||||
int error;
|
||||
ksid_t *ksid;
|
||||
uid_t uid;
|
||||
uid_t uid = crgetuid(cr);
|
||||
gid_t gid = crgetgid(cr);
|
||||
zfs_acl_ids_t acl_ids;
|
||||
boolean_t fuid_dirtied;
|
||||
@@ -1427,12 +1418,6 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
|
||||
* If we have an ephemeral id, ACL, or XVATTR then
|
||||
* make sure file system is at proper version
|
||||
*/
|
||||
|
||||
ksid = crgetsid(cr, KSID_OWNER);
|
||||
if (ksid)
|
||||
uid = ksid_getid(ksid);
|
||||
else
|
||||
uid = crgetuid(cr);
|
||||
if (zfsvfs->z_use_fuids == B_FALSE &&
|
||||
((vap->va_mask & AT_XVATTR) ||
|
||||
IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid)))
|
||||
|
||||
@@ -839,7 +839,9 @@ zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx)
|
||||
xoap = xva_getxoptattr(xvap);
|
||||
ASSERT3P(xoap, !=, NULL);
|
||||
|
||||
ASSERT_VOP_IN_SEQC(ZTOV(zp));
|
||||
if (zp->z_zfsvfs->z_replay == B_FALSE) {
|
||||
ASSERT_VOP_IN_SEQC(ZTOV(zp));
|
||||
}
|
||||
|
||||
if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) {
|
||||
uint64_t times[2];
|
||||
|
||||
@@ -128,7 +128,7 @@ groupmember(gid_t gid, const cred_t *cr)
|
||||
uid_t
|
||||
crgetuid(const cred_t *cr)
|
||||
{
|
||||
return (KUID_TO_SUID(cr->euid));
|
||||
return (KUID_TO_SUID(cr->fsuid));
|
||||
}
|
||||
|
||||
/* Return the real user id */
|
||||
@@ -138,44 +138,9 @@ crgetruid(const cred_t *cr)
|
||||
return (KUID_TO_SUID(cr->uid));
|
||||
}
|
||||
|
||||
/* Return the saved user id */
|
||||
uid_t
|
||||
crgetsuid(const cred_t *cr)
|
||||
{
|
||||
return (KUID_TO_SUID(cr->suid));
|
||||
}
|
||||
|
||||
/* Return the filesystem user id */
|
||||
uid_t
|
||||
crgetfsuid(const cred_t *cr)
|
||||
{
|
||||
return (KUID_TO_SUID(cr->fsuid));
|
||||
}
|
||||
|
||||
/* Return the effective group id */
|
||||
gid_t
|
||||
crgetgid(const cred_t *cr)
|
||||
{
|
||||
return (KGID_TO_SGID(cr->egid));
|
||||
}
|
||||
|
||||
/* Return the real group id */
|
||||
gid_t
|
||||
crgetrgid(const cred_t *cr)
|
||||
{
|
||||
return (KGID_TO_SGID(cr->gid));
|
||||
}
|
||||
|
||||
/* Return the saved group id */
|
||||
gid_t
|
||||
crgetsgid(const cred_t *cr)
|
||||
{
|
||||
return (KGID_TO_SGID(cr->sgid));
|
||||
}
|
||||
|
||||
/* Return the filesystem group id */
|
||||
gid_t
|
||||
crgetfsgid(const cred_t *cr)
|
||||
{
|
||||
return (KGID_TO_SGID(cr->fsgid));
|
||||
}
|
||||
@@ -184,12 +149,7 @@ EXPORT_SYMBOL(crhold);
|
||||
EXPORT_SYMBOL(crfree);
|
||||
EXPORT_SYMBOL(crgetuid);
|
||||
EXPORT_SYMBOL(crgetruid);
|
||||
EXPORT_SYMBOL(crgetsuid);
|
||||
EXPORT_SYMBOL(crgetfsuid);
|
||||
EXPORT_SYMBOL(crgetgid);
|
||||
EXPORT_SYMBOL(crgetrgid);
|
||||
EXPORT_SYMBOL(crgetsgid);
|
||||
EXPORT_SYMBOL(crgetfsgid);
|
||||
EXPORT_SYMBOL(crgetngroups);
|
||||
EXPORT_SYMBOL(crgetgroups);
|
||||
EXPORT_SYMBOL(groupmember);
|
||||
|
||||
@@ -121,7 +121,7 @@ secpolicy_vnode_access2(const cred_t *cr, struct inode *ip, uid_t owner,
|
||||
int
|
||||
secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner)
|
||||
{
|
||||
if (crgetfsuid(cr) == owner)
|
||||
if (crgetuid(cr) == owner)
|
||||
return (0);
|
||||
|
||||
if (zpl_inode_owner_or_capable(kcred->user_ns, ip))
|
||||
@@ -147,7 +147,7 @@ secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner)
|
||||
int
|
||||
secpolicy_vnode_chown(const cred_t *cr, uid_t owner)
|
||||
{
|
||||
if (crgetfsuid(cr) == owner)
|
||||
if (crgetuid(cr) == owner)
|
||||
return (0);
|
||||
|
||||
#if defined(CONFIG_USER_NS)
|
||||
@@ -184,7 +184,7 @@ secpolicy_vnode_remove(const cred_t *cr)
|
||||
int
|
||||
secpolicy_vnode_setdac(const cred_t *cr, uid_t owner)
|
||||
{
|
||||
if (crgetfsuid(cr) == owner)
|
||||
if (crgetuid(cr) == owner)
|
||||
return (0);
|
||||
|
||||
#if defined(CONFIG_USER_NS)
|
||||
@@ -220,7 +220,7 @@ secpolicy_vnode_setids_setgids(const cred_t *cr, gid_t gid)
|
||||
if (!kgid_has_mapping(cr->user_ns, SGID_TO_KGID(gid)))
|
||||
return (EPERM);
|
||||
#endif
|
||||
if (crgetfsgid(cr) != gid && !groupmember(gid, cr))
|
||||
if (crgetgid(cr) != gid && !groupmember(gid, cr))
|
||||
return (priv_policy_user(cr, CAP_FSETID, EPERM));
|
||||
|
||||
return (0);
|
||||
@@ -286,7 +286,7 @@ secpolicy_setid_clear(vattr_t *vap, cred_t *cr)
|
||||
static int
|
||||
secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner)
|
||||
{
|
||||
if (crgetfsuid(cr) == owner)
|
||||
if (crgetuid(cr) == owner)
|
||||
return (0);
|
||||
|
||||
#if defined(CONFIG_USER_NS)
|
||||
|
||||
@@ -116,14 +116,14 @@ zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr)
|
||||
{
|
||||
vap->va_mask = ATTR_MODE;
|
||||
vap->va_mode = mode;
|
||||
vap->va_uid = crgetfsuid(cr);
|
||||
vap->va_uid = crgetuid(cr);
|
||||
|
||||
if (dir && dir->i_mode & S_ISGID) {
|
||||
vap->va_gid = KGID_TO_SGID(dir->i_gid);
|
||||
if (S_ISDIR(mode))
|
||||
vap->va_mode |= S_ISGID;
|
||||
} else {
|
||||
vap->va_gid = crgetfsgid(cr);
|
||||
vap->va_gid = crgetgid(cr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -492,8 +492,8 @@ zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
|
||||
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||
vap->va_mode = xattr_mode;
|
||||
vap->va_mask = ATTR_MODE;
|
||||
vap->va_uid = crgetfsuid(cr);
|
||||
vap->va_gid = crgetfsgid(cr);
|
||||
vap->va_uid = crgetuid(cr);
|
||||
vap->va_gid = crgetgid(cr);
|
||||
|
||||
error = -zfs_create(dxzp, (char *)name, vap, 0, 0644, &xzp,
|
||||
cr, 0, NULL);
|
||||
|
||||
+1
-1
@@ -1205,7 +1205,7 @@ static void
|
||||
hdr_l2only_dest(void *vbuf, void *unused)
|
||||
{
|
||||
(void) unused;
|
||||
arc_buf_hdr_t *hdr = vbuf;
|
||||
arc_buf_hdr_t *hdr __maybe_unused = vbuf;
|
||||
|
||||
ASSERT(HDR_EMPTY(hdr));
|
||||
arc_space_return(HDR_L2ONLY_SIZE, ARC_SPACE_L2HDRS);
|
||||
|
||||
Reference in New Issue
Block a user