What does the UCI -P option?

Hi!

Documentation on UCI options is imprecise.

# uci
Usage: uci [<options>] <command> [<arguments>]

Commands:
	batch
	export     [<config>]
	import     [<config>]
	changes    [<config>]
	commit     [<config>]
	add        <config> <section-type>
	add_list   <config>.<section>.<option>=<string>
	del_list   <config>.<section>.<option>=<string>
	show       [<config>[.<section>[.<option>]]]
	get        <config>.<section>[.<option>]
	set        <config>.<section>[.<option>]=<value>
	delete     <config>.<section>[.<option>]
	rename     <config>.<section>[.<option>]=<name>
	revert     <config>[.<section>[.<option>]]
	reorder    <config>.<section>=<position>

Options:
	-c <path>  set the search path for config files (default: /etc/config)
	-d <str>   set the delimiter for list values in uci show
	-f <file>  use <file> as input instead of stdin
	-m         when importing, merge data into an existing package
	-n         name unnamed sections on export (default)
	-N         don't name unnamed sections
	-p <path>  add a search path for config change files
	-P <path>  add a search path for config change files and use as default
	-q         quiet mode (don't print error messages)
	-s         force strict mode (stop on parser errors, default)
	-S         disable strict mode
	-X         do not use extended syntax on 'show'

For instance, I had to search on the forum to understand the revert option (c.f. How do I undo a uci set command?).

revert <config>[.<section>[.<option>]] Revert the given option, section or configuration file.

Note: English is not my native language.

Another example. I have tried to understand how to use Hotplug. So, I looked at the file /etc/hotplug.d/iface/00-netstate. See below.

[ ifup = "$ACTION" ] && {
	uci_toggle_state network "$INTERFACE" up 1
	[ -n "$DEVICE" ] && {
		uci_toggle_state network "$INTERFACE" ifname "$DEVICE"
	}
}
# file: /lib/config/uci.sh
uci_toggle_state() {
        uci_revert_state "$1" "$2" "$3"
        uci_set_state "$1" "$2" "$3" "$4"
}
# file: /lib/config/uci.sh
uci_revert_state() {
        local PACKAGE="$1"
        local CONFIG="$2"
        local OPTION="$3"

        /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -P /var/state revert "$PACKAGE${CONFIG:+.$CONFIG}${OPTION:+.$OPTION}"
}
# file: /lib/config/uci.sh
uci_set_state() {
        local PACKAGE="$1"
        local CONFIG="$2"
        local OPTION="$3"
        local VALUE="$4"

        [ "$#" = 4 ] || return 0
        /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -P /var/state set "$PACKAGE.$CONFIG${OPTION:+.$OPTION}=$VALUE"
}

In the Wiki, there are some words about UCI -P and -p options. Unfortunately, I still do not understand how to use these options. I don't understand a word.

   -p <path>  add a search path for config change files
   -P <path>  add a search path for config change files and use as default

This is not normal. Because I've read the UCI page. Moreover, I know how to interpret a Unix Shell command line pretty well.

Could someone explain the difference between the options -p and -P and what they do? Could someone improve the documentation?

Best regards.

Uci does not write modifications directly to config files but stores changes in so called delta files. By default, the delta files are stored in /tmp/.uci/.

When you invoke uci show or uci get, the delta file contents are overlaid over the actual config files. Likewise when you modify values, e.g. with uci set or uci delete, those changes are written into a delta file. A uci revert discards those deltas, a uci commit merges them into the actual /etc/config/ files.

By utilizing the -p and -P options you can override the list of directories where delta files are searched.The -P adds a directory and makes it the primary choice for storing deltas while -p adds a further directory candidate to the end of the list.

So in short, -P and -p modify the locations where uci looks for unmerged/uncommitted config changes.

The hotplug script you looked at is a compatibility shim using the deprecated uci state variable mechanism. State variables used to be a way to overlay runtime information into uci by putting those dynamic state variables in the form of uci delta files in a non-standard location (/var/state/ instead of /tmp/.uci/). The -P /var/state/ argument was used under the hood to implement this.

In normal usage scenarios, there is no need to ever override the default delta directory and the use of state variables (uci_set_state(), uci_get_state()) is discouraged.

LuCI uses the libuci api equivalent of -P to give each logged in user session a different delta directory so that different sessions do not see/overwrite each others changes and to not interfere with uci operations performed on the cli.

6 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.