Lines 59-64
Link Here
|
59 |
static char *_getenv_dynamic_locked(const char *name, int *idx); |
59 |
static char *_getenv_dynamic_locked(const char *name, int *idx); |
60 |
static char *_getenv_dynamic(const char *name, int *idx); |
60 |
static char *_getenv_dynamic(const char *name, int *idx); |
61 |
|
61 |
|
|
|
62 |
static char *kenv_acquire(const char *name); |
63 |
static void kenv_release(const char *buf); |
64 |
|
62 |
static MALLOC_DEFINE(M_KENV, "kenv", "kernel environment"); |
65 |
static MALLOC_DEFINE(M_KENV, "kenv", "kernel environment"); |
63 |
|
66 |
|
64 |
#define KENV_SIZE 512 /* Maximum number of environment strings */ |
67 |
#define KENV_SIZE 512 /* Maximum number of environment strings */ |
Lines 88-95
Link Here
|
88 |
#define KENV_CHECK if (!dynamic_kenv) \ |
91 |
#define KENV_CHECK if (!dynamic_kenv) \ |
89 |
panic("%s: called before SI_SUB_KMEM", __func__) |
92 |
panic("%s: called before SI_SUB_KMEM", __func__) |
90 |
|
93 |
|
91 |
static char *getenv_string_buffer(const char *); |
|
|
92 |
|
93 |
int |
94 |
int |
94 |
sys_kenv(td, uap) |
95 |
sys_kenv(td, uap) |
95 |
struct thread *td; |
96 |
struct thread *td; |
Lines 482-497
Link Here
|
482 |
char * |
483 |
char * |
483 |
kern_getenv(const char *name) |
484 |
kern_getenv(const char *name) |
484 |
{ |
485 |
{ |
485 |
char *ret; |
486 |
char *cp, *ret; |
|
|
487 |
int len; |
486 |
|
488 |
|
487 |
if (dynamic_kenv) { |
489 |
if (dynamic_kenv) { |
488 |
ret = getenv_string_buffer(name); |
490 |
len = KENV_MNAMELEN + 1 + kenv_mvallen + 1; |
489 |
if (ret == NULL) { |
491 |
ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO); |
490 |
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, |
492 |
mtx_lock(&kenv_lock); |
491 |
"getenv"); |
493 |
cp = _getenv_dynamic(name, NULL); |
|
|
494 |
if (cp != NULL) |
495 |
strlcpy(ret, cp, len); |
496 |
mtx_unlock(&kenv_lock); |
497 |
if (cp == NULL) { |
498 |
uma_zfree(kenv_zone, ret); |
499 |
ret = NULL; |
492 |
} |
500 |
} |
493 |
} else |
501 |
} else |
494 |
ret = _getenv_static(name); |
502 |
ret = _getenv_static(name); |
|
|
503 |
|
495 |
return (ret); |
504 |
return (ret); |
496 |
} |
505 |
} |
497 |
|
506 |
|
Lines 503-514
Link Here
|
503 |
{ |
512 |
{ |
504 |
char *cp; |
513 |
char *cp; |
505 |
|
514 |
|
506 |
if (dynamic_kenv) { |
515 |
cp = kenv_acquire(name); |
507 |
mtx_lock(&kenv_lock); |
516 |
kenv_release(cp); |
508 |
cp = _getenv_dynamic(name, NULL); |
517 |
|
509 |
mtx_unlock(&kenv_lock); |
|
|
510 |
} else |
511 |
cp = _getenv_static(name); |
512 |
if (cp != NULL) |
518 |
if (cp != NULL) |
513 |
return (1); |
519 |
return (1); |
514 |
return (0); |
520 |
return (0); |
Lines 615-644
Link Here
|
615 |
} |
621 |
} |
616 |
|
622 |
|
617 |
/* |
623 |
/* |
618 |
* Return a buffer containing the string value from an environment variable |
624 |
* Return the internal kenv buffer for the variable name, if it exists. |
|
|
625 |
* If the dynamic kenv is initialized and the name is present, return |
626 |
* with kenv_lock held. |
619 |
*/ |
627 |
*/ |
620 |
static char * |
628 |
static char * |
621 |
getenv_string_buffer(const char *name) |
629 |
kenv_acquire(const char *name) |
622 |
{ |
630 |
{ |
623 |
char *cp, *ret; |
631 |
char *value; |
624 |
int len; |
|
|
625 |
|
632 |
|
626 |
if (dynamic_kenv) { |
633 |
if (dynamic_kenv) { |
627 |
len = KENV_MNAMELEN + 1 + kenv_mvallen + 1; |
|
|
628 |
ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO); |
629 |
mtx_lock(&kenv_lock); |
634 |
mtx_lock(&kenv_lock); |
630 |
cp = _getenv_dynamic(name, NULL); |
635 |
value = _getenv_dynamic(name, NULL); |
631 |
if (cp != NULL) |
636 |
if (value == NULL) |
632 |
strlcpy(ret, cp, len); |
637 |
mtx_unlock(&kenv_lock); |
633 |
mtx_unlock(&kenv_lock); |
638 |
return (value); |
634 |
if (cp == NULL) { |
|
|
635 |
uma_zfree(kenv_zone, ret); |
636 |
ret = NULL; |
637 |
} |
638 |
} else |
639 |
} else |
639 |
ret = _getenv_static(name); |
640 |
return (_getenv_static(name)); |
|
|
641 |
} |
640 |
|
642 |
|
641 |
return (ret); |
643 |
/* |
|
|
644 |
* Undo a previous kenv_acquire() operation |
645 |
*/ |
646 |
static void |
647 |
kenv_release(const char *buf) |
648 |
{ |
649 |
if ((buf != NULL) && dynamic_kenv) |
650 |
mtx_unlock(&kenv_lock); |
642 |
} |
651 |
} |
643 |
|
652 |
|
644 |
/* |
653 |
/* |
Lines 649-665
Link Here
|
649 |
{ |
658 |
{ |
650 |
char *cp; |
659 |
char *cp; |
651 |
|
660 |
|
652 |
if (dynamic_kenv) { |
661 |
cp = kenv_acquire(name); |
653 |
mtx_lock(&kenv_lock); |
662 |
|
654 |
cp = _getenv_dynamic(name, NULL); |
663 |
if (cp != NULL) |
655 |
if (cp != NULL) |
664 |
strlcpy(data, cp, size); |
656 |
strlcpy(data, cp, size); |
665 |
|
657 |
mtx_unlock(&kenv_lock); |
666 |
kenv_release(cp); |
658 |
} else { |
667 |
|
659 |
cp = _getenv_static(name); |
|
|
660 |
if (cp != NULL) |
661 |
strlcpy(data, cp, size); |
662 |
} |
663 |
return (cp != NULL); |
668 |
return (cp != NULL); |
664 |
} |
669 |
} |
665 |
|
670 |
|
Lines 673-688
Link Here
|
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 |
rc = 0; /* assume failure */ |
683 |
return (0); |
|
|
684 |
|
688 |
|
685 |
rc = 0; /* assume failure */ |
689 |
buf = kenv_acquire(name); |
|
|
690 |
if (buf == NULL) |
691 |
goto error; |
692 |
|
686 |
/* get maximum number of elements */ |
693 |
/* get maximum number of elements */ |
687 |
size /= type_size; |
694 |
size /= type_size; |
688 |
|
695 |
|
Lines 797-804
Link Here
|
797 |
if (n != 0) |
804 |
if (n != 0) |
798 |
rc = 1; /* success */ |
805 |
rc = 1; /* success */ |
799 |
error: |
806 |
error: |
800 |
if (dynamic_kenv) |
807 |
kenv_release(buf); |
801 |
uma_zfree(kenv_zone, buf); |
|
|
802 |
return (rc); |
808 |
return (rc); |
803 |
} |
809 |
} |
804 |
|
810 |
|
Lines 898-915
Link Here
|
898 |
int |
904 |
int |
899 |
getenv_quad(const char *name, quad_t *data) |
905 |
getenv_quad(const char *name, quad_t *data) |
900 |
{ |
906 |
{ |
901 |
char *value, *vtp; |
907 |
const char *value; |
902 |
quad_t iv; |
908 |
char suffix, *vtp; |
|
|
909 |
quad_t iv; |
903 |
|
910 |
|
904 |
value = getenv_string_buffer(name); |
911 |
value = kenv_acquire(name); |
905 |
if (value == NULL) |
912 |
if (value == NULL) { |
906 |
return (0); |
913 |
goto error; |
|
|
914 |
} |
907 |
iv = strtoq(value, &vtp, 0); |
915 |
iv = strtoq(value, &vtp, 0); |
908 |
if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) { |
916 |
if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) { |
909 |
freeenv(value); |
917 |
goto error; |
910 |
return (0); |
|
|
911 |
} |
918 |
} |
912 |
switch (vtp[0]) { |
919 |
suffix = vtp[0]; |
|
|
920 |
kenv_release(value); |
921 |
switch (suffix) { |
913 |
case 't': case 'T': |
922 |
case 't': case 'T': |
914 |
iv *= 1024; |
923 |
iv *= 1024; |
915 |
/* FALLTHROUGH */ |
924 |
/* FALLTHROUGH */ |
Lines 924-935
Link Here
|
924 |
case '\0': |
933 |
case '\0': |
925 |
break; |
934 |
break; |
926 |
default: |
935 |
default: |
927 |
freeenv(value); |
|
|
928 |
return (0); |
936 |
return (0); |
929 |
} |
937 |
} |
930 |
freeenv(value); |
|
|
931 |
*data = iv; |
938 |
*data = iv; |
932 |
return (1); |
939 |
return (1); |
|
|
940 |
error: |
941 |
kenv_release(value); |
942 |
return (0); |
933 |
} |
943 |
} |
934 |
|
944 |
|
935 |
/* |
945 |
/* |