Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
84e9e197
Commit
84e9e197
authored
Dec 30, 2013
by
Andrey Mazo
Committed by
Serge Hallyn
Jan 01, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use pthread_atfork() to unlock mutexes after fork()
Signed-off-by:
Andrey Mazo
<
mazo@telum.ru
>
Signed-off-by:
Serge Hallyn
<
serge.hallyn@ubuntu.com
>
parent
f2363e38
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
24 additions
and
22 deletions
+24
-22
Makefile.am
src/lxc/Makefile.am
+2
-1
attach.c
src/lxc/attach.c
+0
-2
bdev.c
src/lxc/bdev.c
+0
-13
lxccontainer.c
src/lxc/lxccontainer.c
+0
-4
lxclock.c
src/lxc/lxclock.c
+22
-1
monitor.c
src/lxc/monitor.c
+0
-1
No files found.
src/lxc/Makefile.am
View file @
84e9e197
...
@@ -135,9 +135,10 @@ AM_CFLAGS += -DHAVE_SECCOMP
...
@@ -135,9 +135,10 @@ AM_CFLAGS += -DHAVE_SECCOMP
liblxc_so_SOURCES
+=
seccomp.c
liblxc_so_SOURCES
+=
seccomp.c
endif
endif
liblxc_so_CFLAGS
=
-fPIC
-DPIC
$(AM_CFLAGS)
liblxc_so_CFLAGS
=
-fPIC
-DPIC
$(AM_CFLAGS)
-pthread
liblxc_so_LDFLAGS
=
\
liblxc_so_LDFLAGS
=
\
-pthread
\
-shared
\
-shared
\
-Wl
,-soname,liblxc.so.
$
(
firstword
$
(
subst ., ,
$(VERSION)
))
-Wl
,-soname,liblxc.so.
$
(
firstword
$
(
subst ., ,
$(VERSION)
))
...
...
src/lxc/attach.c
View file @
84e9e197
...
@@ -497,7 +497,6 @@ char *lxc_attach_getpwshell(uid_t uid)
...
@@ -497,7 +497,6 @@ char *lxc_attach_getpwshell(uid_t uid)
NULL
NULL
};
};
process_unlock
();
// we're no longer sharing
close
(
pipes
[
0
]);
close
(
pipes
[
0
]);
/* we want to capture stdout */
/* we want to capture stdout */
...
@@ -790,7 +789,6 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
...
@@ -790,7 +789,6 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
return
-
1
;
return
-
1
;
}
}
process_unlock
();
// we're no longer sharing
/* first subprocess begins here, we close the socket that is for the
/* first subprocess begins here, we close the socket that is for the
* initial thread
* initial thread
*/
*/
...
...
src/lxc/bdev.c
View file @
84e9e197
...
@@ -73,7 +73,6 @@ static int do_rsync(const char *src, const char *dest)
...
@@ -73,7 +73,6 @@ static int do_rsync(const char *src, const char *dest)
if
(
pid
>
0
)
if
(
pid
>
0
)
return
wait_for_pid
(
pid
);
return
wait_for_pid
(
pid
);
process_unlock
();
// we're no longer sharing
l
=
strlen
(
src
)
+
2
;
l
=
strlen
(
src
)
+
2
;
s
=
malloc
(
l
);
s
=
malloc
(
l
);
if
(
!
s
)
if
(
!
s
)
...
@@ -198,7 +197,6 @@ static int do_mkfs(const char *path, const char *fstype)
...
@@ -198,7 +197,6 @@ static int do_mkfs(const char *path, const char *fstype)
if
(
pid
>
0
)
if
(
pid
>
0
)
return
wait_for_pid
(
pid
);
return
wait_for_pid
(
pid
);
process_unlock
();
// we're no longer sharing
// If the file is not a block device, we don't want mkfs to ask
// If the file is not a block device, we don't want mkfs to ask
// us about whether to proceed.
// us about whether to proceed.
close
(
0
);
close
(
0
);
...
@@ -283,7 +281,6 @@ static int detect_fs(struct bdev *bdev, char *type, int len)
...
@@ -283,7 +281,6 @@ static int detect_fs(struct bdev *bdev, char *type, int len)
return
ret
;
return
ret
;
}
}
process_unlock
();
// we're no longer sharing
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
exit
(
1
);
exit
(
1
);
...
@@ -575,7 +572,6 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
...
@@ -575,7 +572,6 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
if
(
!
pid
)
{
if
(
!
pid
)
{
char
dev
[
MAXPATHLEN
];
char
dev
[
MAXPATHLEN
];
process_unlock
();
// we're no longer sharing
ret
=
snprintf
(
dev
,
MAXPATHLEN
,
"%s/%s"
,
zfsroot
,
nname
);
ret
=
snprintf
(
dev
,
MAXPATHLEN
,
"%s/%s"
,
zfsroot
,
nname
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
exit
(
1
);
exit
(
1
);
...
@@ -599,7 +595,6 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
...
@@ -599,7 +595,6 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
if
((
pid
=
fork
())
<
0
)
if
((
pid
=
fork
())
<
0
)
return
-
1
;
return
-
1
;
if
(
!
pid
)
{
if
(
!
pid
)
{
process_unlock
();
// we're no longer sharing
execlp
(
"zfs"
,
"zfs"
,
"destroy"
,
path1
,
NULL
);
execlp
(
"zfs"
,
"zfs"
,
"destroy"
,
path1
,
NULL
);
exit
(
1
);
exit
(
1
);
}
}
...
@@ -610,7 +605,6 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
...
@@ -610,7 +605,6 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
if
((
pid
=
fork
())
<
0
)
if
((
pid
=
fork
())
<
0
)
return
-
1
;
return
-
1
;
if
(
!
pid
)
{
if
(
!
pid
)
{
process_unlock
();
// we're no longer sharing
execlp
(
"zfs"
,
"zfs"
,
"snapshot"
,
path1
,
NULL
);
execlp
(
"zfs"
,
"zfs"
,
"snapshot"
,
path1
,
NULL
);
exit
(
1
);
exit
(
1
);
}
}
...
@@ -621,7 +615,6 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
...
@@ -621,7 +615,6 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
if
((
pid
=
fork
())
<
0
)
if
((
pid
=
fork
())
<
0
)
return
-
1
;
return
-
1
;
if
(
!
pid
)
{
if
(
!
pid
)
{
process_unlock
();
// we're no longer sharing
execlp
(
"zfs"
,
"zfs"
,
"clone"
,
option
,
path1
,
path2
,
NULL
);
execlp
(
"zfs"
,
"zfs"
,
"clone"
,
option
,
path1
,
path2
,
NULL
);
exit
(
1
);
exit
(
1
);
}
}
...
@@ -672,7 +665,6 @@ static int zfs_destroy(struct bdev *orig)
...
@@ -672,7 +665,6 @@ static int zfs_destroy(struct bdev *orig)
if
(
pid
)
if
(
pid
)
return
wait_for_pid
(
pid
);
return
wait_for_pid
(
pid
);
process_unlock
();
// we're no longer sharing
if
(
!
zfs_list_entry
(
orig
->
src
,
output
,
MAXPATHLEN
))
{
if
(
!
zfs_list_entry
(
orig
->
src
,
output
,
MAXPATHLEN
))
{
ERROR
(
"Error: zfs entry for %s not found"
,
orig
->
src
);
ERROR
(
"Error: zfs entry for %s not found"
,
orig
->
src
);
return
-
1
;
return
-
1
;
...
@@ -717,7 +709,6 @@ static int zfs_create(struct bdev *bdev, const char *dest, const char *n,
...
@@ -717,7 +709,6 @@ static int zfs_create(struct bdev *bdev, const char *dest, const char *n,
if
(
pid
)
if
(
pid
)
return
wait_for_pid
(
pid
);
return
wait_for_pid
(
pid
);
process_unlock
();
// we're no longer sharing
char
dev
[
MAXPATHLEN
];
char
dev
[
MAXPATHLEN
];
ret
=
snprintf
(
dev
,
MAXPATHLEN
,
"%s/%s"
,
zfsroot
,
n
);
ret
=
snprintf
(
dev
,
MAXPATHLEN
,
"%s/%s"
,
zfsroot
,
n
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
...
@@ -862,7 +853,6 @@ static int do_lvm_create(const char *path, unsigned long size, const char *thinp
...
@@ -862,7 +853,6 @@ static int do_lvm_create(const char *path, unsigned long size, const char *thinp
if
(
pid
>
0
)
if
(
pid
>
0
)
return
wait_for_pid
(
pid
);
return
wait_for_pid
(
pid
);
process_unlock
();
// we're no longer sharing
// lvcreate default size is in M, not bytes.
// lvcreate default size is in M, not bytes.
ret
=
snprintf
(
sz
,
24
,
"%lu"
,
size
/
1000000
);
ret
=
snprintf
(
sz
,
24
,
"%lu"
,
size
/
1000000
);
if
(
ret
<
0
||
ret
>=
24
)
if
(
ret
<
0
||
ret
>=
24
)
...
@@ -922,7 +912,6 @@ static int lvm_snapshot(const char *orig, const char *path, unsigned long size)
...
@@ -922,7 +912,6 @@ static int lvm_snapshot(const char *orig, const char *path, unsigned long size)
if
(
pid
>
0
)
if
(
pid
>
0
)
return
wait_for_pid
(
pid
);
return
wait_for_pid
(
pid
);
process_unlock
();
// we're no longer sharing
// lvcreate default size is in M, not bytes.
// lvcreate default size is in M, not bytes.
ret
=
snprintf
(
sz
,
24
,
"%lu"
,
size
/
1000000
);
ret
=
snprintf
(
sz
,
24
,
"%lu"
,
size
/
1000000
);
if
(
ret
<
0
||
ret
>=
24
)
if
(
ret
<
0
||
ret
>=
24
)
...
@@ -1056,7 +1045,6 @@ static int lvm_destroy(struct bdev *orig)
...
@@ -1056,7 +1045,6 @@ static int lvm_destroy(struct bdev *orig)
if
((
pid
=
fork
())
<
0
)
if
((
pid
=
fork
())
<
0
)
return
-
1
;
return
-
1
;
if
(
!
pid
)
{
if
(
!
pid
)
{
process_unlock
();
// we're no longer sharing
execlp
(
"lvremove"
,
"lvremove"
,
"-f"
,
orig
->
src
,
NULL
);
execlp
(
"lvremove"
,
"lvremove"
,
"-f"
,
orig
->
src
,
NULL
);
exit
(
1
);
exit
(
1
);
}
}
...
@@ -2092,7 +2080,6 @@ struct bdev *bdev_copy(const char *src, const char *oldname, const char *cname,
...
@@ -2092,7 +2080,6 @@ struct bdev *bdev_copy(const char *src, const char *oldname, const char *cname,
return
new
;
return
new
;
}
}
process_unlock
();
// we're no longer sharing
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
{
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
{
SYSERROR
(
"unshare CLONE_NEWNS"
);
SYSERROR
(
"unshare CLONE_NEWNS"
);
exit
(
1
);
exit
(
1
);
...
...
src/lxc/lxccontainer.c
View file @
84e9e197
...
@@ -601,7 +601,6 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv
...
@@ -601,7 +601,6 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv
if
(
pid
!=
0
)
if
(
pid
!=
0
)
return
wait_on_daemonized_start
(
c
,
pid
);
return
wait_on_daemonized_start
(
c
,
pid
);
process_unlock
();
// we're no longer sharing
/* second fork to be reparented by init */
/* second fork to be reparented by init */
pid
=
fork
();
pid
=
fork
();
if
(
pid
<
0
)
{
if
(
pid
<
0
)
{
...
@@ -839,7 +838,6 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet
...
@@ -839,7 +838,6 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet
char
**
newargv
;
char
**
newargv
;
struct
lxc_conf
*
conf
=
c
->
lxc_conf
;
struct
lxc_conf
*
conf
=
c
->
lxc_conf
;
process_unlock
();
// we're no longer sharing
if
(
quiet
)
{
if
(
quiet
)
{
close
(
0
);
close
(
0
);
close
(
1
);
close
(
1
);
...
@@ -1236,7 +1234,6 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
...
@@ -1236,7 +1234,6 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
if
(
pid
==
0
)
{
// child
if
(
pid
==
0
)
{
// child
struct
bdev
*
bdev
=
NULL
;
struct
bdev
*
bdev
=
NULL
;
process_unlock
();
// we're no longer sharing
if
(
!
(
bdev
=
do_bdev_create
(
c
,
bdevtype
,
specs
)))
{
if
(
!
(
bdev
=
do_bdev_create
(
c
,
bdevtype
,
specs
)))
{
ERROR
(
"Error creating backing store type %s for %s"
,
ERROR
(
"Error creating backing store type %s for %s"
,
bdevtype
?
bdevtype
:
"(none)"
,
c
->
name
);
bdevtype
?
bdevtype
:
"(none)"
,
c
->
name
);
...
@@ -2328,7 +2325,6 @@ static int clone_update_rootfs(struct lxc_container *c0,
...
@@ -2328,7 +2325,6 @@ static int clone_update_rootfs(struct lxc_container *c0,
if
(
pid
>
0
)
if
(
pid
>
0
)
return
wait_for_pid
(
pid
);
return
wait_for_pid
(
pid
);
process_unlock
();
// we're no longer sharing
bdev
=
bdev_init
(
c
->
lxc_conf
->
rootfs
.
path
,
c
->
lxc_conf
->
rootfs
.
mount
,
NULL
);
bdev
=
bdev_init
(
c
->
lxc_conf
->
rootfs
.
path
,
c
->
lxc_conf
->
rootfs
.
mount
,
NULL
);
if
(
!
bdev
)
if
(
!
bdev
)
exit
(
1
);
exit
(
1
);
...
...
src/lxc/lxclock.c
View file @
84e9e197
...
@@ -89,7 +89,7 @@ void unlock_mutex(pthread_mutex_t *l)
...
@@ -89,7 +89,7 @@ void unlock_mutex(pthread_mutex_t *l)
int
ret
;
int
ret
;
if
((
ret
=
pthread_mutex_unlock
(
l
))
!=
0
)
{
if
((
ret
=
pthread_mutex_unlock
(
l
))
!=
0
)
{
fprintf
(
stderr
,
"pthread_mutex_lock returned:%d %s"
,
ret
,
strerror
(
ret
));
fprintf
(
stderr
,
"pthread_mutex_
un
lock returned:%d %s"
,
ret
,
strerror
(
ret
));
dump_stacktrace
();
dump_stacktrace
();
exit
(
1
);
exit
(
1
);
}
}
...
@@ -317,6 +317,21 @@ void process_unlock(void)
...
@@ -317,6 +317,21 @@ void process_unlock(void)
unlock_mutex
(
&
thread_mutex
);
unlock_mutex
(
&
thread_mutex
);
}
}
/* One thread can do fork() while another one is holding a mutex.
* There is only one thread in child just after the fork(), so noone will ever release that mutex.
* We setup a "child" fork handler to unlock the mutex just after the fork().
* For several mutex types, unlocking an unlocked mutex can lead to undefined behavior.
* One way to deal with it is to setup "prepare" fork handler
* to lock the mutex before fork() and both "parent" and "child" fork handlers
* to unlock the mutex.
* This forbids doing fork() while explicitly holding the lock.
*/
__attribute__
((
constructor
))
static
void
process_lock_setup_atfork
(
void
)
{
pthread_atfork
(
process_lock
,
process_unlock
,
process_unlock
);
}
/* Protects static const values inside the lxc_global_config_value funtion */
/* Protects static const values inside the lxc_global_config_value funtion */
void
static_lock
(
void
)
void
static_lock
(
void
)
{
{
...
@@ -328,6 +343,12 @@ void static_unlock(void)
...
@@ -328,6 +343,12 @@ void static_unlock(void)
unlock_mutex
(
&
static_mutex
);
unlock_mutex
(
&
static_mutex
);
}
}
__attribute__
((
constructor
))
static
void
static_lock_setup_atfork
(
void
)
{
pthread_atfork
(
static_lock
,
static_unlock
,
static_unlock
);
}
int
container_mem_lock
(
struct
lxc_container
*
c
)
int
container_mem_lock
(
struct
lxc_container
*
c
)
{
{
return
lxclock
(
c
->
privlock
,
0
);
return
lxclock
(
c
->
privlock
,
0
);
...
...
src/lxc/monitor.c
View file @
84e9e197
...
@@ -299,7 +299,6 @@ int lxc_monitord_spawn(const char *lxcpath)
...
@@ -299,7 +299,6 @@ int lxc_monitord_spawn(const char *lxcpath)
return
0
;
return
0
;
}
}
process_unlock
();
// we're no longer sharing
if
(
pipe
(
pipefd
)
<
0
)
{
if
(
pipe
(
pipefd
)
<
0
)
{
SYSERROR
(
"failed to create pipe"
);
SYSERROR
(
"failed to create pipe"
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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