View | Details | Raw Unified | Return to bug 248250 | Differences between
and this patch

Collapse All | Expand All

(-)sys/kern/kern_environment.c (-34 / +57 lines)
Lines 44-50 Link Here
44
#include <sys/queue.h>
44
#include <sys/queue.h>
45
#include <sys/lock.h>
45
#include <sys/lock.h>
46
#include <sys/malloc.h>
46
#include <sys/malloc.h>
47
#include <sys/mutex.h>
47
#include <sys/rmlock.h>
48
#include <sys/priv.h>
48
#include <sys/priv.h>
49
#include <sys/kernel.h>
49
#include <sys/kernel.h>
50
#include <sys/systm.h>
50
#include <sys/systm.h>
Lines 78-84 Link Here
78
78
79
/* dynamic environment variables */
79
/* dynamic environment variables */
80
char		**kenvp;
80
char		**kenvp;
81
struct mtx	kenv_lock;
81
struct rmlock	kenv_lock;
82
82
83
/*
83
/*
84
 * No need to protect this with a mutex since SYSINITS are single threaded.
84
 * No need to protect this with a mutex since SYSINITS are single threaded.
Lines 100-105 Link Here
100
		int len;
100
		int len;
101
	} */ *uap;
101
	} */ *uap;
102
{
102
{
103
	struct rm_priotracker tracker;
103
	char *name, *value, *buffer = NULL;
104
	char *name, *value, *buffer = NULL;
104
	size_t len, done, needed, buflen;
105
	size_t len, done, needed, buflen;
105
	int error, i;
106
	int error, i;
Lines 120-126 Link Here
120
			    kenv_mvallen + 2);
121
			    kenv_mvallen + 2);
121
		if (uap->len > 0 && uap->value != NULL)
122
		if (uap->len > 0 && uap->value != NULL)
122
			buffer = malloc(buflen, M_TEMP, M_WAITOK|M_ZERO);
123
			buffer = malloc(buflen, M_TEMP, M_WAITOK|M_ZERO);
123
		mtx_lock(&kenv_lock);
124
		rm_rlock(&kenv_lock, &tracker);
124
		for (i = 0; kenvp[i] != NULL; i++) {
125
		for (i = 0; kenvp[i] != NULL; i++) {
125
			len = strlen(kenvp[i]) + 1;
126
			len = strlen(kenvp[i]) + 1;
126
			needed += len;
127
			needed += len;
Lines 134-140 Link Here
134
				done += len;
135
				done += len;
135
			}
136
			}
136
		}
137
		}
137
		mtx_unlock(&kenv_lock);
138
		rm_runlock(&kenv_lock, &tracker);
138
		if (buffer != NULL) {
139
		if (buffer != NULL) {
139
			error = copyout(buffer, uap->value, done);
140
			error = copyout(buffer, uap->value, done);
140
			free(buffer, M_TEMP);
141
			free(buffer, M_TEMP);
Lines 396-402 Link Here
396
	init_dynamic_kenv_from(kern_envp, &dynamic_envpos);
397
	init_dynamic_kenv_from(kern_envp, &dynamic_envpos);
397
	kenvp[dynamic_envpos] = NULL;
398
	kenvp[dynamic_envpos] = NULL;
398
399
399
	mtx_init(&kenv_lock, "kernel environment", NULL, MTX_DEF);
400
	rm_init(&kenv_lock, "kernel environment");
400
	dynamic_kenv = true;
401
	dynamic_kenv = true;
401
}
402
}
402
SYSINIT(kenv, SI_SUB_KMEM + 1, SI_ORDER_FIRST, init_dynamic_kenv, NULL);
403
SYSINIT(kenv, SI_SUB_KMEM + 1, SI_ORDER_FIRST, init_dynamic_kenv, NULL);
Lines 436-442 Link Here
436
_getenv_dynamic(const char *name, int *idx)
437
_getenv_dynamic(const char *name, int *idx)
437
{
438
{
438
439
439
	mtx_assert(&kenv_lock, MA_OWNED);
440
	rm_assert(&kenv_lock, RA_LOCKED);
440
	return (_getenv_dynamic_locked(name, idx));
441
	return (_getenv_dynamic_locked(name, idx));
441
}
442
}
442
443
Lines 501-512 Link Here
501
int
502
int
502
testenv(const char *name)
503
testenv(const char *name)
503
{
504
{
505
	struct rm_priotracker tracker;
504
	char *cp;
506
	char *cp;
505
507
506
	if (dynamic_kenv) {
508
	if (dynamic_kenv) {
507
		mtx_lock(&kenv_lock);
509
		rm_rlock(&kenv_lock, &tracker);
508
		cp = _getenv_dynamic(name, NULL);
510
		cp = _getenv_dynamic(name, NULL);
509
		mtx_unlock(&kenv_lock);
511
		rm_runlock(&kenv_lock, &tracker);
510
	} else
512
	} else
511
		cp = _getenv_static(name);
513
		cp = _getenv_static(name);
512
	if (cp != NULL)
514
	if (cp != NULL)
Lines 562-573 Link Here
562
	buf = malloc(namelen + vallen, M_KENV, M_WAITOK);
564
	buf = malloc(namelen + vallen, M_KENV, M_WAITOK);
563
	sprintf(buf, "%s=%s", name, value);
565
	sprintf(buf, "%s=%s", name, value);
564
566
565
	mtx_lock(&kenv_lock);
567
	rm_wlock(&kenv_lock);
566
	cp = _getenv_dynamic(name, &i);
568
	cp = _getenv_dynamic(name, &i);
567
	if (cp != NULL) {
569
	if (cp != NULL) {
568
		oldenv = kenvp[i];
570
		oldenv = kenvp[i];
569
		kenvp[i] = buf;
571
		kenvp[i] = buf;
570
		mtx_unlock(&kenv_lock);
572
		rm_wunlock(&kenv_lock);
571
		free(oldenv, M_KENV);
573
		free(oldenv, M_KENV);
572
	} else {
574
	} else {
573
		/* We add the option if it wasn't found */
575
		/* We add the option if it wasn't found */
Lines 577-589 Link Here
577
		/* Bounds checking */
579
		/* Bounds checking */
578
		if (i < 0 || i >= KENV_SIZE) {
580
		if (i < 0 || i >= KENV_SIZE) {
579
			free(buf, M_KENV);
581
			free(buf, M_KENV);
580
			mtx_unlock(&kenv_lock);
582
			rm_wunlock(&kenv_lock);
581
			return (-1);
583
			return (-1);
582
		}
584
		}
583
585
584
		kenvp[i] = buf;
586
		kenvp[i] = buf;
585
		kenvp[i + 1] = NULL;
587
		kenvp[i + 1] = NULL;
586
		mtx_unlock(&kenv_lock);
588
		rm_wunlock(&kenv_lock);
587
	}
589
	}
588
	return (0);
590
	return (0);
589
}
591
}
Lines 599-605 Link Here
599
601
600
	KENV_CHECK;
602
	KENV_CHECK;
601
603
602
	mtx_lock(&kenv_lock);
604
	rm_wlock(&kenv_lock);
603
	cp = _getenv_dynamic(name, &i);
605
	cp = _getenv_dynamic(name, &i);
604
	if (cp != NULL) {
606
	if (cp != NULL) {
605
		oldenv = kenvp[i];
607
		oldenv = kenvp[i];
Lines 606-616 Link Here
606
		for (j = i + 1; kenvp[j] != NULL; j++)
608
		for (j = i + 1; kenvp[j] != NULL; j++)
607
			kenvp[i++] = kenvp[j];
609
			kenvp[i++] = kenvp[j];
608
		kenvp[i] = NULL;
610
		kenvp[i] = NULL;
609
		mtx_unlock(&kenv_lock);
611
		rm_wunlock(&kenv_lock);
610
		zfree(oldenv, M_KENV);
612
		zfree(oldenv, M_KENV);
611
		return (0);
613
		return (0);
612
	}
614
	}
613
	mtx_unlock(&kenv_lock);
615
	rm_wunlock(&kenv_lock);
614
	return (-1);
616
	return (-1);
615
}
617
}
616
618
Lines 620-625 Link Here
620
static char *
622
static char *
621
getenv_string_buffer(const char *name)
623
getenv_string_buffer(const char *name)
622
{
624
{
625
	struct rm_priotracker tracker;
623
	char *cp, *ret;
626
	char *cp, *ret;
624
	int len;
627
	int len;
625
628
Lines 626-636 Link Here
626
	if (dynamic_kenv) {
629
	if (dynamic_kenv) {
627
		len = KENV_MNAMELEN + 1 + kenv_mvallen + 1;
630
		len = KENV_MNAMELEN + 1 + kenv_mvallen + 1;
628
		ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO);
631
		ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO);
629
		mtx_lock(&kenv_lock);
632
		rm_rlock(&kenv_lock, &tracker);
630
		cp = _getenv_dynamic(name, NULL);
633
		cp = _getenv_dynamic(name, NULL);
631
		if (cp != NULL)
634
		if (cp != NULL)
632
			strlcpy(ret, cp, len);
635
			strlcpy(ret, cp, len);
633
		mtx_unlock(&kenv_lock);
636
		rm_runlock(&kenv_lock, &tracker);
634
		if (cp == NULL) {
637
		if (cp == NULL) {
635
			uma_zfree(kenv_zone, ret);
638
			uma_zfree(kenv_zone, ret);
636
			ret = NULL;
639
			ret = NULL;
Lines 647-660 Link Here
647
int
650
int
648
getenv_string(const char *name, char *data, int size)
651
getenv_string(const char *name, char *data, int size)
649
{
652
{
653
	struct rm_priotracker tracker;
650
	char *cp;
654
	char *cp;
651
655
652
	if (dynamic_kenv) {
656
	if (dynamic_kenv) {
653
		mtx_lock(&kenv_lock);
657
		rm_rlock(&kenv_lock, &tracker);
654
		cp = _getenv_dynamic(name, NULL);
658
		cp = _getenv_dynamic(name, NULL);
655
		if (cp != NULL)
659
		if (cp != NULL)
656
			strlcpy(data, cp, size);
660
			strlcpy(data, cp, size);
657
		mtx_unlock(&kenv_lock);
661
		rm_runlock(&kenv_lock, &tracker);
658
	} else {
662
	} else {
659
		cp = _getenv_static(name);
663
		cp = _getenv_static(name);
660
		if (cp != NULL)
664
		if (cp != NULL)
Lines 670-688 Link Here
670
getenv_array(const char *name, void *pdata, int size, int *psize,
674
getenv_array(const char *name, void *pdata, int size, int *psize,
671
    int type_size, bool allow_signed)
675
    int type_size, bool allow_signed)
672
{
676
{
677
	struct rm_priotracker tracker;
673
	uint8_t shift;
678
	uint8_t shift;
674
	int64_t value;
679
	int64_t value;
675
	int64_t old;
680
	int64_t old;
676
	char *buf;
681
	const char *buf;
677
	char *end;
682
	char *end;
678
	char *ptr;
683
	const char *ptr;
679
	int n;
684
	int n;
680
	int rc;
685
	int rc;
681
686
682
	if ((buf = getenv_string_buffer(name)) == NULL)
687
	if (dynamic_kenv) {
683
		return (0);
688
		rm_rlock(&kenv_lock, &tracker);
689
		buf = _getenv_dynamic(name, NULL);
690
	} else
691
		buf = _getenv_static(name);
684
692
685
	rc = 0;			  /* assume failure */
693
	rc = 0;			  /* assume failure */
694
695
	if (buf == NULL)
696
		goto error;
697
686
	/* get maximum number of elements */
698
	/* get maximum number of elements */
687
	size /= type_size;
699
	size /= type_size;
688
700
Lines 798-804 Link Here
798
		rc = 1;	/* success */
810
		rc = 1;	/* success */
799
error:
811
error:
800
	if (dynamic_kenv)
812
	if (dynamic_kenv)
801
		uma_zfree(kenv_zone, buf);
813
		rm_runlock(&kenv_lock, &tracker);
802
	return (rc);
814
	return (rc);
803
}
815
}
804
816
Lines 898-915 Link Here
898
int
910
int
899
getenv_quad(const char *name, quad_t *data)
911
getenv_quad(const char *name, quad_t *data)
900
{
912
{
901
	char	*value, *vtp;
913
	struct rm_priotracker tracker;
902
	quad_t	iv;
914
	const char	*value;
915
	char		suffix, *vtp;
916
	quad_t		iv;
903
917
904
	value = getenv_string_buffer(name);
918
	if (dynamic_kenv) {
905
	if (value == NULL)
919
		rm_rlock(&kenv_lock, &tracker);
906
		return (0);
920
		value = _getenv_dynamic(name, NULL);
921
	} else
922
		value = _getenv_static(name);
923
	if (value == NULL) {
924
		goto error;
925
	}
907
	iv = strtoq(value, &vtp, 0);
926
	iv = strtoq(value, &vtp, 0);
908
	if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
927
	if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
909
		freeenv(value);
928
		goto error;
910
		return (0);
911
	}
929
	}
912
	switch (vtp[0]) {
930
	suffix = vtp[0];
931
	if (dynamic_kenv)
932
		rm_runlock(&kenv_lock, &tracker);
933
	switch (suffix) {
913
	case 't': case 'T':
934
	case 't': case 'T':
914
		iv *= 1024;
935
		iv *= 1024;
915
		/* FALLTHROUGH */
936
		/* FALLTHROUGH */
Lines 924-935 Link Here
924
	case '\0':
945
	case '\0':
925
		break;
946
		break;
926
	default:
947
	default:
927
		freeenv(value);
928
		return (0);
948
		return (0);
929
	}
949
	}
930
	freeenv(value);
931
	*data = iv;
950
	*data = iv;
932
	return (1);
951
	return (1);
952
error:
953
	if (dynamic_kenv)
954
		rm_runlock(&kenv_lock, &tracker);
955
	return (0);
933
}
956
}
934
957
935
/*
958
/*
(-)sys/kern/subr_hints.c (-5 / +8 lines)
Lines 33-39 Link Here
33
#include <sys/lock.h>
33
#include <sys/lock.h>
34
#include <sys/kernel.h>
34
#include <sys/kernel.h>
35
#include <sys/malloc.h>
35
#include <sys/malloc.h>
36
#include <sys/mutex.h>
36
#include <sys/rmlock.h>
37
#include <sys/sysctl.h>
37
#include <sys/sysctl.h>
38
#include <sys/systm.h>
38
#include <sys/systm.h>
39
#include <sys/bus.h>
39
#include <sys/bus.h>
Lines 42-47 Link Here
42
#define	FBACK_STENV	1	/* Static env */
42
#define	FBACK_STENV	1	/* Static env */
43
#define	FBACK_STATIC	2	/* static_hints */
43
#define	FBACK_STATIC	2	/* static_hints */
44
44
45
extern struct rmlock kenv_lock;
46
45
/*
47
/*
46
 * We'll use hintenv_merged to indicate that the dynamic environment has been
48
 * We'll use hintenv_merged to indicate that the dynamic environment has been
47
 * properly prepared for hint usage.  This implies that the dynamic environment
49
 * properly prepared for hint usage.  This implies that the dynamic environment
Lines 126-131 Link Here
126
    const char **ret_name, int *ret_namelen, int *ret_unit,
128
    const char **ret_name, int *ret_namelen, int *ret_unit,
127
    const char **ret_resname, int *ret_resnamelen, const char **ret_value)
129
    const char **ret_resname, int *ret_resnamelen, const char **ret_value)
128
{
130
{
131
	struct rm_priotracker tracker; 
129
	int fbacklvl = FBACK_MDENV, i = 0, n = 0;
132
	int fbacklvl = FBACK_MDENV, i = 0, n = 0;
130
	char r_name[32];
133
	char r_name[32];
131
	int r_unit;
134
	int r_unit;
Lines 150-156 Link Here
150
			 * already been folded in to the environment
153
			 * already been folded in to the environment
151
			 * by this point.
154
			 * by this point.
152
			 */
155
			 */
153
			mtx_lock(&kenv_lock);
156
			rm_rlock(&kenv_lock, &tracker);
154
			cp = kenvp[0];
157
			cp = kenvp[0];
155
			for (i = 0; cp != NULL; cp = kenvp[++i]) {
158
			for (i = 0; cp != NULL; cp = kenvp[++i]) {
156
				if (!strncmp(cp, "hint.", 5)) {
159
				if (!strncmp(cp, "hint.", 5)) {
Lines 158-164 Link Here
158
					break;
161
					break;
159
				}
162
				}
160
			}
163
			}
161
			mtx_unlock(&kenv_lock);
164
			rm_runlock(&kenv_lock, &tracker);
162
			dyn_used = true;
165
			dyn_used = true;
163
		} else {
166
		} else {
164
			/*
167
			/*
Lines 224-230 Link Here
224
	}
227
	}
225
228
226
	if (dyn_used) {
229
	if (dyn_used) {
227
		mtx_lock(&kenv_lock);
230
		rm_rlock(&kenv_lock, &tracker);
228
		i = 0;
231
		i = 0;
229
	}
232
	}
230
233
Lines 269-275 Link Here
269
		}
272
		}
270
	}
273
	}
271
	if (dyn_used)
274
	if (dyn_used)
272
		mtx_unlock(&kenv_lock);
275
		rm_runlock(&kenv_lock, &tracker);
273
	if (cp == NULL)
276
	if (cp == NULL)
274
		goto fallback;
277
		goto fallback;
275
278
(-)sys/sys/systm.h (-1 lines)
Lines 195-201 Link Here
195
 */
195
 */
196
extern int osreldate;
196
extern int osreldate;
197
extern bool dynamic_kenv;
197
extern bool dynamic_kenv;
198
extern struct mtx kenv_lock;
199
extern char *kern_envp;
198
extern char *kern_envp;
200
extern char *md_envp;
199
extern char *md_envp;
201
extern char static_env[];
200
extern char static_env[];

Return to bug 248250