Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
steam
systemd
Commits
036643a2
Commit
036643a2
authored
Feb 13, 2010
by
Lennart Poettering
Browse files
config: implement search path logic
parent
65d2ebdc
Changes
8
Hide whitespace changes
Inline
Side-by-side
Makefile.am
View file @
036643a2
...
...
@@ -17,9 +17,15 @@
ACLOCAL_AMFLAGS
=
-I
m4
pkgsysconfdir
=
$(sysconfdir)
/systemd
AM_CPPFLAGS
=
\
-include
$(top_builddir)
/config.h
\
-DUNIT_PATH
=
\"
/tmp/does/not/exist
\"
-DSYSTEM_CONFIG_UNIT_PATH
=
\"
$(pkgsysconfdir)
/system
\"
\
-DSYSTEM_DATA_UNIT_PATH
=
\"
$(pkgdatadir)
/system
\"
\
-DSYSTEM_SYSVINIT_PATH
=
\"
$(sysconfdir)
/init.d
\"
\
-DSESSION_CONFIG_UNIT_PATH
=
\"
$(pkgsysconfdir)
/session
\"
\
-DSESSION_DATA_UNIT_PATH
=
\"
$(pkgdatadir)
/session
\"
sbin_PROGRAMS
=
\
systemd
...
...
dbus.c
View file @
036643a2
...
...
@@ -378,7 +378,7 @@ int bus_init(Manager *m) {
dbus_connection_set_change_sigpipe
(
FALSE
);
dbus_error_init
(
&
error
);
if
(
!
(
m
->
bus
=
dbus_bus_get_private
(
m
->
running_as
==
MANAGER_
U
SE
R
?
DBUS_BUS_SESSION
:
DBUS_BUS_SYSTEM
,
&
error
)))
{
if
(
!
(
m
->
bus
=
dbus_bus_get_private
(
m
->
running_as
==
MANAGER_SE
SSION
?
DBUS_BUS_SESSION
:
DBUS_BUS_SYSTEM
,
&
error
)))
{
log_error
(
"Failed to get D-Bus connection: %s"
,
error
.
message
);
dbus_error_free
(
&
error
);
return
-
ECONNREFUSED
;
...
...
load-dropin.c
View file @
036643a2
...
...
@@ -25,6 +25,7 @@
#include
"unit.h"
#include
"load-dropin.h"
#include
"log.h"
#include
"strv.h"
int
unit_load_dropin
(
Unit
*
u
)
{
Iterator
i
;
...
...
@@ -39,52 +40,56 @@ int unit_load_dropin(Unit *u) {
char
*
path
;
DIR
*
d
;
struct
dirent
*
de
;
char
**
p
;
if
(
asprintf
(
&
path
,
"%s/%s.wants"
,
unit_path
(),
t
)
<
0
)
return
-
ENOMEM
;
STRV_FOREACH
(
p
,
u
->
meta
.
manager
->
unit_path
)
{
if
(
!
(
d
=
opendir
(
path
)))
{
r
=
-
errno
;
free
(
path
);
if
(
asprintf
(
&
path
,
"%s/%s.wants"
,
*
p
,
t
)
<
0
)
return
-
ENOMEM
;
if
(
r
==
-
ENOENT
)
continue
;
if
(
!
(
d
=
opendir
(
path
)))
{
r
=
-
errno
;
free
(
path
);
return
r
;
}
if
(
r
==
-
ENOENT
)
continue
;
free
(
path
);
return
r
;
}
while
((
de
=
readdir
(
d
)))
{
if
(
de
->
d_name
[
0
]
==
'.'
)
continue
;
free
(
path
);
assert
(
de
->
d_name
[
0
]);
while
((
de
=
readdir
(
d
)))
{
if
(
de
->
d_name
[
0
]
==
'.'
)
continue
;
if
(
de
->
d_name
[
strlen
(
de
->
d_name
)
-
1
]
==
'~'
)
continue
;
assert
(
de
->
d_name
[
0
]);
if
(
asprintf
(
&
path
,
"%s/%s.wants/%s"
,
unit_path
(),
t
,
de
->
d_name
)
<
0
)
{
closedir
(
d
);
return
-
ENOMEM
;
}
if
(
de
->
d_name
[
strlen
(
de
->
d_name
)
-
1
]
==
'~'
)
continue
;
if
(
!
unit_name_is_valid
(
de
->
d_name
))
{
log_info
(
"Name of %s is not a valid unit name. Ignoring."
,
path
);
free
(
path
);
continue
;
}
if
(
asprintf
(
&
path
,
"%s/%s.wants/%s"
,
*
p
,
t
,
de
->
d_name
)
<
0
)
{
closedir
(
d
);
return
-
ENOMEM
;
}
r
=
unit_add_dependency_by_name
(
u
,
UNIT_WANTS
,
path
);
free
(
path
);
if
(
!
unit_name_is_valid
(
de
->
d_name
))
{
log_info
(
"Name of %s is not a valid unit name. Ignoring."
,
path
);
free
(
path
);
continue
;
}
if
(
r
<
0
)
{
closedir
(
d
);
return
r
;
r
=
unit_add_dependency_by_name
(
u
,
UNIT_WANTS
,
path
);
free
(
path
);
if
(
r
<
0
)
{
closedir
(
d
);
return
r
;
}
}
}
closedir
(
d
);
closedir
(
d
);
}
}
return
0
;
...
...
load-fragment.c
View file @
036643a2
...
...
@@ -1128,7 +1128,7 @@ static int load_from_path(Unit *u, const char *path) {
int
r
;
Set
*
symlink_names
;
FILE
*
f
;
char
*
filename
,
*
id
;
char
*
filename
=
NULL
,
*
id
;
sections
[
0
]
=
"Meta"
;
sections
[
1
]
=
section_table
[
u
->
meta
.
type
];
...
...
@@ -1137,18 +1137,56 @@ static int load_from_path(Unit *u, const char *path) {
if
(
!
(
symlink_names
=
set_new
(
string_hash_func
,
string_compare_func
)))
return
-
ENOMEM
;
/* Instead of opening the path right away, we manually
* follow all symlinks and add their name to our unit
* name set while doing so */
if
(
!
(
filename
=
path_make_absolute
(
path
,
unit_path
())))
{
r
=
-
ENOMEM
;
goto
finish
;
}
if
(
path_is_absolute
(
path
))
{
if
(
!
(
filename
=
strdup
(
path
)))
{
r
=
-
ENOMEM
;
goto
finish
;
}
if
((
r
=
open_follow
(
&
filename
,
&
f
,
symlink_names
,
&
id
))
<
0
)
{
free
(
filename
);
filename
=
NULL
;
if
((
r
=
open_follow
(
&
filename
,
&
f
,
symlink_names
,
&
id
))
<
0
)
{
if
(
r
==
-
ENOENT
)
r
=
0
;
/* returning 0 means: no suitable config file found */
if
(
r
!=
-
ENOENT
)
goto
finish
;
}
}
else
{
char
**
p
;
STRV_FOREACH
(
p
,
u
->
meta
.
manager
->
unit_path
)
{
/* Instead of opening the path right away, we manually
* follow all symlinks and add their name to our unit
* name set while doing so */
if
(
!
(
filename
=
path_make_absolute
(
path
,
*
p
)))
{
r
=
-
ENOMEM
;
goto
finish
;
}
if
((
r
=
open_follow
(
&
filename
,
&
f
,
symlink_names
,
&
id
))
<
0
)
{
char
*
sn
;
free
(
filename
);
filename
=
NULL
;
if
(
r
!=
-
ENOENT
)
goto
finish
;
/* Empty the symlink names for the next run */
while
((
sn
=
set_steal_first
(
symlink_names
)))
free
(
sn
);
continue
;
}
break
;
}
}
if
(
!
filename
)
{
r
=
0
;
/* returning 0 means: no suitable config file found */
goto
finish
;
}
...
...
manager.c
View file @
036643a2
...
...
@@ -70,6 +70,176 @@ static int manager_setup_signals(Manager *m) {
return
0
;
}
static
char
**
session_dirs
(
void
)
{
const
char
*
home
,
*
e
;
char
*
config_home
=
NULL
,
*
data_home
=
NULL
;
char
**
config_dirs
=
NULL
,
**
data_dirs
=
NULL
;
char
**
r
=
NULL
,
**
t
;
/* Implement the mechanisms defined in
*
* http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
*
* We look in both the config and the data dirs because we
* want to encourage that distributors ship their unit files
* as data, and allow overriding as configuration.
*/
home
=
getenv
(
"HOME"
);
if
((
e
=
getenv
(
"XDG_CONFIG_HOME"
)))
{
if
(
asprintf
(
&
config_home
,
"%s/systemd/session"
,
e
)
<
0
)
goto
fail
;
}
else
if
(
home
)
{
if
(
asprintf
(
&
config_home
,
"%s/.config/systemd/session"
,
home
)
<
0
)
goto
fail
;
}
if
((
e
=
getenv
(
"XDG_CONFIG_DIRS"
)))
config_dirs
=
strv_split
(
e
,
":"
);
else
config_dirs
=
strv_new
(
"/etc/xdg"
,
NULL
);
if
(
!
config_dirs
)
goto
fail
;
if
((
e
=
getenv
(
"XDG_DATA_HOME"
)))
{
if
(
asprintf
(
&
data_home
,
"%s/systemd/session"
,
e
)
<
0
)
goto
fail
;
}
else
if
(
home
)
{
if
(
asprintf
(
&
data_home
,
"%s/.local/share/systemd/session"
,
home
)
<
0
)
goto
fail
;
}
if
((
e
=
getenv
(
"XDG_DATA_DIRS"
)))
data_dirs
=
strv_split
(
e
,
":"
);
else
data_dirs
=
strv_new
(
"/usr/local/share"
,
"/usr/share"
,
NULL
);
if
(
!
data_dirs
)
goto
fail
;
/* Now merge everything we found. */
if
(
config_home
)
{
if
(
!
(
t
=
strv_append
(
r
,
config_home
)))
goto
fail
;
strv_free
(
r
);
r
=
t
;
}
if
(
!
(
t
=
strv_merge_concat
(
r
,
config_dirs
,
"/systemd/session"
)))
goto
finish
;
strv_free
(
r
);
r
=
t
;
if
(
!
(
t
=
strv_append
(
r
,
SESSION_CONFIG_UNIT_PATH
)))
goto
fail
;
strv_free
(
r
);
r
=
t
;
if
(
data_home
)
{
if
(
!
(
t
=
strv_append
(
r
,
data_home
)))
goto
fail
;
strv_free
(
r
);
r
=
t
;
}
if
(
!
(
t
=
strv_merge_concat
(
r
,
data_dirs
,
"/systemd/session"
)))
goto
fail
;
strv_free
(
r
);
r
=
t
;
if
(
!
(
t
=
strv_append
(
r
,
SESSION_DATA_UNIT_PATH
)))
goto
fail
;
strv_free
(
r
);
r
=
t
;
if
(
!
strv_path_make_absolute_cwd
(
r
))
goto
fail
;
finish:
free
(
config_home
);
strv_free
(
config_dirs
);
free
(
data_home
);
strv_free
(
data_dirs
);
return
r
;
fail:
strv_free
(
r
);
r
=
NULL
;
goto
finish
;
}
static
int
manager_find_paths
(
Manager
*
m
)
{
const
char
*
e
;
char
*
t
;
assert
(
m
);
/* First priority is whatever has been passed to us via env
* vars */
if
((
e
=
getenv
(
"SYSTEMD_UNIT_PATH"
)))
if
(
!
(
m
->
unit_path
=
split_path_and_make_absolute
(
e
)))
return
-
ENOMEM
;
if
(
strv_isempty
(
m
->
unit_path
))
{
/* Nothing is set, so let's figure something out. */
strv_free
(
m
->
unit_path
);
if
(
m
->
running_as
==
MANAGER_SESSION
)
{
if
(
!
(
m
->
unit_path
=
session_dirs
()))
return
-
ENOMEM
;
}
else
if
(
!
(
m
->
unit_path
=
strv_new
(
SYSTEM_CONFIG_UNIT_PATH
,
/* /etc/systemd/system/ */
SYSTEM_DATA_UNIT_PATH
,
/* /lib/systemd/system/ */
NULL
)))
return
-
ENOMEM
;
}
/* FIXME: This should probably look for MANAGER_INIT, and exclude MANAGER_SYSTEM */
if
(
m
->
running_as
!=
MANAGER_SESSION
)
{
/* /etc/init.d/ compativility does not matter to users */
if
((
e
=
getenv
(
"SYSTEMD_SYSVINIT_PATH"
)))
if
(
!
(
m
->
sysvinit_path
=
split_path_and_make_absolute
(
e
)))
return
-
ENOMEM
;
if
(
strv_isempty
(
m
->
sysvinit_path
))
{
strv_free
(
m
->
sysvinit_path
);
if
(
!
(
m
->
sysvinit_path
=
strv_new
(
SYSTEM_SYSVINIT_PATH
,
/* /etc/init.d/ */
NULL
)))
return
-
ENOMEM
;
}
}
strv_uniq
(
m
->
unit_path
);
strv_uniq
(
m
->
sysvinit_path
);
assert
(
!
strv_isempty
(
m
->
unit_path
));
if
(
!
(
t
=
strv_join
(
m
->
unit_path
,
"
\n\t
"
)))
return
-
ENOMEM
;
log_debug
(
"Looking for unit files in:
\n\t
%s"
,
t
);
free
(
t
);
if
(
!
strv_isempty
(
m
->
sysvinit_path
))
{
if
(
!
(
t
=
strv_join
(
m
->
sysvinit_path
,
"
\n\t
"
)))
return
-
ENOMEM
;
log_debug
(
"Looking for SysV init scripts in:
\n\t
%s"
,
t
);
free
(
t
);
}
else
log_debug
(
"Ignoring SysV init scripts."
);
return
0
;
}
Manager
*
manager_new
(
void
)
{
Manager
*
m
;
...
...
@@ -81,13 +251,16 @@ Manager* manager_new(void) {
else
if
(
getuid
()
==
0
)
m
->
running_as
=
MANAGER_SYSTEM
;
else
m
->
running_as
=
MANAGER_
U
SE
R
;
m
->
running_as
=
MANAGER_SE
SSION
;
log_debug
(
"systemd running in %s mode."
,
manager_running_as_to_string
(
m
->
running_as
));
m
->
signal_watch
.
fd
=
m
->
mount_watch
.
fd
=
m
->
udev_watch
.
fd
=
m
->
epoll_fd
=
-
1
;
m
->
current_job_id
=
1
;
/* start as id #1, so that we can leave #0 around as "null-like" value */
if
(
manager_find_paths
(
m
)
<
0
)
goto
fail
;
if
(
!
(
m
->
units
=
hashmap_new
(
string_hash_func
,
string_compare_func
)))
goto
fail
;
...
...
@@ -146,6 +319,9 @@ void manager_free(Manager *m) {
if
(
m
->
signal_watch
.
fd
>=
0
)
close_nointr
(
m
->
signal_watch
.
fd
);
strv_free
(
m
->
unit_path
);
strv_free
(
m
->
sysvinit_path
);
free
(
m
);
}
...
...
@@ -1360,7 +1536,7 @@ int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
static
const
char
*
const
manager_running_as_table
[
_MANAGER_RUNNING_AS_MAX
]
=
{
[
MANAGER_INIT
]
=
"init"
,
[
MANAGER_SYSTEM
]
=
"system"
,
[
MANAGER_
U
SE
R
]
=
"
u
se
r
"
[
MANAGER_SE
SSION
]
=
"se
ssion
"
};
DEFINE_STRING_TABLE_LOOKUP
(
manager_running_as
,
ManagerRunningAs
);
manager.h
View file @
036643a2
...
...
@@ -35,7 +35,7 @@ typedef struct Watch Watch;
typedef
enum
ManagerRunningAs
{
MANAGER_INIT
,
/* root and pid=1 */
MANAGER_SYSTEM
,
/* root and pid!=1 */
MANAGER_
U
SE
R
,
/* non-root */
MANAGER_SE
SSION
,
/* non-root */
_MANAGER_RUNNING_AS_MAX
,
_MANAGER_RUNNING_AS_INVALID
=
-
1
}
ManagerRunningAs
;
...
...
@@ -123,6 +123,9 @@ struct Manager {
Watch
signal_watch
;
char
**
unit_path
;
char
**
sysvinit_path
;
/* Data specific to the device subsystem */
struct
udev
*
udev
;
struct
udev_monitor
*
udev_monitor
;
...
...
unit.c
View file @
036643a2
...
...
@@ -972,16 +972,6 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name) {
return
0
;
}
const
char
*
unit_path
(
void
)
{
char
*
e
;
if
((
e
=
getenv
(
"UNIT_PATH"
)))
if
(
path_is_absolute
(
e
))
return
e
;
return
UNIT_PATH
;
}
int
set_unit_path
(
const
char
*
p
)
{
char
*
cwd
,
*
c
;
int
r
;
...
...
@@ -1002,7 +992,7 @@ int set_unit_path(const char *p) {
return
-
ENOMEM
;
}
if
(
setenv
(
"UNIT_PATH"
,
c
,
0
)
<
0
)
{
if
(
setenv
(
"
SYSTEMD_
UNIT_PATH"
,
c
,
0
)
<
0
)
{
r
=
-
errno
;
free
(
c
);
return
r
;
...
...
unit.h
View file @
036643a2
...
...
@@ -282,7 +282,6 @@ void unit_unwatch_timer(Unit *u, Watch *w);
bool
unit_job_is_applicable
(
Unit
*
u
,
JobType
j
);
const
char
*
unit_path
(
void
);
int
set_unit_path
(
const
char
*
p
);
char
*
unit_name_escape_path
(
const
char
*
prefix
,
const
char
*
path
,
const
char
*
suffix
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment