static void handle_node_add(struct rpc_desc *rpc_desc, void *data, size_t size) { struct hotplug_context *ctx; struct krg_namespace *ns = find_get_krg_ns(); bool master = rpc_desc_get_client(rpc_desc) == kerrighed_node_id; char *page; int ret; BUG_ON(!ns); ctx = hotplug_ctx_alloc(ns); put_krg_ns(ns); if (!ctx) goto out_failed; ctx->node_set = *(struct hotplug_node_set *)data; if (!master) { mutex_lock(&hotplug_mutex); ret = rpc_connect_mask(ctx->ns->rpc_comm, &ctx->node_set.v); if (ret) goto out_failed_unlock; } ret = __nodes_add(ctx); if (ret) goto out_failed_close; hotplug_ctx_put(ctx); page = (char *)__get_free_page(GFP_KERNEL); if (page) { ret = krgnodelist_scnprintf(page, PAGE_SIZE, krgnode_online_map); BUG_ON(ret >= PAGE_SIZE); printk("Kerrighed is running on %d nodes: %s\n", num_online_krgnodes(), page); free_page((unsigned long)page); } else { printk("Kerrighed is running on %d nodes\n", num_online_krgnodes()); } if (!master) mutex_unlock(&hotplug_mutex); local_add_done(rpc_desc); return; out_failed_close: if (master) goto out_failed_put; rpc_close_mask(ctx->ns->rpc_comm, &ctx->node_set.v); out_failed_unlock: mutex_unlock(&hotplug_mutex); out_failed_put: hotplug_ctx_put(ctx); out_failed: printk("kerrighed: [ADD] Failed to add nodes!\n"); }
void get_physical_root(struct path *root) { struct krg_namespace *krg_ns = find_get_krg_ns(); BUG_ON(!krg_ns); root->mnt = krg_ns->root_nsproxy.mnt_ns->root; root->dentry = root->mnt->mnt_root; path_get(root); put_krg_ns(krg_ns); while (d_mountpoint(root->dentry) && follow_down(&root->mnt, &root->dentry)) ; }
static void handle_node_remove(struct rpc_desc *desc, void *data, size_t size) { struct hotplug_context *ctx; struct krg_namespace *ns = find_get_krg_ns(); char *page; int ret; BUG_ON(!ns); ctx = hotplug_ctx_alloc(ns); put_krg_ns(ns); if (!ctx) { printk("kerrighed: Failed to remove nodes!\n"); return; } ctx->node_set = *(struct hotplug_node_set *)data; mutex_lock(&hotplug_mutex); if (krgnode_isset(kerrighed_node_id, ctx->node_set.v)) { do_local_node_remove(desc, ctx); hotplug_ctx_put(ctx); printk("kerrighed: Node removed\n"); mutex_unlock(&hotplug_mutex); return; } do_other_node_remove(desc, ctx); hotplug_ctx_put(ctx); page = (char *)__get_free_page(GFP_KERNEL); if (page) { ret = krgnodelist_scnprintf(page, PAGE_SIZE, krgnode_online_map); BUG_ON(ret >= PAGE_SIZE); printk("Kerrighed is running on %d nodes: %s\n", num_online_krgnodes(), page); free_page((unsigned long)page); } else { printk("Kerrighed is running on %d nodes\n", num_online_krgnodes()); } mutex_unlock(&hotplug_mutex); }
void chroot_to_physical_root(struct prev_root *prev_root) { struct krg_namespace *krg_ns = find_get_krg_ns(); struct fs_struct *fs = current->fs; struct path root, prev_pwd; BUG_ON(!krg_ns); put_krg_ns(krg_ns); // BUG_ON(fs->users != 1); get_physical_root(&root); write_lock(&fs->lock); prev_root->path = fs->root; fs->root = root; path_get(&root); prev_pwd = fs->pwd; fs->pwd = root; write_unlock(&fs->lock); path_put(&prev_pwd); BUG_ON(prev_root->path.mnt->mnt_ns != current->nsproxy->mnt_ns); prev_root->nsproxy = current->nsproxy; rcu_assign_pointer(current->nsproxy, &krg_ns->root_nsproxy); }