Example #1
0
int migrate_nfs_update_server(struct nfs_server *server, const char *hostname,
                              struct sockaddr *sap, size_t salen, struct net *net)
{
    struct nfs_client *clp = server->nfs_client;
    struct rpc_clnt *clnt = server->client;
    struct xprt_create xargs = {
        .ident		= clp->cl_proto,
        .net		= net,
        .dstaddr	= sap,
        .addrlen	= salen,
        .servername	= hostname,
    };
    char buf[INET6_ADDRSTRLEN + 1];
    struct sockaddr_storage address;
    struct sockaddr *localaddr = (struct sockaddr *)&address;
    int error;

    dfprintk(MOUNT, "zql: --> %s: move FSID %llx:%llx to \"%s\")\n", __func__,
             (unsigned long long)server->fsid.major,
             (unsigned long long)server->fsid.minor,
             hostname);

    error = rpc_switch_client_transport(clnt, &xargs, clnt->cl_timeout);
    if (error != 0) {
        dfprintk(MOUNT, "zql: <-- %s(): rpc_switch_client_transport returned %d\n",
                 __func__, error);
        goto out;
    }

    error = rpc_localaddr(clnt, localaddr, sizeof(address));
    if (error != 0) {
        dfprintk(MOUNT, "zql: <-- %s(): rpc_localaddr returned %d\n",
                 __func__, error);
        goto out;
    }

    error = -EAFNOSUPPORT;
    if (rpc_ntop(localaddr, buf, sizeof(buf)) == 0) {
        dfprintk(MOUNT, "zql: <-- %s(): rpc_ntop returned %d\n",
                 __func__, error);
        goto out;
    }

    nfs_server_remove_lists(server);
    error = migrate_nfs_set_client(server, hostname, sap, salen, buf,
                                   clp->cl_rpcclient->cl_auth->au_flavor,
                                   clp->cl_proto, clnt->cl_timeout,
                                   clp->cl_minorversion, net);
    nfs_put_client(clp);
    if (error != 0) {
        nfs_server_insert_lists(server);
        dfprintk(MOUNT, "zql: <-- %s(): nfs4_set_client returned %d\n",
                 __func__, error);
        goto out;
    }

    if (server->nfs_client->cl_hostname == NULL)
        server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL);
    nfs_server_insert_lists(server);

    error = migrate_nfs_probe_destination(server);
    if (error < 0) {
        dfprintk(MOUNT, "zql: error in migrate_nfs_probe_destination\n");
        goto out;
    }

    dfprintk(MOUNT, "zql: <-- %s() succeeded\n", __func__);

out:
    dfprintk(MOUNT, "zql: error in %s()\n", __func__);
    return error;
}

static void zql_update_server(struct nfs_server *server)
{
    /*
     * we do not have to free server,
     * instead, we only update struct nfs_server.
     */
    //nfs_free_server(server);
    /* free old nfs_client, though we can leave it there and use it when switch back */
    //server->nfs_client->rpc_ops->free_client(server->nfs_client);
    //struct nfs_server parent_server;
    //struct nfs_client *parent_client;
    //struct nfs_subversion *nfs_mod;
    struct nfs_parsed_mount_data *parsed;

    //char raw_data[] = "addr=162.105.146.169,vers=3,proto=tcp,mountvers=3,mountproto=udp,mountport=20048";

    /* keep old server parameter, copy original server to a temporary parameter */
    //parent_server = *server;
    //parent_client = parent_server.nfs_client;

    /* generate nfs_parsed_mount_data */
    parsed = nfs_alloc_parsed_mount_data();
    if (parsed == NULL)
        dfprintk(MOUNT, "zql: nfs_alloc_parsed_mount_data error\n");
    /* init nfs_parsed_mount_data */
    if (nfs_zql_control == 168)
        migrate_nfs_validate_text_mount_data168(/*raw_data, */parsed/*, dev_name*/);
    else if (nfs_zql_control == 169)
        migrate_nfs_validate_text_mount_data169(parsed);
    else
        dfprintk(MOUNT, "zql: nfs_zql_control error\n");

    migrate_nfs_update_server(server, parsed->nfs_server.hostname, (struct sockaddr *)&parsed->nfs_server.address,
                              parsed->nfs_server.addrlen, parsed->net);

    /*nfs_mod = get_nfs_version(parsed->version);
    if (IS_ERR(nfs_mod))
    	dfprintk(MOUNT, "zql: get_nfs_version error\n");*/
    /* init server->nfs_client */
    //migrate_nfs_set_client(server, parsed, nfs_mod, parent_server.client->cl_timeout);

    //nfs_init_server_rpcclient(server, parent_server.client->cl_timeout, parsed->selected_flavor);

    //put_nfs_version(nfs_mod);

    nfs_free_parsed_mount_data(parsed);

    return;
}

static void zql_control_test(struct nfs_server *server)
{
    if (nfs_zql_control == 5 || nfs_zql_control == 168
            || nfs_zql_control == 169) {
        dfprintk(MOUNT, "zql: control start ... %d\n", nfs_zql_control);
        while (nfs_zql_control == 5) {
            msleep_interruptible(500);
        }
        if (nfs_zql_control == 168 || nfs_zql_control == 169) {
            spin_lock(&zql_switch_status);
            if (switch_status == 0) {
                switch_status = 1;
                spin_unlock(&zql_switch_status);
                dfprintk(MOUNT, "zql: switch succeed\n");
                dfprintk(MOUNT, "zql: start update server\n");
                zql_update_server(server);
                switch_status = 0;
                nfs_zql_control = 10;
                dfprintk(MOUNT, "zql: update server done\n");
            } else {
                spin_unlock(&zql_switch_status);
                dfprintk(MOUNT, "zql: switch_status check\n");
                while (switch_status == 1) {
                    msleep_interruptible(100);
                }
                dfprintk(MOUNT, "zql: switch_status done\n");
            }
        }
        else if (nfs_zql_control == 4)
            dfprintk(MOUNT, "zql: switch failed\n");
        else
            dfprintk(MOUNT, "zql: unknown failure\n");
    }
}
/* zql code end */

static const struct inode_operations nfs3_dir_inode_operations = {
    .create		= nfs_create,
    .lookup		= nfs_lookup,
    .link		= nfs_link,
    .unlink		= nfs_unlink,
    .symlink	= nfs_symlink,
    .mkdir		= nfs_mkdir,
    .rmdir		= nfs_rmdir,
    .mknod		= nfs_mknod,
    .rename		= nfs_rename,
    .permission	= nfs_permission,
    .getattr	= nfs_getattr,
    .setattr	= nfs_setattr,
#ifdef CONFIG_NFS_V3_ACL
    .listxattr	= nfs3_listxattr,
    .getxattr	= generic_getxattr,
    .setxattr	= generic_setxattr,
    .removexattr	= generic_removexattr,
    .get_acl	= nfs3_get_acl,
    .set_acl	= nfs3_set_acl,
#endif
};

static const struct inode_operations nfs3_file_inode_operations = {
    .permission	= nfs_permission,
    .getattr	= nfs_getattr,
    .setattr	= nfs_setattr,
#ifdef CONFIG_NFS_V3_ACL
    .listxattr	= nfs3_listxattr,
    .getxattr	= generic_getxattr,
    .setxattr	= generic_setxattr,
    .removexattr	= generic_removexattr,
    .get_acl	= nfs3_get_acl,
    .set_acl	= nfs3_set_acl,
#endif
};

const struct nfs_rpc_ops nfs_v3_clientops = {
    .version	= 3,			/* protocol version */
    .dentry_ops	= &nfs_dentry_operations,
    .dir_inode_ops	= &nfs3_dir_inode_operations,
    .file_inode_ops	= &nfs3_file_inode_operations,
    .file_ops	= &nfs_file_operations,
    .getroot	= nfs3_proc_get_root,
    .submount	= nfs_submount,
    .try_mount	= nfs_try_mount,
    .getattr	= nfs3_proc_getattr,
    .setattr	= nfs3_proc_setattr,
    .lookup		= nfs3_proc_lookup,
    .access		= nfs3_proc_access,
    .readlink	= nfs3_proc_readlink,
    .create		= nfs3_proc_create,
    .remove		= nfs3_proc_remove,
    .unlink_setup	= nfs3_proc_unlink_setup,
    .unlink_rpc_prepare = nfs3_proc_unlink_rpc_prepare,
    .unlink_done	= nfs3_proc_unlink_done,
    .rename_setup	= nfs3_proc_rename_setup,
    .rename_rpc_prepare = nfs3_proc_rename_rpc_prepare,
    .rename_done	= nfs3_proc_rename_done,
    .link		= nfs3_proc_link,
    .symlink	= nfs3_proc_symlink,
    .mkdir		= nfs3_proc_mkdir,
    .rmdir		= nfs3_proc_rmdir,
    .readdir	= nfs3_proc_readdir,
    .mknod		= nfs3_proc_mknod,
    .statfs		= nfs3_proc_statfs,
    .fsinfo		= nfs3_proc_fsinfo,
    .pathconf	= nfs3_proc_pathconf,
    .decode_dirent	= nfs3_decode_dirent,
    .pgio_rpc_prepare = nfs3_proc_pgio_rpc_prepare,
    .read_setup	= nfs3_proc_read_setup,
    .read_done	= nfs3_read_done,
    .write_setup	= nfs3_proc_write_setup,
    .write_done	= nfs3_write_done,
    .commit_setup	= nfs3_proc_commit_setup,
    .commit_rpc_prepare = nfs3_proc_commit_rpc_prepare,
    .commit_done	= nfs3_commit_done,
    .lock		= nfs3_proc_lock,
    .clear_acl_cache = forget_all_cached_acls,
    .close_context	= nfs_close_context,
    .have_delegation = nfs3_have_delegation,
    .return_delegation = nfs3_return_delegation,
    .alloc_client	= nfs_alloc_client,
    .init_client	= nfs_init_client,
    .free_client	= nfs_free_client,
    .create_server	= nfs3_create_server,
    .clone_server	= nfs3_clone_server,
};
Example #2
0
/**
 * nfs4_init_client - Initialise an NFS4 client record
 *
 * @clp: nfs_client to initialise
 * @timeparms: timeout parameters for underlying RPC transport
 * @ip_addr: callback IP address in presentation format
 * @authflavor: authentication flavor for underlying RPC transport
 *
 * Returns pointer to an NFS client, or an ERR_PTR value.
 */
struct nfs_client *nfs4_init_client(struct nfs_client *clp,
				    const struct rpc_timeout *timeparms,
				    const char *ip_addr,
				    rpc_authflavor_t authflavour)
{
	char buf[INET6_ADDRSTRLEN + 1];
	struct nfs_client *old;
	int error;

	if (clp->cl_cons_state == NFS_CS_READY) {
		/* the client is initialised already */
		dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp);
		return clp;
	}

	/* Check NFS protocol revision and initialize RPC op vector */
	clp->rpc_ops = &nfs_v4_clientops;

	if (clp->cl_minorversion != 0)
		__set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags);
	__set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
	error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I);
	if (error == -EINVAL)
		error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX);
	if (error < 0)
		goto error;

	/* If no clientaddr= option was specified, find a usable cb address */
	if (ip_addr == NULL) {
		struct sockaddr_storage cb_addr;
		struct sockaddr *sap = (struct sockaddr *)&cb_addr;

		error = rpc_localaddr(clp->cl_rpcclient, sap, sizeof(cb_addr));
		if (error < 0)
			goto error;
		error = rpc_ntop(sap, buf, sizeof(buf));
		if (error < 0)
			goto error;
		ip_addr = (const char *)buf;
	}
	strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));

	error = nfs_idmap_new(clp);
	if (error < 0) {
		dprintk("%s: failed to create idmapper. Error = %d\n",
			__func__, error);
		goto error;
	}
	__set_bit(NFS_CS_IDMAP, &clp->cl_res_state);

	error = nfs4_init_client_minor_version(clp);
	if (error < 0)
		goto error;

	if (!nfs4_has_session(clp))
		nfs_mark_client_ready(clp, NFS_CS_READY);

	error = nfs4_discover_server_trunking(clp, &old);
	if (error < 0)
		goto error;

	if (clp != old)
		clp->cl_preserve_clid = true;
	nfs_put_client(clp);
	return old;

error:
	nfs_mark_client_ready(clp, error);
	nfs_put_client(clp);
	dprintk("<-- nfs4_init_client() = xerror %d\n", error);
	return ERR_PTR(error);
}