aboutsummaryrefslogtreecommitdiffstats log msg author committer range
blob: d9cf5ff5ff63e50cf131a5f95f7a34961eeb98b0 (plain)
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167  pre { line-height: 125%; margin: 0; } td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; } span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; } td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */\section{System Environment} In this section, we are going to discuss system requirements for a continuous operation of the tools. This environment differs in some regards to the one used for experiments and laboratory tests, given that monitoring, self-recovery in case of errors and resistance to failure are much more important in a 24/7 operation. We will be using the term \emph{production environment} to refer to such a usage. \subsection{Launching the tools} Services running in a production environment are usually administered remotely, and have to be able to run without requiring a user to be connected all the time. Traditionally, such services are implemented as daemons in UNIX terminology, and are started and stopped using the init system of the distribution. The ODR-mmbTools cannot daemonise themselves, and require another approach. \paragraph{Screen multiplexer} An easy approach is to use a screen multiplexer, like \emph{GNU Screen} or \emph{tmux} that can be used to launch a session from which the user can detach and reattach. See the relevant manpages for more information. A screen multiplexer alone does permit the tools to run without a user connected, but does not automatically restart failed processes, and does not send any warning emails in case of a fault. The dab-scripts\footnote{The dab-scripts are available on the Opendigitalradio github.}, already mentioned in \ref{usingexistingwebstreams}, can be a helpful addition in that case. They can monitor that the processes are still running, and if necessary restart them. \paragraph{supervisord} The execution of the tools can also be supervised by a dedicated tool instead of using the scripts. \texttt{supervisor}\footnote{\url{http://supervisord.org}} is (its name will not surprise you) exactly such a tool. Once installed, it reads the configuration in \texttt{/etc/supervisor.conf} and launches the processes it has to monitor. Each process to monitor is described by a file. The following example assumes the tools run as user \texttt{odr}, and the multiplex configuration is in \texttt{/home/odr/config.mux}, and launches ODR-DabMux. The logs of ODR-DabMux is written to the log specified files. \begin{lstlisting} [program:ODR-DabMux] command=odr-dabmux config.mux directory=/home/odr user=odr autostart=true autorestart=true stdout_logfile=/home/odr/logs/mux.out.log stderr_logfile=/home/odr/logs/mux.err.log \end{lstlisting} Once this configuration has been added to the supervisor configuration, the settings have to be reread using: \begin{lstlisting} supervisorctl reread \end{lstlisting} In order for supervisor to start managing and running this process, it has to be added: \begin{lstlisting} supervisorctl add ODR-DabMux \end{lstlisting} Setting up more processes can be simply achieved by customising this configuration template for the other tools. Examples are available in the \texttt{mmbtools-aux} repository, under the \texttt{supervisor} folder, and have to be customised to the paths used in your setup. supervisor also includes a small web-server that can display the state of the managed processes. It is enabled with the \verb+[inet_http_server]+ setting in the configuration file. \subsection{Logging} Essential for a production environment is traceability of events, which is achieved using logging of important messages. ODR-DabMux and ODR-DabMod both support logging to standard error, to a file and to the system logger \texttt{syslog}. Logging to syslog is the most flexible solution, because the log information can be forwarded over the network to a centralised logging server, and can be filtered according to the priority of each message. Both tools log to the LOCAL0 facility, which can be redirected to a file, in order to group ODR-mmbTools-related messages together. %\sidenote{Describe rsyslog configuration} In order to avoid that the log files grow over time to unreasonable sizes, \texttt{logrotate} should be setup to rotate the files automatically. %\sidenote{Describe logrotate configuration} \subsection{Timing} The ODR-mmbTools require a correct system time to function properly. This is especially important when running a SFN, but cannot be neglected for a proper production operation even with a single transmitter. The system needs to run a NTP client that synchronises the system time over the network. Correct synchronisation can be checked using the \texttt{lpeers} command of the \texttt{ntpq} tool. The magnitude of the offset, indicated in milliseconds, should be below 10. The performance of the NTP synchronisation should also be monitored permanently during operation. \subsection{Monitoring using munin} The Munin\footnote{\url{http://munin-monitoring.org/}} monitoring tool can create graphs for essential system health parameters, and can also send emails in case a specific value exceeds its allowed bounds. This helps the operator in assessing the system status and the well-functioning of the services. In addition to basic system measurements like CPU, RAM and disk usage, NTP synchronisation, disk and network performance and many other information, there are also custom data sources for ODR-DabMux. These data sources include ZMQ input buffer monitoring (buffer level, underruns and overruns) and input audio level (peak for both channels). This data source can be installed by copying \verb+doc/stats_dabmux_multi.py+ to \texttt{/etc/munin/plugins.d}. They require that the ODR-DabMux management server is enabled in the configuration, and will automatically generate the graphs for the subchannels used in the configuration. \subsection{Real-time Scheduling} As a general principle, it is advisable to run tools that do not need superuser privileges under another user than \texttt{root}. The same principle also applies to the ODR-mmbTools, where care has to be taken that the tools can request real-time scheduling when needed. This is achieved by adding the following to \texttt{/etc/security/limits.conf}, assuming the tools are run under the user \texttt{odr}. \begin{lstlisting} odr - rtprio 65 odr - nice -10 \end{lstlisting} If you have installed JACK with real-time privileges, you might already find the same setting, but for the audio group, written as \texttt{@audio}, which is sufficient. \subsection{Accessing the USRP as Non-root} Superuser privileges are not required to access USB-connected USRP devices, but sometimes the system lacks the configuration to enable normal users to communicate to the device. In that case, it is necessary to add a rule file for \texttt{udev}. This file is included in the UHD sources, but might not have been automatically installed. The file is called \texttt{uhd-usrp.rules}, should be placed into \texttt{/etc/udev/rules.d/} and should contain { \footnotesize \begin{verbatim} #USRP1 SUBSYSTEMS=="usb", ATTRS{idVendor}=="fffe", ATTRS{idProduct}=="0002", MODE:="0666" #B100 SUBSYSTEMS=="usb", ATTRS{idVendor}=="2500", ATTRS{idProduct}=="0002", MODE:="0666" #B200 SUBSYSTEMS=="usb", ATTRS{idVendor}=="2500", ATTRS{idProduct}=="0020", MODE:="0666" \end{verbatim} } % vim: spl=en spell tw=80 et