1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-02-25 21:57:45 +03:00

Add escape sequence for ':' and '@' found in device names used as PVs.

This commit is contained in:
Peter Rajnoha 2010-09-23 12:02:33 +00:00
parent e72e8cc71f
commit cffd634681
11 changed files with 86 additions and 33 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.74 -
=====================================
Add escape sequence for ':' and '@' found in device names used as PVs.
Replace alloca with dm_malloc in _aligned_io.
Fix partial mode operations for lvm1 metadata format.
Track recursive filter iteration to avoid refreshing while in use. (2.02.56)

View File

@ -677,6 +677,7 @@ int vg_extend(struct volume_group *vg, int pv_count, char **pv_names,
/* attach each pv */
for (i = 0; i < pv_count; i++) {
unescape_colons_and_at_signs(pv_names[i], NULL, NULL);
if (!vg_extend_single_pv(vg, pv_names[i], pp))
goto bad;
}

View File

@ -109,19 +109,31 @@ static void _quote_characters(char **out, const char *src,
}
/*
* Unquote orig_char in string.
* Also unquote quote_char.
* Unquote each character given in orig_char array and unquote quote_char
* as well. The array ends up with '\0' character. Also save the first
* occurence of each character from orig_char that was found unquoted in
* arr_substr_first_unquoted array. This way we can process several
* characters in one go.
*/
static void _unquote_characters(char *src, const int orig_char,
const int quote_char)
static void _unquote_characters(char *src, const int orig_chars[],
const int quote_char,
char *arr_substr_first_unquoted[])
{
char *out = src;
int c;
int i;
while (*src) {
if (*src == quote_char &&
(*(src + 1) == orig_char || *(src + 1) == quote_char))
src++;
for (i = 0; (c = orig_chars[i]); i++) {
if (*src == quote_char &&
(*(src + 1) == c || *(src + 1) == quote_char)) {
src++;
break;
}
else if (arr_substr_first_unquoted && (*src == c) &&
!arr_substr_first_unquoted[i])
arr_substr_first_unquoted[i] = out;
}
*out++ = *src++;
}
@ -217,7 +229,31 @@ char *escape_double_quotes(char *out, const char *src)
*/
void unescape_double_quotes(char *src)
{
_unquote_characters(src, '\"', '\\');
const int orig_chars[] = {'\"', '\0'};
_unquote_characters(src, orig_chars, '\\', NULL);
}
/*
* Unescape colons and "at" signs in situ and save the substrings
* starting at the position of the first unescaped colon and the
* first unescaped "at" sign. This is normally used to unescape
* device names used as PVs.
*/
void unescape_colons_and_at_signs(char *src,
char **substr_first_unquoted_colon,
char **substr_first_unquoted_at_sign)
{
const int orig_chars[] = {':', '@', '\0'};
char *arr_substr_first_unquoted[] = {NULL, NULL, NULL};
_unquote_characters(src, orig_chars, '\\', arr_substr_first_unquoted);
if (substr_first_unquoted_colon)
*substr_first_unquoted_colon = arr_substr_first_unquoted[0];
if (substr_first_unquoted_at_sign)
*substr_first_unquoted_at_sign = arr_substr_first_unquoted[1];
}
/*

View File

@ -60,4 +60,13 @@ char *escape_double_quotes(char *out, const char *src);
*/
void unescape_double_quotes(char *src);
/*
* Unescape colons and at signs in situ and save the substring starting
* at the position of the first unescaped colon and the first unescaped
* "at" sign.
*/
void unescape_colons_and_at_signs(char *src,
char **substr_first_unquoted_colon,
char **substr_first_unquoted_at_sign);
#endif

View File

@ -195,7 +195,8 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
int total = 0;
struct volume_group *vg;
const char *pv_name, *vg_name;
const char *vg_name;
char *pv_name;
struct pv_list *pvl;
struct dm_list *vgnames;
@ -223,6 +224,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
log_verbose("Using physical volume(s) on command line");
for (; opt < argc; opt++) {
pv_name = argv[opt];
unescape_colons_and_at_signs(pv_name, NULL, NULL);
vg_name = find_vgname_from_pvname(cmd, pv_name);
if (!vg_name) {
log_error("Failed to read physical volume %s",

View File

@ -31,6 +31,7 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
/* FIXME: warning and/or check if in use? */
log_verbose("Scanning %s", argv[i]);
unescape_colons_and_at_signs(argv[i], NULL, NULL);
pv_analyze(cmd, argv[i],
arg_uint64_value(cmd, labelsector_ARG,
UINT64_C(0)));

View File

@ -109,6 +109,8 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
unescape_colons_and_at_signs(argv[i], NULL, NULL);
if (!pvcreate_single(cmd, argv[i], &pp)) {
stack;
ret = ECMD_FAILED;

View File

@ -644,17 +644,16 @@ int pvmove(struct cmd_context *cmd, int argc, char **argv)
}
if (argc) {
pv_name = argv[0];
if (!(pv_name = dm_pool_strdup(cmd->mem, argv[0]))) {
log_error("Failed to clone PV name");
return ECMD_FAILED;
}
unescape_colons_and_at_signs(pv_name, &colon, NULL);
/* Drop any PE lists from PV name */
if ((colon = strchr(pv_name, ':'))) {
if (!(pv_name = dm_pool_strndup(cmd->mem, pv_name,
(unsigned) (colon -
pv_name)))) {
log_error("Failed to clone PV name");
return ECMD_FAILED;
}
}
if (colon)
*colon = '\0';
if (!arg_count(cmd, abort_ARG) &&
(ret = _set_up_pvmove(cmd, pv_name, argc, argv)) !=

View File

@ -144,6 +144,7 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv)
}
for (i = 0; i < argc; i++) {
unescape_colons_and_at_signs(argv[i], NULL, NULL);
r = pvremove_single(cmd, argv[i], NULL);
if (r > ret)
ret = r;

View File

@ -680,7 +680,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
struct dm_list *pvslist, *vgnames;
struct dm_list tags;
struct str_list *sll;
char *tagname;
char *at_sign, *tagname;
int scanned = 0;
struct dm_list mdas;
@ -694,8 +694,9 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
if (argc) {
log_verbose("Using physical volume(s) on command line");
for (; opt < argc; opt++) {
if (*argv[opt] == '@') {
tagname = argv[opt] + 1;
unescape_colons_and_at_signs(argv[opt], NULL, &at_sign);
if (at_sign && (at_sign == argv[opt])) {
tagname = at_sign + 1;
if (!validate_name(tagname)) {
log_error("Skipping invalid tag %s",
@ -1093,8 +1094,8 @@ struct dm_list *create_pv_list(struct dm_pool *mem, struct volume_group *vg, int
struct dm_list *r;
struct pv_list *pvl;
struct dm_list tags, arg_pvnames;
const char *pvname = NULL;
char *colon, *tagname;
char *pvname = NULL;
char *colon, *at_sign, *tagname;
int i;
/* Build up list of PVs */
@ -1108,8 +1109,10 @@ struct dm_list *create_pv_list(struct dm_pool *mem, struct volume_group *vg, int
dm_list_init(&arg_pvnames);
for (i = 0; i < argc; i++) {
if (*argv[i] == '@') {
tagname = argv[i] + 1;
unescape_colons_and_at_signs(argv[i], &colon, &at_sign);
if (at_sign && (at_sign == argv[i])) {
tagname = at_sign + 1;
if (!validate_name(tagname)) {
log_error("Skipping invalid tag %s", tagname);
continue;
@ -1128,13 +1131,10 @@ struct dm_list *create_pv_list(struct dm_pool *mem, struct volume_group *vg, int
pvname = argv[i];
if ((colon = strchr(pvname, ':'))) {
if (!(pvname = dm_pool_strndup(mem, pvname,
(unsigned) (colon -
pvname)))) {
log_error("Failed to clone PV name");
return NULL;
}
if (colon && !(pvname = dm_pool_strndup(mem, pvname,
(unsigned) (colon - pvname)))) {
log_error("Failed to clone PV name");
return NULL;
}
if (!(pvl = find_pv_in_vg(vg, pvname))) {

View File

@ -394,6 +394,7 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
/* Move PVs across to new structure */
for (opt = 0; opt < argc; opt++) {
unescape_colons_and_at_signs(argv[opt], NULL, NULL);
if (!move_pv(vg_from, vg_to, argv[opt]))
goto_bad;
}