[CRIU] [PATCH 12/17] proc_parse: Add parsing of fanotify entries

Pavel Emelyanov xemul at parallels.com
Mon Dec 24 09:07:08 EST 2012


On 12/24/2012 05:57 PM, Cyrill Gorcunov wrote:
> On Mon, Dec 24, 2012 at 05:28:04PM +0400, Pavel Emelyanov wrote:
>>
>> Why adding _new_ stuff to parse results in rewriting the _existing_ stuff parsing?
> 
> Because of the kernel format specifics -- I've to return the @type of the
> parsed entry. Previously we only were carried inotify objects, now I need
> to parse fanotify, and adding "call-back" parameters allowed me to unitfy
> the code.
> 
> I believe you don't like it because of the patch view itself. Here is how
> it looks in real
> 
> 
> +		if (fdinfo_field(str, "fanotify flags")) {
> +			struct fsnotify_params *p = arg;
> +
> +			if (type != FD_TYPES__FSNOTIFY)
> +				goto parse_err;
> +
> +			ret = sscanf(str, "fanotify flags:%x event-flags:%x",
> +				     &p->flags, &p->eflags);
> +			if (ret != 2)
> +				goto parse_err;
> +			entry_met = true;
> +			continue;
> +		}
> +		if (fdinfo_field(str, "inotify wd")	||
> +		    fdinfo_field(str, "fanotify ino")	||
> +		    fdinfo_field(str, "fanotify mnt_id")) {
>  			FhEntry f_handle = FH_ENTRY__INIT;
> +			struct fsnotify_params *p = arg;
>  			int hoff;
>  
>  			fsnotify_wd_entry__init(&entry.fsy);
>  			entry.fsy.f_handle = &f_handle;
>  			entry.fsy.has_type = true;
>  
>  			if (type != FD_TYPES__FSNOTIFY)

The "inotify wd" string results in parse error? Why?

>  				goto parse_err;
>  
> +			entry.fsy.has_type = true;
> +			switch (str[9]) {
> +			case 'd':
> +			case 'i':
> +				if (str[9] == 'd') {
> +					entry.fsy.type = FSNOTIFY_TYPE__INOTIFY;
> +					ret = sscanf(&str[11],
> +						     "%x ino:%lx sdev:%x "
> +						     "mask:%x ignored_mask:%x "
> +						     "fhandle-bytes:%x fhandle-type:%x "
> +						     "f_handle: %n",
> +						     &entry.fsy.wd, &entry.fsy.i_ino, &entry.fsy.s_dev,
> +						     &entry.fsy.mask, &entry.fsy.ignored_mask,
> +						     &entry.fsy.f_handle->bytes, &entry.fsy.f_handle->type,
> +						     &hoff);
> +					if (ret != 7)
> +						goto parse_err;
> +					hoff += 11;
> +				} else {
> +					entry.fsy.type = FSNOTIFY_TYPE__FANOTIFY;
> +					ret = sscanf(&str[13],
> +						     "%lx sdev:%x "
> +						     "mflags:%x mask:%x ignored_mask:%x "
> +						     "fhandle-bytes:%x fhandle-type:%x "
> +						     "f_handle: %n",
> +						     &entry.fsy.i_ino, &entry.fsy.s_dev,
> +						     &entry.fsy.wd, &entry.fsy.mask, &entry.fsy.ignored_mask,
> +						     &entry.fsy.f_handle->bytes, &entry.fsy.f_handle->type,
> +						     &hoff);
> +					if (ret != 7)
> +						goto parse_err;
> +					hoff += 13;
> +				}
>  
> +				f_handle.n_handle = FH_ENTRY_SIZES__min_entries;
> +				f_handle.handle = xmalloc(pb_repeated_size(&f_handle, handle));
> +				if (!f_handle.handle)
> +					return -1;
>  
> +				parse_fhandle_encoded(str + hoff, entry.fsy.f_handle);
> +				break;
> +			case 'm':
> +				/*
> +				 * In real it's not @s_dev parsed here but
> +				 * @mnt_id. Thus the caller must be ready
> +				 * for that and handle this trick accordingly.
> +				 */
> +				entry.fsy.type = FSNOTIFY_TYPE__FANOTIFY;
> +				ret = sscanf(&str[16],
> +					     "%x mflags:%x mask:%x ignored_mask:%x",
> +					     &entry.fsy.s_dev, &entry.fsy.wd,
> +					     &entry.fsy.mask, &entry.fsy.ignored_mask);
> +				if (ret != 4)
> +					goto parse_err;
> +				break;
> +			default:
> +				BUG();
> +				break;
> +			}
> +
> +			ret = cb(&entry, p);

This is ugly anyway. The resulting code looks like

if (field_is("xyzabc") || field_is("wvubcd") || field_is("wvucde")) {
	foo();
	switch (field[2]) { /* why field[2], not 3 or any other magic number? 
                             * because it's the first letter, that differs between
                             * these tree, isn't it obvious?! */
	'a':
		do_a();
		break;
	'b':
		do_b();
		break;
	'c':
		do_c();
		break;
	}

	continue;
}

instead of plain and readable

if (field_is("xyzabc")) {
	foo();
	do_a();
	continue;
}

if (field_is("wvubcd")) {
	foo();
	do_b();
	continue;
}

if (field_is("wvucde")) {
	foo();
	do_c();
	continue;
}

>  			xfree(f_handle.handle);
> 
> 	Cyrill
> .
> 




More information about the CRIU mailing list