summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTzafrir Cohen <tzafrir.cohen@xorcom.com>2009-10-21 14:30:32 +0000
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>2009-10-21 14:30:32 +0000
commit939ffb7577ce08dfc552ce0c112e9d51fd2b4519 (patch)
treeb109d414522a83530be7999b0aa9d13a61f5c739
parentee453cb6ce6863f1b3f87888bf4572d1f6455cb3 (diff)
Fix XPP_HOTPLUG_DAHDI: logic; end of init.d script
'Hotplug mode' was introduced in r7335. * The logic in the script was broken. - Negative logic is not such a grand idea to start with. * Interactive invocation of init.d ends when expected and not sooner. This change makes waitfor_xpds wait longer. Rather than waiting for all the Astribanks to load, it will now wait until the initialization of dahdi from the Astribanks hook script is run. This allows running e.g.: /etc/init.d/dahdi start; /etc/init.d/asterisk start It also means that 'astribank_is_starting' is actually used as a semaphore and not only as stamp file. As before, those changes have no effect if hotplug mode is not explicitly enabled (setting 'XPP_HOTPLUG_DAHDI=yes' in init.conf). git-svn-id: http://svn.asterisk.org/svn/dahdi/tools/trunk@7409 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rwxr-xr-xdahdi.init24
-rwxr-xr-xxpp/astribank_hook9
-rw-r--r--xpp/astribank_is_starting.826
-rw-r--r--xpp/astribank_is_starting.c72
-rwxr-xr-xxpp/waitfor_xpds18
5 files changed, 131 insertions, 18 deletions
diff --git a/dahdi.init b/dahdi.init
index a5ed780..5730c3b 100755
--- a/dahdi.init
+++ b/dahdi.init
@@ -86,10 +86,13 @@ unload_module() {
rmmod $module
}
-# In (xpp) hotplug mode, if we're called from udev, skip loading
-# modules:
-hotplug_skip_modprobe() {
- if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" = '' ]
+# In (xpp) hotplug mode, the init script is also executed from the
+# hotplug hook. In that case it should not attempt to loade modules.
+#
+# This function only retunrs false (1) if we're in hotplug mode and
+# coming from the hotplug hook script.
+hotplug_should_load_modules() {
+ if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" != '' ]
then
return 1
fi
@@ -97,11 +100,14 @@ hotplug_skip_modprobe() {
}
# In (xpp) hotplug mode: quit after we loaded modules.
-# Make sure that this is only called if there is an Astribank on the
-# system, which will call the rest of the script from the
-# astribank_hook.
+#
+# In hotplug mode, the main run should end here, whereas the rest of the
+# script should be finished by the instance running from the hook.
+# Note that we only get here if there are actually Astribanks on the
+# system (otherwise noone will trigger the run of the hotplug hook
+# script).
hotplug_exit_after_load() {
- if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" != '' ]
+ if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" = '' ]
then
exit 0
fi
@@ -207,7 +213,7 @@ RETVAL=0
# See how we were called.
case "$1" in
start)
- if ! hotplug_skip_modprobe; then
+ if hotplug_should_load_modules; then
load_modules
fi
diff --git a/xpp/astribank_hook b/xpp/astribank_hook
index 8c5bea8..dc55d14 100755
--- a/xpp/astribank_hook
+++ b/xpp/astribank_hook
@@ -29,7 +29,11 @@ fi
export XPPORDER_CONF="$dahdi_conf/xpp_order"
if [ ! -r "$XPPORDER_CONF" ]; then
- echo "Skip($ACTION): No '$XPPORDER_CONF'" | $LOGGER
+ (
+ echo "Skip($ACTION): No '$XPPORDER_CONF'"
+ echo "Removing uneeded startup semaphore"
+ astribank_is_starting -v -r 2>&1
+ ) 2>&1 | $LOGGER
exit 0
fi
export DAHDI_CFG_CMD="dahdi_cfg -c $dahdi_conf/system.conf"
@@ -73,6 +77,9 @@ start_dahdi() {
if [ -x "$dir/twinstar_hook" ]; then
"$dir/twinstar_hook"
fi
+ # Finished astribanks
+ echo "Removing semaphore"
+ astribank_is_starting -v -r
}
case "$ACTION" in
diff --git a/xpp/astribank_is_starting.8 b/xpp/astribank_is_starting.8
index 205e498..55db6f6 100644
--- a/xpp/astribank_is_starting.8
+++ b/xpp/astribank_is_starting.8
@@ -3,9 +3,9 @@
.SH NAME
astribank_is_starting \- Mark / check is a Xorcom Astribank (xpp) is starting
.SH SYNOPSIS
-.B astribank_is_starting [-d] <-a|-r>
+.B astribank_is_starting [-d] [-v] [-t \fItimeout\fB] <-a|-r|-w>
-.B astribank_is_starting [-d]
+.B astribank_is_starting [-d] [-v]
.B astribank_is_starting -h
@@ -29,11 +29,28 @@ Set the mark. Should return 0 unless there's an error.
Reset the mark. Should return 0 unless there's an error.
.RE
+.BI -t timeout
+.RS
+.B Timeout.
+Set the timeout value for the \fB-w\fR option. Default is 60 seconds.
+.RE
+
+.B -w
+.RS
+.B Wait.
+Wait for mark to be reset. Should return 0 unless there's an error.
+.RE
+
Without -a or -r: return 0 if the mark has been set, or a non-zero value
otherwise.
.B -d
.RS
+Print debug information to stderr.
+.RE
+
+.B -v
+.RS
Verbose execution.
.RE
@@ -65,6 +82,11 @@ Q: Why do you use a semaphore?
A: because, unlike the filesystem, it is writable at any given time.
+.SH BUGS
+Option ordering matter. The \fB-v\fR and \fB-d\fR options should preceed
+the actions (\fB-a\fR, \fB-r\fR and \fB-w\fR).
+The \fB-t\fItimeout\fR option should preceed the \fB-w\fR option.
+
.SH SEE ALSO
semctl(3)
diff --git a/xpp/astribank_is_starting.c b/xpp/astribank_is_starting.c
index 3018904..9a1552b 100644
--- a/xpp/astribank_is_starting.c
+++ b/xpp/astribank_is_starting.c
@@ -10,10 +10,13 @@
static char *progname;
static const key_t key_astribanks = 0xAB11A0;
static int debug;
+static int verbose;
+static int timeout_seconds = 60;
+
static void usage(void)
{
- fprintf(stderr, "Usage: %s [-d] [-a] [-r]\n", progname);
+ fprintf(stderr, "Usage: %s [-d] [-t <seconds>] [-a|-r|-w]\n", progname);
exit(1);
}
@@ -41,6 +44,8 @@ static int absem_touch(void)
}
if(debug)
fprintf(stderr, "%s: touched absem\n", progname);
+ if(verbose)
+ printf("Astribanks initialization is starting\n");
return 0;
}
@@ -63,6 +68,47 @@ static int absem_remove(void)
}
if(debug)
fprintf(stderr, "%s: removed absem\n", progname);
+ if(verbose)
+ printf("Astribanks initialization is done\n");
+ return 0;
+}
+
+static int absem_wait(void)
+{
+ int absem;
+ struct sembuf sops;
+ long now;
+ long start_wait;
+ struct timespec timeout;
+
+ if((absem = absem_get(0)) < 0) {
+ perror(__FUNCTION__);
+ return absem;
+ }
+ sops.sem_num = 0;
+ sops.sem_op = -1;
+ sops.sem_flg = 0;
+ start_wait = time(NULL);
+ timeout.tv_sec = timeout_seconds;
+ timeout.tv_nsec = 0;
+ if(semtimedop(absem, &sops, 1, &timeout) < 0) {
+ switch(errno) {
+ case EIDRM: /* Removed -- OK */
+ break;
+ case EAGAIN: /* Timeout -- Report */
+ fprintf(stderr, "Astribanks waiting timed out\n");
+ return -errno;
+ default: /* Unexpected errors */
+ perror("semop");
+ return -errno;
+ }
+ /* fall-thgough */
+ }
+ now = time(NULL);
+ if(debug)
+ fprintf(stderr, "%s: waited on absem %d seconds\n", progname, now - start_wait);
+ if(verbose)
+ printf("Finished after %d seconds\n", now - start_wait);
return 0;
}
@@ -77,17 +123,20 @@ static int absem_detected(void)
}
if(debug)
fprintf(stderr, "%s: absem exists\n", progname);
+ if(verbose)
+ printf("Astribanks are initializing...\n");
return 0;
}
int main(int argc, char *argv[])
{
- const char options[] = "darh";
+ const char options[] = "dvarwt:h";
int val;
progname = argv[0];
while (1) {
int c;
+ int t;
c = getopt (argc, argv, options);
if (c == -1)
@@ -97,6 +146,19 @@ int main(int argc, char *argv[])
case 'd':
debug++;
break;
+ case 'v':
+ verbose++;
+ break;
+ case 't':
+ t = atoi(optarg);
+ if(t <= 0) {
+ fprintf(stderr,
+ "%s: -t expect a positive number of seconds: '%s'\n",
+ progname, optarg);
+ usage();
+ }
+ timeout_seconds = t;
+ break;
case 'a':
if((val = absem_touch()) < 0) {
fprintf(stderr, "%s: Add failed: %d\n", progname, val);
@@ -109,6 +171,12 @@ int main(int argc, char *argv[])
return 1;
}
return 0;
+ case 'w':
+ if((val = absem_wait()) < 0) {
+ fprintf(stderr, "%s: Wait failed: %d\n", progname, val);
+ return 1;
+ }
+ return 0;
case 'h':
default:
fprintf(stderr, "Unknown option '%c'\n", c);
diff --git a/xpp/waitfor_xpds b/xpp/waitfor_xpds
index 7caa981..6bee5f2 100755
--- a/xpp/waitfor_xpds
+++ b/xpp/waitfor_xpds
@@ -29,6 +29,8 @@ set -e
mydir=`dirname $0`
PATH="${mydir}:${PATH}"
+[ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf
+
ab_list() {
# Only check /sys info (don't use /proc anymore).
ab=`find /sys/bus/astribanks/devices/xbus-*/ -name waitfor_xpds 2> /dev/null || :`
@@ -45,7 +47,7 @@ if ! astribank_is_starting="`which astribank_is_starting 2>/dev/null`"; then
exit 0
fi
if [ "`$dahdi_hardware | grep xpp_usb`" != "" ]; then
- astribank_is_starting -a
+ astribank_is_starting -v -a
fi
if ! astribank_is_starting; then
exit 0
@@ -67,7 +69,7 @@ done
echo ""
# Wait for device to stabilize and XPD's to finish initalizations
-echo 1>&2 "Astribanks initalization "
+echo 1>&2 "Astribanks initializing spans"
while
if ! ab=`ab_list`; then
exit 1
@@ -78,5 +80,13 @@ do
cat $ab
done
-# Handled astribanks
-astribank_is_starting -r
+if [ "$XPP_HOTPLUG_DAHDI" = yes ]; then
+ if [ "$CALLED_FROM_ATRIBANK_HOOK" = '' ]; then
+ # Now we can wait until the hotplug run would remove the semaphore
+ echo -n 1>&2 "Other DAHDI initializations... "
+ astribank_is_starting -v -w 1>&2
+ fi
+else
+ # Non-hotplug -- Sequential initialization, remove semaphore
+ astribank_is_starting -v -r 1>&2
+fi