[ClusterLabs] Single quotes in values for 'crm resource <rsc> param set'
Vladislav Bogdanov
bubble at hoster-ok.com
Mon Aug 17 09:22:33 UTC 2015
17.08.2015 10:39, Kristoffer Grönlund wrote:
> Vladislav Bogdanov <bubble at hoster-ok.com> writes:
>
>> Hi Kristoffer, all.
>>
>> Could you please look why I get error when trying to update valid
>> resource value (which already has single quotes inside) with the
>> slightly different one by running the command in the subject?
>>
>> It looks like is_value_sane() doesn't accept single quotes just because
>> crmsh quotes all arguments to crm_resource with them. I need to pass a
>> command-line with semicolons in one of parameters which is run with eval
>> in the resource agent. Backslashed double-quoting does not work in this
>> case, but single-quotes work fine.
>>
>> Could that be some-how fixed?
>
> Well, first of all passing the command line through bash complicates
> things, so if that's what is causing you trouble you could try writing
> your command line to a file and passing it to crmsh using crm -f <file>.
> Another option is using "crm -f -" and piping the command line into
> crmsh.
>
Do you mean one with double-quotes?
Otherwise is_value_sane() will fail anyways.
Using "... \"string;string\"" notation in the file strips quotes from the actual command run.
Well, may be function I use is not smart enough, but that works with single-qouted value.
What I think could be done for single-quotes support is to assume that value which contains
them was actually passed in the double-quotes, so double-quotes should be used when
running crm_resource. We may also have in mind that CIB uses double-quotes for values internally.
> If that doesn't help, it would help /me/ in figuring out just what the
> problem is if you could give me an example of what the current value is
> and what it is you are trying to set it to. :)
Well, this is the (obfuscated a bit due to customer's policies) working resource definition
(word wrap off):
primitive staging-0-fs ocf:vendor:Filesystem \
params device="/dev/vg_staging_shared/staging_0" directory="/cluster/storage/staging-0" fstype=gfs2 options="" manage_directory=true subagent="/sbin/fs-io-throttle %a staging-0 /cluster/storage/staging-0 zone 0 '5000M:300;2500M:100;1500M:50;1000M:35;500M:10;300M:mm'" subagent_timeout=10 \
op start interval=0 timeout=90 \
op stop interval=0 timeout=100 \
op monitor interval=10 timeout=45 depth=0 \
op monitor interval=240 timeout=240 depth=10 \
op monitor interval=360 timeout=240 depth=20
Here is the command which fails:
# crm resource param staging-0-fs set subagent "/sbin/fs-io-throttle %a staging-0 /cluster/storage/staging-0 zone 0 '5000M:300;2500M:100;1500M:50;1000M:35;500M:10;400M:mm'"
DEBUG: pacemaker version: [err: ][out: CRM Version: 1.1.12 (1b9beb7)]
DEBUG: found pacemaker version: 1.1.12
ERROR: /sbin/fs-io-throttle %a staging-0 /cluster/storage/staging-0 zone 0 '5000M:300;2500M:100;1500M:50;1000M:35;500M:10;400M:mm': bad name
ERROR: Bad usage: Expected valid name, got '/sbin/fs-io-throttle %a staging-0 /cluster/storage/staging-0 zone 0 '5000M:300;2500M:100;1500M:50;1000M:35;500M:10;400M:mm'', command: 'param staging-0-fs set subagent /sbin/fs-io-throttle %a staging-0 /cluster/storage/staging-0 zone 0 '5000M:300;2500M:100;1500M:50;1000M:35;500M:10;400M:mm''
Replacing single-quotes with back-slashed double ones (\"5000M:300;2500M:100;1500M:50;1000M:35;500M:10;400M:mm\")
makes that string unquoted in the CIB, so semicolons are recognized as command separators by the shell
run from the RA.
Using double-escaping (\\"5000M:300;2500M:100;1500M:50;1000M:35;500M:10;400M:mm\\") when passing value in the
double quotes breaks the shell which runs command.
Using single quotes with one or two back-slashes before double-quote inside for a value produces
unparseable CIB with &dqout; in it.
Here is the function which runs that subagent command (I believe it should support several
semicolon-separated commands as well, but did not test that yet):
run_subagent() {
local subagent_timeout=$1
local subagent_command=$2
local WRAPPER
subagent_command=${subagent_command//%a/${__OCF_ACTION}}
subagent_command=${subagent_command//%r/${OCF_RESOURCE_INSTANCE%:*}}
subagent_command=${subagent_command//%n/$( crm_node -n )}
case "${subagent_timeout}" in
0|""|*[!0-9]*)
WRAPPER="bash -c \"${subagent_command}\""
;;
*)
WRAPPER="timeout -s KILL ${subagent_timeout} bash -c \"${subagent_command}\""
;;
esac
ocf_run eval "${WRAPPER}"
}
It is called with:
run_subagent ${OCF_RESKEY_subagent_timeout} "${OCF_RESKEY_subagent}"
Best regards,
Vladislav
More information about the Users
mailing list