From: Christian Brauner Date: Wed, 6 May 2026 10:40:26 +0000 (+0200) Subject: vmspawn: reject --bind-volume= duplicates at parse time X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F41961%2Fhead;p=thirdparty%2Fsystemd.git vmspawn: reject --bind-volume= duplicates at parse time bind_volume_parse() does not look at peers, so passing the same PROVIDER:VOLUME twice on the command line silently produces two parsed entries in arg_bind_volumes. vmspawn_bind_volume_acquire() then builds two DriveInfo with identical d->id (":"). At boot, bridge_register_drive() puts d->id into the b->block_devices hashmap; the second insert returns -EEXIST and the user sees a bare "File exists" with no context for which volume is responsible. Reject the collision at the parse site with a linear scan over the existing array — n_items is small (one entry per --bind-volume on the command line), and a clear error message naming the offending volume is much more useful than the late EEXIST from the QMP setup loop. Signed-off-by: Christian Brauner (Amutable) --- diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c index ee8ae518f03..57b7697079e 100644 --- a/src/vmspawn/vmspawn.c +++ b/src/vmspawn/vmspawn.c @@ -787,6 +787,12 @@ static int parse_argv(int argc, char *argv[]) { bv->config, valid); } + FOREACH_ARRAY(it, arg_bind_volumes.items, arg_bind_volumes.n_items) + if (streq((*it)->provider, bv->provider) && streq((*it)->volume, bv->volume)) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Volume '%s:%s' specified more than once for --bind-volume=.", + bv->provider, bv->volume); + if (!GREEDY_REALLOC(arg_bind_volumes.items, arg_bind_volumes.n_items + 1)) return log_oom(); arg_bind_volumes.items[arg_bind_volumes.n_items++] = TAKE_PTR(bv);