On Thu, Mar 05, 2009 at 08:38:57AM -0800, Dave Hansen wrote:
> This takes a suggestion of Ingo's along with comments from lots of
> other people.  It can track whether a given file is able to be
> checkpointed.  It introduces a f_op to allow easy customization
> like the reset of the VFS.

Here is how alternative looks like
* without touching VFS at all
* without adding default handlers
* without duplicate code every ->checkpoint hook will have
* without largely useless "special file" messages
  (what's so special about it?)
* without adding userspace-visible /proc/*/checkpointable 
* without recalculating "checkpointable" property on fs_struct
  on every C/R=y kernel.

* with "ban by default" policy as well
* with error message immediatly understandable by developer:

        cr_check_file: can't checkpoint file f61a0f40, ->f_op = 
socket_file_ops+0x0/0x1c0

It may lack some printk, but printks are trivial to insert including
using d_path for precise info.



static int cr_check_file(struct file *file)
{
        struct inode *inode = file->f_path.dentry->d_inode;
        unsigned int major, minor;

        if (d_unhashed(file->f_path.dentry))
                return -EINVAL;
#ifdef CONFIG_SECURITY
        if (file->f_security)
                return -EINVAL;
#endif
#ifdef CONFIG_EPOLL
        spin_lock(&file->f_ep_lock);
        if (!list_empty(&file->f_ep_links)) {
                spin_unlock(&file->f_ep_lock);
                return -EINVAL;
        }
        spin_unlock(&file->f_ep_lock);
#endif

        switch (inode->i_mode & S_IFMT) {
        case S_IFREG:
        case S_IFDIR:
                /* Likely on-disk filesystem. */
                /* FIXME: FUSE, NFS, other networking filesystems */
                if (inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV)
                        return 0;
                break;
        case S_IFBLK:
                major = imajor(inode);
                minor = iminor(inode);
                printk("%s: can't checkpoint block device %u:%u, ->f_op = 
%pS\n", __func__, major, minor, file->f_op);
                return -EINVAL;
        case S_IFCHR:
                major = imajor(inode);
                minor = iminor(inode);
                if (major == UNIX98_PTY_SLAVE_MAJOR)
                        return 0;
                printk("%s: can't checkpoint char device %u:%u, ->f_op = 
%pS\n", __func__, major, minor, file->f_op);
                return -EINVAL;
        case S_IFIFO:
                break;
        case S_IFSOCK:
                return 0;
        case S_IFLNK:
                /* One can't open symlink. */
                BUG();
        }
        printk("%s: can't checkpoint file %p, ->f_op = %pS\n", __func__, file, 
file->f_op);
        return -EINVAL;
}

static int __cr_collect_file(struct cr_context *ctx, struct file *file)
{
        struct cr_object *obj;

        obj = cr_find_obj_by_ptr(ctx, file, CR_CTX_FILE);
        if (obj) {
                obj->o_count++;
                return 0;
        }

        obj = cr_object_create(file);
        if (!obj)
                return -ENOMEM;
        list_add_tail(&obj->o_list, &ctx->cr_obj[CR_CTX_FILE]);
        printk("collect file %p\n", file);
        return 0;
}

int cr_collect_file(struct cr_context *ctx, struct file *file)
{
        int rv;

        rv = cr_check_file(file);
        if (rv < 0)
                return rv;
        return __cr_collect_file(ctx, file);
}
_______________________________________________
Containers mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/containers

_______________________________________________
Devel mailing list
[email protected]
https://openvz.org/mailman/listinfo/devel

Reply via email to