dahdi_cfg: Add semaphore to prevent parallel execution.
When dahdi is configured for fully dynamic configuration on a device and span basis via sysfs and udev it is possible for multiple instances of dahdi_cfg to be run in parallel on different spans. If this happens it is possible to see errors on the console that tone zones are already registered since the check for the existence of a tone zone and the re-registering needs to be atomic. dahdi_cfg will now prevent itself from running in parallel. Signed-off-by: Shaun Ruffell <sruffell@digium.com> Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
This commit is contained in:
parent
a4f79134c9
commit
9989b8779c
2
Makefile
2
Makefile
@ -168,7 +168,7 @@ $(LTZ_SO): $(LTZ_SO_OBJS)
|
|||||||
$(CC) $(CFLAGS) -shared -Wl,-soname,$(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) -o $@ $^ -lm
|
$(CC) $(CFLAGS) -shared -Wl,-soname,$(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) -o $@ $^ -lm
|
||||||
|
|
||||||
dahdi_cfg: $(LTZ_A)
|
dahdi_cfg: $(LTZ_A)
|
||||||
dahdi_cfg: LIBS+=-lm
|
dahdi_cfg: LIBS+=-lm -lpthread
|
||||||
dahdi_pcap:
|
dahdi_pcap:
|
||||||
$(CC) $(CFLAGS) dahdi_pcap.c -lpcap -o $@ $<
|
$(CC) $(CFLAGS) dahdi_pcap.c -lpcap -o $@ $<
|
||||||
|
|
||||||
|
58
dahdi_cfg.c
58
dahdi_cfg.c
@ -35,6 +35,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <semaphore.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -794,7 +796,7 @@ static int setfiftysixkhdlc(char *keyword, char *args)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apply_fiftysix(void)
|
static int apply_fiftysix(void)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int rate;
|
int rate;
|
||||||
@ -808,7 +810,7 @@ static void apply_fiftysix(void)
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Couldn't open /dev/dahdi/channel: %s\n",
|
"Couldn't open /dev/dahdi/channel: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
exit(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(chanfd, DAHDI_SPECIFY, &x)) {
|
if (ioctl(chanfd, DAHDI_SPECIFY, &x)) {
|
||||||
@ -829,6 +831,7 @@ static void apply_fiftysix(void)
|
|||||||
}
|
}
|
||||||
close(chanfd);
|
close(chanfd);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setechocan(char *keyword, char *args)
|
static int setechocan(char *keyword, char *args)
|
||||||
@ -1530,6 +1533,9 @@ int main(int argc, char *argv[])
|
|||||||
char *buf;
|
char *buf;
|
||||||
char *key, *value;
|
char *key, *value;
|
||||||
int x,found;
|
int x,found;
|
||||||
|
sem_t *lock = SEM_FAILED;
|
||||||
|
const char *SEM_NAME = "dahdi_cfg";
|
||||||
|
int exit_code = 0;
|
||||||
|
|
||||||
while((c = getopt(argc, argv, "fthc:vsd::C:S:")) != -1) {
|
while((c = getopt(argc, argv, "fthc:vsd::C:S:")) != -1) {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
@ -1656,6 +1662,20 @@ finish:
|
|||||||
printf("About to open Master device\n");
|
printf("About to open Master device\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock = sem_open(SEM_NAME, O_CREAT, O_RDWR, 1);
|
||||||
|
if (SEM_FAILED == lock) {
|
||||||
|
error("Unable to create 'dahdi_cfg' mutex.\n");
|
||||||
|
exit_code = 1;
|
||||||
|
goto release_sem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-1 == sem_wait(lock)) {
|
||||||
|
error("Failed to wait for dahdi_cfg mutex.\n");
|
||||||
|
exit_code = 1;
|
||||||
|
goto release_sem;
|
||||||
|
}
|
||||||
|
|
||||||
for (x=0;x<numdynamic;x++) {
|
for (x=0;x<numdynamic;x++) {
|
||||||
/* destroy them all */
|
/* destroy them all */
|
||||||
ioctl(fd, DAHDI_DYNAMIC_DESTROY, &zds[x]);
|
ioctl(fd, DAHDI_DYNAMIC_DESTROY, &zds[x]);
|
||||||
@ -1667,10 +1687,12 @@ finish:
|
|||||||
if (ioctl(fd, DAHDI_SHUTDOWN, &lc[x].span)) {
|
if (ioctl(fd, DAHDI_SHUTDOWN, &lc[x].span)) {
|
||||||
fprintf(stderr, "DAHDI shutdown failed: %s\n", strerror(errno));
|
fprintf(stderr, "DAHDI shutdown failed: %s\n", strerror(errno));
|
||||||
close(fd);
|
close(fd);
|
||||||
exit(1);
|
exit_code = 1;
|
||||||
|
goto release_sem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exit(1);
|
exit_code = 1;
|
||||||
|
goto release_sem;
|
||||||
}
|
}
|
||||||
for (x=0;x<spans;x++) {
|
for (x=0;x<spans;x++) {
|
||||||
if (only_span && lc[x].span != only_span)
|
if (only_span && lc[x].span != only_span)
|
||||||
@ -1678,14 +1700,16 @@ finish:
|
|||||||
if (ioctl(fd, DAHDI_SPANCONFIG, lc + x)) {
|
if (ioctl(fd, DAHDI_SPANCONFIG, lc + x)) {
|
||||||
fprintf(stderr, "DAHDI_SPANCONFIG failed on span %d: %s (%d)\n", lc[x].span, strerror(errno), errno);
|
fprintf(stderr, "DAHDI_SPANCONFIG failed on span %d: %s (%d)\n", lc[x].span, strerror(errno), errno);
|
||||||
close(fd);
|
close(fd);
|
||||||
exit(1);
|
exit_code = 1;
|
||||||
|
goto release_sem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (x=0;x<numdynamic;x++) {
|
for (x=0;x<numdynamic;x++) {
|
||||||
if (ioctl(fd, DAHDI_DYNAMIC_CREATE, &zds[x])) {
|
if (ioctl(fd, DAHDI_DYNAMIC_CREATE, &zds[x])) {
|
||||||
fprintf(stderr, "DAHDI dynamic span creation failed: %s\n", strerror(errno));
|
fprintf(stderr, "DAHDI dynamic span creation failed: %s\n", strerror(errno));
|
||||||
close(fd);
|
close(fd);
|
||||||
exit(1);
|
exit_code = 1;
|
||||||
|
goto release_sem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
|
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
|
||||||
@ -1810,7 +1834,8 @@ finish:
|
|||||||
" to channel 16 of an E1 CAS span\n");
|
" to channel 16 of an E1 CAS span\n");
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
exit(1);
|
exit_code = 1;
|
||||||
|
goto release_sem;
|
||||||
}
|
}
|
||||||
|
|
||||||
ae[x].chan = x;
|
ae[x].chan = x;
|
||||||
@ -1821,7 +1846,8 @@ finish:
|
|||||||
if (ioctl(fd, DAHDI_ATTACH_ECHOCAN, &ae[x])) {
|
if (ioctl(fd, DAHDI_ATTACH_ECHOCAN, &ae[x])) {
|
||||||
fprintf(stderr, "DAHDI_ATTACH_ECHOCAN failed on channel %d: %s (%d)\n", x, strerror(errno), errno);
|
fprintf(stderr, "DAHDI_ATTACH_ECHOCAN failed on channel %d: %s (%d)\n", x, strerror(errno), errno);
|
||||||
close(fd);
|
close(fd);
|
||||||
exit(1);
|
exit_code = 1;
|
||||||
|
goto release_sem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0 == numzones) {
|
if (0 == numzones) {
|
||||||
@ -1848,7 +1874,8 @@ finish:
|
|||||||
if (ioctl(fd, DAHDI_DEFAULTZONE, &deftonezone)) {
|
if (ioctl(fd, DAHDI_DEFAULTZONE, &deftonezone)) {
|
||||||
fprintf(stderr, "DAHDI_DEFAULTZONE failed: %s (%d)\n", strerror(errno), errno);
|
fprintf(stderr, "DAHDI_DEFAULTZONE failed: %s (%d)\n", strerror(errno), errno);
|
||||||
close(fd);
|
close(fd);
|
||||||
exit(1);
|
exit_code = 1;
|
||||||
|
goto release_sem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (x=0;x<spans;x++) {
|
for (x=0;x<spans;x++) {
|
||||||
@ -1857,9 +1884,16 @@ finish:
|
|||||||
if (ioctl(fd, DAHDI_STARTUP, &lc[x].span)) {
|
if (ioctl(fd, DAHDI_STARTUP, &lc[x].span)) {
|
||||||
fprintf(stderr, "DAHDI startup failed: %s\n", strerror(errno));
|
fprintf(stderr, "DAHDI startup failed: %s\n", strerror(errno));
|
||||||
close(fd);
|
close(fd);
|
||||||
exit(1);
|
exit_code = 1;
|
||||||
|
goto release_sem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apply_fiftysix();
|
exit_code = apply_fiftysix();
|
||||||
exit(0);
|
|
||||||
|
release_sem:
|
||||||
|
if (SEM_FAILED != lock) {
|
||||||
|
sem_post(lock);
|
||||||
|
sem_unlink(SEM_NAME);
|
||||||
|
}
|
||||||
|
exit(exit_code);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user