Commit 4ef3017c authored by Adam Wujek's avatar Adam Wujek 💬

rootfs: make possible to get URL to the dot-config via dhcp

force-dhcp can be used to retrieve a URL to the dot-config, which is downloaded
during boot.
try-dhcp the same as above but don't complain about unsuccessful receive of the
URL via DHCP to SNMP.

Update:
--MIB - add tryDhcp and forceDhcp to the wrsConfigSource object; add
        dhcpError to the wrsBootConfigStatus object
--SNMPd - same as the above; don't error in wrsBootConfigStatus when tryDhcp
          fails
--dot-config's script - support new dot-config sources
--Kconfig - support new dot-config sources
--wrs_failures
--wrs-user-manual
--wrs_release_defconfig - add new items
--create new script for udhcpc to save "filename" configuration field retrieved
  from DHCP server; it contains the URL to the dot-config to be downloaded.
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent a51052af
mainmenu "White Rabbit Switch configuration"
config DOTCONF_URL
choice DOTCONF_SOURCE
prompt "Source for a run-time replacement of dot-config"
default DOTCONF_SOURCE_TRY_DHCP
string "URL for a run-time replacement of dot-config"
config DOTCONF_SOURCE_LOCAL
bool "Use local dot-config"
help
The White Rabbit Switch is configured at run-time,
according to a dot-config .config file. The file
is the same .config you are defining now. If you
select an empty string, dot-config is not replaced
at run time. Otherwise, tftp://, ftp:// or http://
URLs are allowed. Names are allowed if you configured
a DNS server. The special strings IPADDR and MACADDR
are substituted before retrieving the file.
is the same .config you are defining now. If you
select this option, dot-config is not replaced
at run time.
config DOTCONF_SOURCE_REMOTE
bool "Use remote dot-config"
help
Use the URL to dot-config provided in DOTCONF_URL.
config DOTCONF_SOURCE_FORCE_DHCP
bool "Force to get the URL to a dot-config via DHCP"
help
Retrieve a URL to the dot-config via DHCP at boot.
The URL can be configured in the "filename" configuration field of
the DHCP server.
config DOTCONF_SOURCE_TRY_DHCP
bool "Try to get the URL to a dot-config via DHCP"
help
The same as DOTCONF_SOURCE_FORCE_DHCP, but this option does not
cause errors in SNMP's objects if the switch fails to retrieve
the URL to the dot-config via DHCP.
endchoice
config DOTCONF_URL
string "URL for a run-time replacement of dot-config"
depends on DOTCONF_SOURCE_REMOTE
help
tftp://, ftp:// or http:// URLs are allowed. Names are allowed if
you configured a DNS server. The special strings IPADDR and MACADDR
are substituted before retrieving the file.
Example: "tftp://morgana/wrs-config-IPADDR"
config BR2_CONFIGFILE
......
#
# Automatically generated make config: don't edit
#
CONFIG_DOTCONF_URL=""
# CONFIG_DOTCONF_SOURCE_LOCAL is not set
# CONFIG_DOTCONF_SOURCE_REMOTE is not set
# CONFIG_DOTCONF_SOURCE_FORCE_DHCP is not set
CONFIG_DOTCONF_SOURCE_TRY_DHCP=y
CONFIG_BR2_CONFIGFILE="wrs_release_br2_config"
CONFIG_PPSI=y
......
......@@ -336,7 +336,8 @@ configuration file each time it is booted, and applies the choices
before starting any service. The name of the configuration file can
include the @sc{mac} or @sc{ip} address of the device, to allow
running several switches with different configurations in the same
network.
network. The URL to the configuration file can also be retrieved from DHCP
server.
@c ==========================================================================
@node The Configuration File
......@@ -352,12 +353,39 @@ The configuration step creates @t{.config}, that you can copy to your
@sc{wrs} as @t{/wr/etc/dot-config}. After reboot, you'll see your
choices in effect.
The first configuration choice is @t{CONFIG_DOTCONF_URL}. If the
selected string is not empty, the Switch will download a new @t{dot-config}
file, and replace the copy in local storage if it is different. If
the string is empty, no network access is performed.
The first configuration choice is about source of the @t{dot-config} file
(items starting with @t{CONFIG_DOTCONF_SOURCE_}). The following @t{dot-config}
sources are implemented in current version:
@table @t
@item CONFIG_DOTCONF_SOURCE_LOCAL
Use local @t{dot-config} file stored in @t{/wr/etc/dot-config}.
In this case no network access is performed.
@item CONFIG_DOTCONF_SOURCE_REMOTE
Get a @t{dot-config} file from the URL provided in @t{CONFIG_DOTCONF_URL}.
@item CONFIG_DOTCONF_SOURCE_FORCE_DHCP
Get a URL to a @t{dot-config} file from a DHCP server.
The URL can be configured in the ``@t{filename}'' configuration field
of the DHCP server. The configured URL has to be in the same form as
@t{CONFIG_DOTCONF_URL}.
@item CONFIG_DOTCONF_SOURCE_TRY_DHCP
The same as @t{CONFIG_DOTCONF_SOURCE_FORCE_DHCP}, but this option does
not cause errors in SNMP's objects if the switch fails to retrieve the
URL to the @t{dot-config} via DHCP. Note that syntax and download
errors of @t{dot-config} are notified in the same way as for other
choices.
@end table
If the selected option triggers @sc{wrs} to download a new @t{dot-config}
file, it will replace the copy in the local storage if it is different.
@t{CONFIG_DOTCONF_URL} is of the form
The URL (stored in @t{CONFIG_DOTCONF_URL} or retrieved via DHCP) is of the form
``@i{protocol}@t{://}@i{host}@t{/}@i{pathname}''. The special upper-case
strings @t{IPADDR} and @t{MACADDR} are substituted with the current
addresses of the management port of the switch.
......@@ -388,6 +416,7 @@ The three parts of the URL are as follows:
For example this is a valid configuration for run-time update:
@smallexample
CONFIG_DOTCONF_SOURCE_REMOTE=y
CONFIG_DOTCONF_URL="tftp://morgana/wrs-config-IPADDR"
CONFIG_DNS_SERVER="192.168.16.1"
CONFIG_DNS_DOMAIN="i.gnudd.com"
......@@ -397,9 +426,10 @@ And it results, in my case, in @t{wrs-config-192.168.16.9} being
served to the @sc{wrs}.
Please remember that the new @t{dot-config} should include a valid
@t{DOTCONF_URL} setting, or you won't be able to update the configuration
at the next boot. In any case, you can always copy a configuration
file using @i{ssh}, or use the web interface to change the configuration.
@t{CONFIG_DOTCONF_SOURCE_*} setting, or you won't be able to update the
configuration at the next boot. In any case, you can always copy a
configuration file using @i{ssh}, or use the web interface to change the
configuration.
Changes performed using the web interface are immediately active, because
the web server takes proper action; the new file copied over with @i{ssh},
or any hand-edits, are only effective at next boot, unless overwritten by
......@@ -442,9 +472,13 @@ value is changed by the web interface, proper action is taken.
@table @code
@item CONFIG_DOTCONF_URL
@item CONFIG_DOTCONF_SOURCE_LOCAL
@itemx CONFIG_DOTCONF_SOURCE_REMOTE
@itemx CONFIG_DOTCONF_SOURCE_FORCE_DHCP
@itemx CONFIG_DOTCONF_SOURCE_TRY_DHCP
@itemx CONFIG_DOTCONF_URL
The location of a config file to be used at a replacement
The source and location of a config file to be used at a replacement
the next time the system boots. See @ref{Dynamic WRS Configuration}
and @ref{The Configuration File} for details.
......
......@@ -532,14 +532,18 @@ between devices connected to the ports.\\
\item [] \underline{Severity}: ERROR
\item [] \underline{Description}:\\
Dot-config file used to configure the switch can be stored locally or
retrieved from a central server. When it is fetch from the server it has
to be verified before being applied. If downloading or verification has
retrieved from a central server. Additionally URL to the remote dot-config
can be retrieved via DHCP request. When dot-config is fetch from the server
it has to be verified before being applied. If downloading or verification has
failed an alarm is raised.
\item [] \underline{SNMP objects}:\\
\texttt{WR-SWITCH-MIB::wrsBootSuccessful} -- status word informing
whether switch booted correctly\\
\texttt{WR-SWITCH-MIB::wrsConfigSource} -- source of a dot-config,
local or remote\\
local, remote or get URL to the dot-config via DHCP. When
\texttt{wrsConfigSource} is set to the \texttt{tryDhcp}, then failure of
getting dot-config's URL via DHCP does not rise an error in
\texttt{wrsBootSuccessful}\\
\texttt{WR-SWITCH-MIB::wrsConfigSourceUrl} -- path to the dot-config
on a server (if not local)\\
\texttt{WR-SWITCH-MIB::wrsBootConfigStatus} -- result of the dot-config verification
......
......@@ -66,6 +66,7 @@ this section can have one of the following values:
\item \texttt{wrsBootSuccessful} -- Grouped status of
\texttt{wrsBootStatusGroup}, indicating whether boot was successful.
\texttt{Error} when dot-config source is wrong, unable to get the dot-config,
unable to get URL to the dot-config,
dot-config contains errors, unable to read the hwinfo, unable to load
the FPGA bitstream, unable to load the LM32 software, any kernel
modules or userspace daemons are missing (issue \ref{fail:other:boot},
......
......@@ -10,9 +10,10 @@ dotconfig=/wr/etc/dot-config
tmpconfig=/tmp/dot-config
tmpdir=/tmp
rm -f "$tmpdir"/dot-config_source
if [ -f $dotconfig ]; then
. $dotconfig
echo "local" > "$tmpdir"/dot-config_source
#assume that local config is always ok
echo "config_ok" > "$tmpdir"/dot-config_status
else
......@@ -28,9 +29,42 @@ if [ ! -z "$CONFIG_DNS_SERVER" ]; then
fi
fi
# remove "$tmpdir"/dot-config_source_url" in case it is not first run
# of this script
rm -f "$tmpdir"/dot-config_source_url
# If we are expected to get a new dot-conf, do it
if [ -n "$CONFIG_DOTCONF_URL" ]; then
if [ -n "$CONFIG_DOTCONF_SOURCE_REMOTE" ] || [ -n "$CONFIG_DOTCONF_SOURCE_TRY_DHCP" ] \
|| [ -n "$CONFIG_DOTCONF_SOURCE_FORCE_DHCP" ]; then
echo "remote" > "$tmpdir"/dot-config_source
# get URL via DHCP
if [ -n "$CONFIG_DOTCONF_SOURCE_TRY_DHCP" ] \
|| [ -n "$CONFIG_DOTCONF_SOURCE_FORCE_DHCP" ]; then
if [ -n "$CONFIG_DOTCONF_SOURCE_TRY_DHCP" ]; then
echo "try_dhcp" > "$tmpdir"/dot-config_source
fi
if [ -n "$CONFIG_DOTCONF_SOURCE_FORCE_DHCP" ]; then
echo "force_dhcp" > "$tmpdir"/dot-config_source
fi
# let udhcpc run /wr/bin/dhcp_get_filename.sh script to get "filename"
# from DHCP (which contain url with dot-config).
/sbin/udhcpc -i eth0 -s /wr/bin/dhcp_get_filename.sh -O bootfile -o \
-n -q -f -t 5 &>/dev/null
if [ -f "$tmpdir"/dot-config_source_url ]; then
# replace CONFIG_DOTCONF_URL with one gotten from dhcp
CONFIG_DOTCONF_URL=`cat "$tmpdir"/dot-config_source_url`
echo "Got dot-config's URL ("$CONFIG_DOTCONF_URL") via DHCP"
else
echo "dhcp_error" > "$tmpdir"/dot-config_status
echo "Unable to get dot-config's URL via DHCP, using old dot-config"
# apply old dot-config
/wr/bin/apply_dot-config
exit
fi
fi
# replace IPADDR and MACADDR, to have a device-specific name
macaddr=$(cat /sys/class/net/eth0/address)
ipaddr=$(ifconfig eth0 | grep inet | cut -d: -f 2 | cut '-d ' -f 1)
......@@ -78,6 +112,11 @@ if [ -n "$CONFIG_DOTCONF_URL" ]; then
echo "download_error" > "$tmpdir"/dot-config_status
echo "Download error for dot-config \"$URL\", using old"
fi
elif [ -n "$DOTCONF_SOURCE_LOCAL" ]; then
echo "local" > "$tmpdir"/dot-config_source
echo "Using local dot-config"
else
echo "Unknown dot-config source. Using local dot-config"
fi
# Finally, apply what we have, be it old or new
......
#!/bin/sh
# Adam Wujek @ CERN
#
# This script is to be run by udhcpc
#
# udhcpc should save URL to the dot-config in boot_file.
# URL shall be stored in "filename" configuration field of DHCP server.
#
# We create a temporary file in /tmp, to avoid wearing flash if not
# needed. Then we replace the real file if different.
tmpdir="/tmp"
if [ -n "$boot_file" ]; then
echo $boot_file > "$tmpdir"/dot-config_source_url
fi
......@@ -579,7 +579,9 @@ wrsConfigSource OBJECT-TYPE
error(1),
errorMinor(2),
local(3),
remote(4)
remote(4),
tryDhcp(5),
forceDhcp(6)
}
MAX-ACCESS read-only
STATUS current
......@@ -587,7 +589,11 @@ wrsConfigSource OBJECT-TYPE
"Source of used dotconfig
local - used dot-config was stored on the switch
remote - dot-config retrieved from the network check the
wrsConfigSourceUrl for the path
wrsConfigSourceUrl for the path
tryDhcp - try to get URL to the dot-config via DHCP, if DHCP retrieve
fail do not propagate error to the wrsBootSuccessful;
forceDhcp - get URL to the dot-config via DHCP, if failed propagate error
to the wrsBootSuccessful
errorMinor - cannot read the status file, problem is probably somewhere
else"
::= { wrsBootStatusGroup 6 }
......@@ -616,16 +622,18 @@ wrsBootConfigStatus OBJECT-TYPE
error(2),
downloadError(3),
checkError(4),
errorMinor(5)
errorMinor(5),
dhcpError(6)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Result of loading or downloading dot-config file
ok - dot-config downloaded or loaded correctly
downloadError - unable to download file from given source
downloadError - unable to download a file from a given source
checkError - config file is not valid or too short (less than 200 characters).
errorMinor - cannot read status file, problem is probably somewhere else"
errorMinor - cannot read the status file, problem is probably somewhere else
dhcpError - unable to get URL to dot-config via DHCP (only for forceDhcp)"
::= { wrsBootStatusGroup 9 }
wrsBootHwinfoReadout OBJECT-TYPE
......
......@@ -195,6 +195,12 @@ static void get_dotconfig_source(void)
if (!strncmp(buff, "remote", 10))
wrsBootStatus_s.wrsConfigSource =
WRS_CONFIG_SOURCE_REMOTE;
else if (!strncmp(buff, "try_dhcp", 10))
wrsBootStatus_s.wrsConfigSource =
WRS_CONFIG_SOURCE_TRY_DHCP;
else if (!strncmp(buff, "force_dhcp", 10))
wrsBootStatus_s.wrsConfigSource =
WRS_CONFIG_SOURCE_FORCE_DHCP;
else if (!strncmp(buff, "local", 10))
wrsBootStatus_s.wrsConfigSource =
WRS_CONFIG_SOURCE_LOCAL;
......@@ -208,7 +214,7 @@ static void get_dotconfig_source(void)
WRS_CONFIG_SOURCE_ERROR_MINOR;
}
/* read hostname and file name only when config is not local */
/* read dot-config's URL only when config source is not local */
if (wrsBootStatus_s.wrsConfigSource != WRS_CONFIG_SOURCE_LOCAL) {
/* read URL used to get dotconfig */
f = fopen(DOTCONFIGDIR "/" DOTCONFIG_SOURCE_URL, "r");
......@@ -238,6 +244,9 @@ static void get_dotconfig_source(void)
else if (!strncmp(buff, "download_error", 20))
wrsBootStatus_s.wrsBootConfigStatus =
WRS_CONFIG_STATUS_DL_ERROR;
else if (!strncmp(buff, "dhcp_error", 20))
wrsBootStatus_s.wrsBootConfigStatus =
WRS_CONFIG_STATUS_DHCP_ERROR;
else
wrsBootStatus_s.wrsBootConfigStatus =
WRS_CONFIG_STATUS_ERROR;
......
......@@ -13,12 +13,16 @@
#define WRS_CONFIG_SOURCE_ERROR_MINOR 2 /* warning */
#define WRS_CONFIG_SOURCE_LOCAL 3 /* ok */
#define WRS_CONFIG_SOURCE_REMOTE 4 /* ok */
#define WRS_CONFIG_SOURCE_TRY_DHCP 5 /* ok */
#define WRS_CONFIG_SOURCE_FORCE_DHCP 6 /* ok */
#define WRS_CONFIG_STATUS_OK 1 /* ok */
#define WRS_CONFIG_STATUS_ERROR 2 /* error */
#define WRS_CONFIG_STATUS_DL_ERROR 3 /* error */
#define WRS_CONFIG_STATUS_CHECK_ERROR 4 /* error */
#define WRS_CONFIG_STATUS_ERROR_MINOR 5 /* warning */
#define WRS_CONFIG_STATUS_DHCP_ERROR 6 /* ok, for try_dhcp,
* error for force_dhcp */
#define WRS_BOOT_HWINFO_OK 1 /* ok */
#define WRS_BOOT_HWINFO_ERROR 2 /* error */
......
......@@ -74,6 +74,9 @@ time_t wrsOSStatus_data_fill(void)
|| b->wrsBootConfigStatus == WRS_CONFIG_STATUS_ERROR
|| b->wrsBootConfigStatus == WRS_CONFIG_STATUS_DL_ERROR
|| b->wrsBootConfigStatus == WRS_CONFIG_STATUS_CHECK_ERROR
/* error only when dhcp failed for force_dhcp */
|| (b->wrsBootConfigStatus == WRS_CONFIG_STATUS_DHCP_ERROR
&& b->wrsConfigSource == WRS_CONFIG_SOURCE_FORCE_DHCP)
|| b->wrsBootHwinfoReadout == WRS_BOOT_HWINFO_ERROR
|| b->wrsBootLoadFPGA == WRS_BOOT_LOAD_FPGA_ERROR
|| b->wrsBootLoadFPGA == WRS_BOOT_LOAD_FPGA_FILE_NOT_FOUND
......@@ -109,7 +112,8 @@ time_t wrsOSStatus_data_fill(void)
&& b->wrsRestartReason != WRS_RESTART_REASON_ERROR
&& b->wrsConfigSource != WRS_CONFIG_SOURCE_ERROR
&& b->wrsConfigSource != WRS_CONFIG_SOURCE_ERROR_MINOR /* warning */
&& b->wrsBootConfigStatus == WRS_CONFIG_STATUS_OK
&& (b->wrsBootConfigStatus == WRS_CONFIG_STATUS_OK
|| b->wrsConfigSource == WRS_CONFIG_SOURCE_TRY_DHCP)
&& b->wrsBootHwinfoReadout == WRS_BOOT_HWINFO_OK
&& b->wrsBootLoadFPGA == WRS_BOOT_LOAD_FPGA_OK
&& b->wrsBootLoadLM32 == WRS_BOOT_LOAD_LM32_OK
......@@ -119,16 +123,19 @@ time_t wrsOSStatus_data_fill(void)
/* additional check of source */
if (
b->wrsConfigSource == WRS_CONFIG_SOURCE_LOCAL
|| b->wrsConfigSource == WRS_CONFIG_SOURCE_TRY_DHCP
|| (
(
b->wrsConfigSource == WRS_CONFIG_SOURCE_REMOTE
|| b->wrsConfigSource == WRS_CONFIG_SOURCE_FORCE_DHCP
)
&& strnlen(b->wrsConfigSourceUrl, WRS_CONFIG_SOURCE_URL_LEN + 1)
)
) { /* OK */
/* when dotconfig is local or (remote and host not empty and filename not empty) */
/* when dotconfig is local or try_dhcp or
* ((remote or force_dhcp) and url not empty) */
wrsOSStatus_s.wrsBootSuccessful = WRS_BOOT_SUCCESSFUL_OK;
} else { /* error because of source */
} else { /* error because of empty source url */
wrsOSStatus_s.wrsBootSuccessful = WRS_BOOT_SUCCESSFUL_ERROR;
}
} else { /* probably bug in previous conditions,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment