Skip to content

Commit 4d451ba

Browse files
robnbehlendorf
authored andcommitted
libspl: hide global data objects
Currently libspl is a static archive that is linked into multiple shared objects, which then re-export its symbols. We intend to fix this soon. For the moment though, most programs shipped with OpenZFS depend on two or more of these shared objects, and see the same symbols twice. For functions this is not a problem, as they do not have any mutable state and so the linker can simply select the first one and use that for all. For global data objects however, each shared object will have direct (non-relocatable) references to its own instance of the symbol, such that changes on one will not necessarily be seen by the other. While this shouldn't be a problem in practice as these reexported interfaces are not supposed to be used, they are technically undefined behaviour in C (C17 6.9.2) and are reported by ASAN as a violation of C++'s "One Definition Rule". To fix this, we hide these globals inside their compilation units, and add access functions and macros as appropriate to preserve the existing API (though not ABI). Sponsored-by: https://despairlabs.com/sponsor/ Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <robn@despairlabs.com> Closes #17861
1 parent e282e98 commit 4d451ba

File tree

10 files changed

+58
-52
lines changed

10 files changed

+58
-52
lines changed

cmd/zstream/zstream_redup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,9 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
191191
#ifdef _ILP32
192192
uint64_t max_rde_size = SMALLEST_POSSIBLE_MAX_RDT_MB << 20;
193193
#else
194-
uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
194+
uint64_t physbytes = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
195195
uint64_t max_rde_size =
196-
MAX((physmem * MAX_RDT_PHYSMEM_PERCENT) / 100,
196+
MAX((physbytes * MAX_RDT_PHYSMEM_PERCENT) / 100,
197197
SMALLEST_POSSIBLE_MAX_RDT_MB << 20);
198198
#endif
199199

cmd/ztest.c

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@
140140
#include <sys/zfs_impl.h>
141141
#include <sys/backtrace.h>
142142
#include <libzpool.h>
143+
#include <libspl.h>
143144

144145
static int ztest_fd_data = -1;
145-
static int ztest_fd_rand = -1;
146146

147147
typedef struct ztest_shared_hdr {
148148
uint64_t zh_hdr_size;
@@ -903,13 +903,10 @@ ztest_random(uint64_t range)
903903
{
904904
uint64_t r;
905905

906-
ASSERT3S(ztest_fd_rand, >=, 0);
907-
908906
if (range == 0)
909907
return (0);
910908

911-
if (read(ztest_fd_rand, &r, sizeof (r)) != sizeof (r))
912-
fatal(B_TRUE, "short read from /dev/urandom");
909+
random_get_pseudo_bytes((uint8_t *)&r, sizeof (r));
913910

914911
return (r % range);
915912
}
@@ -8146,10 +8143,8 @@ ztest_raidz_expand_run(ztest_shared_t *zs, spa_t *spa)
81468143
/* Setup a 1 MiB buffer of random data */
81478144
uint64_t bufsize = 1024 * 1024;
81488145
void *buffer = umem_alloc(bufsize, UMEM_NOFAIL);
8146+
random_get_pseudo_bytes((uint8_t *)&buffer, bufsize);
81498147

8150-
if (read(ztest_fd_rand, buffer, bufsize) != bufsize) {
8151-
fatal(B_TRUE, "short read from /dev/urandom");
8152-
}
81538148
/*
81548149
* Put some data in the pool and then attach a vdev to initiate
81558150
* reflow.
@@ -8955,13 +8950,7 @@ main(int argc, char **argv)
89558950
exit(EXIT_FAILURE);
89568951
}
89578952

8958-
/*
8959-
* Force random_get_bytes() to use /dev/urandom in order to prevent
8960-
* ztest from needlessly depleting the system entropy pool.
8961-
*/
8962-
random_path = "/dev/urandom";
8963-
ztest_fd_rand = open(random_path, O_RDONLY | O_CLOEXEC);
8964-
ASSERT3S(ztest_fd_rand, >=, 0);
8953+
libspl_init();
89658954

89668955
if (!fd_data_str) {
89678956
process_options(argc, argv);

lib/libspl/include/sys/misc.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@
3131

3232
#include <sys/utsname.h>
3333

34-
extern const char *random_path;
35-
extern const char *urandom_path;
36-
3734
/*
3835
* Hostname information
3936
*/

lib/libspl/include/sys/systm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#ifndef _LIBSPL_SYS_SYSTM_H
3030
#define _LIBSPL_SYS_SYSTM_H
3131

32-
extern uint64_t physmem;
32+
uint64_t libspl_physmem(void);
33+
34+
#define physmem libspl_physmem()
3335

3436
#endif

lib/libspl/include/sys/taskq.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,11 @@ typedef struct taskq {
8686

8787
#define TASKQID_INVALID ((taskqid_t)0)
8888

89-
extern taskq_t *system_taskq;
90-
extern taskq_t *system_delay_taskq;
89+
extern taskq_t *_system_taskq(void);
90+
extern taskq_t *_system_delay_taskq(void);
91+
92+
#define system_taskq _system_taskq()
93+
#define system_delay_taskq _system_delay_taskq()
9194

9295
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
9396
extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t,

lib/libspl/include/sys/thread.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,9 @@ typedef pthread_t kthread_t;
5858
#define current_is_reclaim_thread() (0)
5959

6060
/* in libzpool, p0 exists only to have its address taken */
61-
typedef struct proc {
62-
uintptr_t this_is_never_used_dont_dereference_it;
63-
} proc_t;
61+
typedef void (proc_t)(void);
62+
extern void p0(void);
6463

65-
extern struct proc p0;
6664
#define curproc (&p0)
6765

6866
#define PS_NONE -1

lib/libspl/libspl.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,18 @@
3131
#include <assert.h>
3232
#include <unistd.h>
3333
#include <sys/misc.h>
34+
#include <sys/systm.h>
3435
#include <sys/utsname.h>
3536
#include "libspl_impl.h"
3637

37-
uint64_t physmem;
38-
struct utsname hw_utsname;
38+
static uint64_t hw_physmem = 0;
39+
static struct utsname hw_utsname = {};
40+
41+
uint64_t
42+
libspl_physmem(void)
43+
{
44+
return (hw_physmem);
45+
}
3946

4047
utsname_t *
4148
utsname(void)
@@ -46,7 +53,7 @@ utsname(void)
4653
void
4754
libspl_init(void)
4855
{
49-
physmem = sysconf(_SC_PHYS_PAGES);
56+
hw_physmem = sysconf(_SC_PHYS_PAGES);
5057

5158
VERIFY0(uname(&hw_utsname));
5259

lib/libspl/random.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,22 @@
3232
#include <sys/random.h>
3333
#include "libspl_impl.h"
3434

35-
const char *random_path = "/dev/random";
36-
const char *urandom_path = "/dev/urandom";
35+
#define RANDOM_PATH "/dev/random"
36+
#define URANDOM_PATH "/dev/urandom"
37+
3738
static int random_fd = -1, urandom_fd = -1;
3839

3940
void
4041
random_init(void)
4142
{
42-
VERIFY((random_fd = open(random_path, O_RDONLY | O_CLOEXEC)) != -1);
43-
VERIFY((urandom_fd = open(urandom_path, O_RDONLY | O_CLOEXEC)) != -1);
43+
/* Handle multiple calls. */
44+
if (random_fd != -1) {
45+
ASSERT3U(urandom_fd, !=, -1);
46+
return;
47+
}
48+
49+
VERIFY((random_fd = open(RANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1);
50+
VERIFY((urandom_fd = open(URANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1);
4451
}
4552

4653
void

lib/libspl/taskq.c

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,20 @@
3636
#include <sys/taskq.h>
3737
#include <sys/kmem.h>
3838

39-
int taskq_now;
40-
taskq_t *system_taskq;
41-
taskq_t *system_delay_taskq;
39+
static taskq_t *__system_taskq = NULL;
40+
static taskq_t *__system_delay_taskq = NULL;
41+
42+
taskq_t
43+
*_system_taskq(void)
44+
{
45+
return (__system_taskq);
46+
}
47+
48+
taskq_t
49+
*_system_delay_taskq(void)
50+
{
51+
return (__system_delay_taskq);
52+
}
4253

4354
static pthread_key_t taskq_tsd;
4455

@@ -111,11 +122,6 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags)
111122
{
112123
taskq_ent_t *t;
113124

114-
if (taskq_now) {
115-
func(arg);
116-
return (1);
117-
}
118-
119125
mutex_enter(&tq->tq_lock);
120126
ASSERT(tq->tq_flags & TASKQ_ACTIVE);
121127
if ((t = task_alloc(tq, tqflags)) == NULL) {
@@ -378,9 +384,6 @@ taskq_member(taskq_t *tq, kthread_t *t)
378384
{
379385
int i;
380386

381-
if (taskq_now)
382-
return (1);
383-
384387
for (i = 0; i < tq->tq_nthreads; i++)
385388
if (tq->tq_threadlist[i] == t)
386389
return (1);
@@ -405,18 +408,18 @@ void
405408
system_taskq_init(void)
406409
{
407410
VERIFY0(pthread_key_create(&taskq_tsd, NULL));
408-
system_taskq = taskq_create("system_taskq", 64, maxclsyspri, 4, 512,
411+
__system_taskq = taskq_create("system_taskq", 64, maxclsyspri, 4, 512,
409412
TASKQ_DYNAMIC | TASKQ_PREPOPULATE);
410-
system_delay_taskq = taskq_create("delay_taskq", 4, maxclsyspri, 4,
413+
__system_delay_taskq = taskq_create("delay_taskq", 4, maxclsyspri, 4,
411414
512, TASKQ_DYNAMIC | TASKQ_PREPOPULATE);
412415
}
413416

414417
void
415418
system_taskq_fini(void)
416419
{
417-
taskq_destroy(system_taskq);
418-
system_taskq = NULL; /* defensive */
419-
taskq_destroy(system_delay_taskq);
420-
system_delay_taskq = NULL;
420+
taskq_destroy(__system_taskq);
421+
__system_taskq = NULL; /* defensive */
422+
taskq_destroy(__system_delay_taskq);
423+
__system_delay_taskq = NULL;
421424
VERIFY0(pthread_key_delete(taskq_tsd));
422425
}

lib/libspl/thread.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
#include <sys/thread.h>
3333

3434
/* this only exists to have its address taken */
35-
struct proc p0;
35+
void p0(void) {}
3636

3737
/*
3838
* =========================================================================

0 commit comments

Comments
 (0)