1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-06-16 06:15:24 +00:00

Feature: Support killing a running dumpfile

See: #2173
This commit is contained in:
Philipp Schafft 2022-03-21 20:03:16 +00:00
parent 0e538c855b
commit 801b315d1d
7 changed files with 73 additions and 5 deletions

View File

@ -31,4 +31,5 @@ nobase_dist_admin_DATA = \
includes/web-page.xsl \
ui/confirmdeleteuser.xsl \
ui/confirmkillclient.xsl \
ui/confirmkillsource.xsl
ui/confirmkillsource.xsl \
ui/confirmkilldumpfile.xsl

View File

@ -8,6 +8,14 @@
<li><a href="/admin/moveclients.xsl?mount={$mount}">Move listeners</a></li>
<li><a href="/admin/updatemetadata.xsl?mount={$mount}">Metadata</a></li>
<li><a href="/admin/fallbacks.xsl?mount={$mount}&amp;omode=strict">Set fallback</a></li>
<xsl:choose>
<xsl:when test="dumpfile_written/text() != '0'">
<li class="critical"><a href="/admin/ui/confirmkilldumpfile.xsl?mount={$mount}">Stop dumpfile</a></li>
</xsl:when>
<xsl:otherwise>
<li class="disabled"><a>No dumpfile running</a></li>
</xsl:otherwise>
</xsl:choose>
<li class="critical"><a href="/admin/ui/confirmkillsource.xsl?mount={$mount}">Kill source</a></li>
</ul>
</div>

View File

@ -0,0 +1,24 @@
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xt="http://www.jclark.com/xt" extension-element-prefixes="xt" exclude-result-prefixes="xt">
<!-- Import include files -->
<xsl:include href="includes/confirm.xsl"/>
<xsl:variable name="title">Confirm Stopping dumpfile</xsl:variable>
<xsl:template name="content">
<xsl:for-each select="/report/incident">
<xsl:variable name="get-parameters" select="resource[@type='parameter']/value[@member='get-parameters']" />
<xsl:variable name="mount" select="$get-parameters/value[@member='mount']" />
<xsl:call-template name="confirm">
<xsl:with-param name="text">Please confirm stopping the dumpfile for <code><xsl:value-of select="$mount/@value" /></code>.</xsl:with-param>
<xsl:with-param name="action-cancel">/admin/streamlist.xsl</xsl:with-param>
<xsl:with-param name="action-confirm">/admin/dumpfilecontrol.xsl</xsl:with-param>
<xsl:with-param name="params-cancel">
<xsl:copy-of select="$mount" />
</xsl:with-param>
<xsl:with-param name="params-confirm">
<xsl:copy-of select="$mount" />
<value member="action" value="kill" />
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

View File

@ -143,6 +143,8 @@
#define KILLSOURCE_RAW_REQUEST "killsource"
#define KILLSOURCE_HTML_REQUEST "killsource.xsl"
#define KILLSOURCE_JSON_REQUEST "killsource.json"
#define DUMPFILECONTROL_RAW_REQUEST "dumpfilecontrol"
#define DUMPFILECONTROL_HTML_REQUEST "dumpfilecontrol.xsl"
#define ADMIN_XSL_RESPONSE "response.xsl"
#define MANAGEAUTH_RAW_REQUEST "manageauth"
#define MANAGEAUTH_HTML_REQUEST "manageauth.xsl"
@ -190,6 +192,7 @@ static void command_list_listen_sockets (client_t *client, source_t *source, adm
static void command_move_clients (client_t *client, source_t *source, admin_format_t response);
static void command_kill_client (client_t *client, source_t *source, admin_format_t response);
static void command_kill_source (client_t *client, source_t *source, admin_format_t response);
static void command_dumpfile_control (client_t *client, source_t *source, admin_format_t response);
static void command_manageauth (client_t *client, source_t *source, admin_format_t response);
static void command_updatemetadata (client_t *client, source_t *source, admin_format_t response);
static void command_buildm3u (client_t *client, source_t *source, admin_format_t response);
@ -237,6 +240,8 @@ static const admin_command_handler_t handlers[] = {
{ KILLSOURCE_RAW_REQUEST, ADMINTYPE_MOUNT, ADMIN_FORMAT_RAW, ADMINSAFE_UNSAFE, command_kill_source, NULL},
{ KILLSOURCE_HTML_REQUEST, ADMINTYPE_MOUNT, ADMIN_FORMAT_HTML, ADMINSAFE_UNSAFE, command_kill_source, NULL},
{ KILLSOURCE_JSON_REQUEST, ADMINTYPE_MOUNT, ADMIN_FORMAT_JSON, ADMINSAFE_UNSAFE, command_kill_source, NULL},
{ DUMPFILECONTROL_RAW_REQUEST, ADMINTYPE_MOUNT, ADMIN_FORMAT_RAW, ADMINSAFE_UNSAFE, command_dumpfile_control, NULL},
{ DUMPFILECONTROL_HTML_REQUEST, ADMINTYPE_MOUNT, ADMIN_FORMAT_HTML, ADMINSAFE_UNSAFE, command_dumpfile_control, NULL},
{ MANAGEAUTH_RAW_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_RAW, ADMINSAFE_HYBRID, command_manageauth, NULL},
{ MANAGEAUTH_HTML_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_HTML, ADMINSAFE_HYBRID, command_manageauth, NULL},
{ MANAGEAUTH_JSON_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_JSON, ADMINSAFE_HYBRID, command_manageauth, NULL},
@ -543,6 +548,9 @@ xmlDocPtr admin_build_sourcelist(const char *mount, client_t *client, admin_form
xmlNewTextChild(srcnode, NULL, XMLSTR("content-type"),
XMLSTR(source->format->contenttype));
}
snprintf(buf, sizeof(buf), "%"PRIu64, source->dumpfile_written);
xmlNewTextChild(srcnode, NULL, XMLSTR("dumpfile_written"), XMLSTR(buf));
}
node = avl_get_next(node);
}
@ -1116,6 +1124,19 @@ static void command_kill_source(client_t *client,
admin_send_response_simple(client, source, response, "Source Removed", 1);
}
static void command_dumpfile_control (client_t *client, source_t *source, admin_format_t response)
{
const char *action;
COMMAND_REQUIRE(client, "action", action);
if (strcmp(action, "kill") == 0) {
source_kill_dumpfile(source);
admin_send_response_simple(client, source, response, "Dumpfile killed.", 1);
} else {
admin_send_response_simple(client, source, response, "No such action", 0);
}
}
static void command_kill_client(client_t *client,
source_t *source,
admin_format_t response)

View File

@ -1477,10 +1477,7 @@ bool source_write_dumpfile(source_t *source, const void *buffer, size_t len)
if (fwrite(buffer, 1, len, source->dumpfile) != len) {
ICECAST_LOG_WARN("Write to dump file failed, disabling");
fclose(source->dumpfile);
source->dumpfile = NULL;
stats_event(source->mount, "dumpfile_written", NULL);
stats_event(source->mount, "dumpfile_start", NULL);
source_kill_dumpfile(source);
return false;
}
@ -1488,3 +1485,15 @@ bool source_write_dumpfile(source_t *source, const void *buffer, size_t len)
return true;
}
void source_kill_dumpfile(source_t *source)
{
if (!source->dumpfile)
return;
fclose(source->dumpfile);
source->dumpfile = NULL;
source->dumpfile_written = 0;
stats_event(source->mount, "dumpfile_written", NULL);
stats_event(source->mount, "dumpfile_start", NULL);
}

View File

@ -111,6 +111,7 @@ void source_recheck_mounts (int update_all);
/* Writes a buffer of raw data to a dumpfile. returns true if the write was successful (and complete). */
bool source_write_dumpfile(source_t *source, const void *buffer, size_t len);
void source_kill_dumpfile(source_t *source);
extern mutex_t move_clients_mutex;

View File

@ -156,6 +156,10 @@ ul.boxnav > li.critical > a, a.critical, input[type='submit'].critical {
background-color: #ff704d !important;
}
ul.boxnav > li.disabled > a, a.disabled, input[type='submit'].disabled {
background-color: #a4a4a4 !important;
}
th.actions {
width: 10%;
}