[CRIU] [PATCH v4 05/17] autofs: parse fsinfo stage introduced

Stanislav Kinsburskiy skinsbursky at odin.com
Tue Jan 19 07:08:45 PST 2016



19.01.2016 14:52, Pavel Emelyanov пишет:
>> +static int parse_options(char *options, int32_t *fd, int32_t *timeout,
>> +			 int32_t *minproto, int32_t *maxproto, int32_t *mode,
>> +			 int32_t *pgrp, int32_t *uid, int32_t *gid,
>> +			 long *pipe_ino)
>> +{
>> +	char **opts;
>> +	int nr_opts, i;
>> +
>> +	*fd = AUTOFS_OPT_UNKNOWN;
>> +	*timeout = AUTOFS_OPT_UNKNOWN;
>> +	*minproto = AUTOFS_OPT_UNKNOWN;
>> +	*maxproto = AUTOFS_OPT_UNKNOWN;
>> +	*mode = AUTOFS_OPT_UNKNOWN;
>> +	*pgrp = AUTOFS_OPT_UNKNOWN;
>> +	*uid = AUTOFS_OPT_UNKNOWN;
>> +	*gid = AUTOFS_OPT_UNKNOWN;
>> +	*pipe_ino = AUTOFS_OPT_UNKNOWN;
>> +
>> +	split(options, ',', &opts, &nr_opts);
>> +	if (!opts)
>> +		return -1;
>> +
>> +	for (i = 0; i < nr_opts; i++) {
>> +		char *opt = opts[i];
>> +
>> +		if (!strncmp(opt, "fd=", strlen("fd=")))
>> +			*fd = atoi(opt + strlen("fd="));
>> +		else if (!strncmp(opt, "pipe_ino=", strlen("pipe_ino=")))
>> +			*pipe_ino = atoi(opt + strlen("pipe_ino="));
> This is the new option you try(ed) to push upstream? What's the status
> of this patch?

I got some response from maintainer (Ian Kent).
You can find it here:

https://lists.openvz.org/pipermail/criu/2016-January/024748.html

In short, he is not familiar with CRIU. So I gave him some information 
why we require new option and how CRIU works.
He has nothing against, but requested for more time to think about how 
to deliver this change to the upstream kernel.
He also mentioned, that there is some project with converting 
"fs/autofs4" into "fs/autofs", it's related to Al Viro.
I think I'll ping him now once again.


>> +		else if (!strncmp(opt, "pgrp=", strlen("pgrp=")))
>> +			*pgrp = atoi(opt + strlen("pgrp="));
>> +		else if (!strncmp(opt, "timeout=", strlen("timeout=")))
>> +			*timeout = atoi(opt + strlen("timeout="));
>> +		else if (!strncmp(opt, "minproto=", strlen("minproto=")))
>> +			*minproto = atoi(opt + strlen("minproto="));
>> +		else if (!strncmp(opt, "maxproto=", strlen("maxproto=")))
>> +			*maxproto = atoi(opt + strlen("maxproto="));
>> +		else if (!strcmp(opt, "indirect"))
>> +			*mode = AUTOFS_MODE_INDIRECT;
>> +		else if (!strcmp(opt, "offset"))
>> +			*mode = AUTOFS_MODE_OFFSET;
>> +		else if (!strcmp(opt, "direct"))
>> +			*mode = AUTOFS_MODE_DIRECT;
>> +		else if (!strncmp(opt, "uid=", strlen("uid=")))
>> +			*uid = atoi(opt + strlen("uid="));
>> +		else if (!strncmp(opt, "gid=", strlen("gid=")))
>> +			*gid = atoi(opt + strlen("gid="));
>> +	}
>> +
>> +	for (i = 0; i < nr_opts; i++)
>> +		xfree(opts[i]);
>> +	xfree(opts);
>> +
>> +	if (*fd == AUTOFS_OPT_UNKNOWN) {
>> +		pr_err("Failed to find fd option\n");
>> +		return -1;
>> +	}
>> +	if (*pgrp == AUTOFS_OPT_UNKNOWN) {
>> +		pr_err("Failed to find pgrp option\n");
>> +		return -1;
>> +	}
>> +	if (*timeout == AUTOFS_OPT_UNKNOWN) {
>> +		pr_err("Failed to find timeout option\n");
>> +		return -1;
>> +	}
>> +	if (*minproto == AUTOFS_OPT_UNKNOWN) {
>> +		pr_err("Failed to find minproto option\n");
>> +		return -1;
>> +	}
>> +	if (*maxproto == AUTOFS_OPT_UNKNOWN) {
>> +		pr_err("Failed to find maxproto option\n");
>> +		return -1;
>> +	}
>> +	if (*mode == AUTOFS_OPT_UNKNOWN) {
>> +		pr_err("Failed to find mode (direct,indirect,offset) option\n");
>> +		return -1;
>> +	}
>> +	if (*pipe_ino == AUTOFS_OPT_UNKNOWN) {
>> +		pr_err("Failed to find pipe_ino option (old kernel?)\n");
>> +		return -1;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +int autofs_parse(struct mount_info *pm, bool for_dump)
>> +{
>> +	AutofsEntry *entry;
>> +	long pipe_ino;
>> +
>> +	if (!for_dump)
>> +		return 0;
>> +
>> +	entry = xmalloc(sizeof(*entry));
>> +	if (!entry)
>> +		return -1;
>> +	autofs_entry__init(entry);
>> +
>> +	if (parse_options(pm->options, &entry->fd, &entry->timeout,
>> +			  &entry->minproto, &entry->maxproto, &entry->mode,
>> +			  &entry->pgrp, &entry->uid, &entry->gid, &pipe_ino))
> How about passing single entry here instead of a bunch of pointers?

Yep, can do it.

>> +		return -1;
>> +
>> +	if (entry->uid != AUTOFS_OPT_UNKNOWN)
>> +		entry->has_uid = true;
>> +	if (entry->gid != AUTOFS_OPT_UNKNOWN)
>> +		entry->has_gid = true;
>> +
>> +	if (entry->fd != AUTOFS_CATATONIC_FD) {
>> +		int found, read_fd;
>> +
>> +		read_fd = autofs_find_read_fd(entry->pgrp, pipe_ino);
>> +		if (read_fd < 0)
>> +			return -1;
>> +
>> +		/* Let' check whether write end is still open */
>> +		found = autofs_kernel_pipe_alive(entry->pgrp, entry->fd, pipe_ino);
>> +		if (found < 0) {
>> +			pr_err("Failed to check fd %d in process %d\n",
>> +					entry->fd, entry->pgrp);
>> +			return -1;
>> +		}
>> +		/* Write end is absent. we need to carry read end to restore. */
>> +		if (!found) {
>> +			entry->has_read_fd = true;
>> +			entry->read_fd = read_fd;
>> +		}
>> +	}
>> +
>> +	pm->autofs = entry;
>> +
>> +	return 0;
>> +}
>> diff --git a/include/autofs.h b/include/autofs.h
>> index b30d915..9770835 100644
>> --- a/include/autofs.h
>> +++ b/include/autofs.h
>> @@ -5,4 +5,7 @@
>>   #define AUTOFS_MINOR	235
>>   #endif
>>   
>> +struct mount_info;
>> +int autofs_parse(struct mount_info *pm, bool for_dump);
>> +
>>   #endif
>> diff --git a/mount.c b/mount.c
>> index 645c4b4..69c69e1 100644
>> --- a/mount.c
>> +++ b/mount.c
>> @@ -27,6 +27,7 @@
>>   #include "kerndat.h"
>>   #include "fs-magic.h"
>>   #include "sysfs_parse.h"
>> +#include "autofs.h"
>>   
>>   #include "protobuf/mnt.pb-c.h"
>>   #include "protobuf/binfmt-misc.pb-c.h"
>> @@ -1694,6 +1695,11 @@ static struct fstype fstypes[32] = {
>>   		.name = "overlay",
>>   		.code = FSTYPE__OVERLAYFS,
>>   		.parse = overlayfs_parse,
>> +	}, {
>> +		.name = "autofs",
>> +		.code = FSTYPE__AUTOFS,
>> +		.parse = autofs_parse,
>> +		.restore = always_fail,
>>   	},
>>   };
>>   
>>
>> _______________________________________________
>> CRIU mailing list
>> CRIU at openvz.org
>> https://lists.openvz.org/mailman/listinfo/criu
>> .
>>



More information about the CRIU mailing list