drbd: Allow to pass resource options to the new-resource command
authorAndreas Gruenbacher <agruen@linbit.com>
Thu, 16 Jun 2011 15:58:02 +0000 (17:58 +0200)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Thu, 8 Nov 2012 15:57:46 +0000 (16:57 +0100)
This is equivalent to how the attach and connect commands work.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_nl.c

index 6d6d105..ece2e4a 100644 (file)
@@ -1379,7 +1379,8 @@ extern int conn_lowest_minor(struct drbd_tconn *tconn);
 enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor, int vnr);
 extern void drbd_minor_destroy(struct kref *kref);
 
-struct drbd_tconn *conn_create(const char *name);
+extern int set_resource_options(struct drbd_tconn *tconn, struct res_opts *res_opts);
+extern struct drbd_tconn *conn_create(const char *name, struct res_opts *res_opts);
 extern void conn_destroy(struct kref *kref);
 struct drbd_tconn *conn_get_by_name(const char *name);
 extern struct drbd_tconn *conn_get_by_addrs(void *my_addr, int my_addr_len,
@@ -1397,7 +1398,6 @@ extern int is_valid_ar_handle(struct drbd_request *, sector_t);
 
 
 /* drbd_nl.c */
-extern void drbd_set_res_opts_defaults(struct res_opts *r);
 extern int drbd_msg_put_info(const char *info);
 extern void drbd_suspend_io(struct drbd_conf *mdev);
 extern void drbd_resume_io(struct drbd_conf *mdev);
index 79f275d..933d476 100644 (file)
@@ -2479,8 +2479,47 @@ void conn_free_crypto(struct drbd_tconn *tconn)
        tconn->int_dig_vv = NULL;
 }
 
+int set_resource_options(struct drbd_tconn *tconn, struct res_opts *res_opts)
+{
+       cpumask_var_t new_cpu_mask;
+       int err;
+
+       if (!zalloc_cpumask_var(&new_cpu_mask, GFP_KERNEL))
+               return -ENOMEM;
+               /*
+               retcode = ERR_NOMEM;
+               drbd_msg_put_info("unable to allocate cpumask");
+               */
+
+       /* silently ignore cpu mask on UP kernel */
+       if (nr_cpu_ids > 1 && res_opts->cpu_mask[0] != 0) {
+               /* FIXME: Get rid of constant 32 here */
+               err = __bitmap_parse(res_opts->cpu_mask, 32, 0,
+                               cpumask_bits(new_cpu_mask), nr_cpu_ids);
+               if (err) {
+                       conn_warn(tconn, "__bitmap_parse() failed with %d\n", err);
+                       /* retcode = ERR_CPU_MASK_PARSE; */
+                       goto fail;
+               }
+       }
+       tconn->res_opts = *res_opts;
+       if (!cpumask_equal(tconn->cpu_mask, new_cpu_mask)) {
+               cpumask_copy(tconn->cpu_mask, new_cpu_mask);
+               drbd_calc_cpu_mask(tconn);
+               tconn->receiver.reset_cpu_mask = 1;
+               tconn->asender.reset_cpu_mask = 1;
+               tconn->worker.reset_cpu_mask = 1;
+       }
+       err = 0;
+
+fail:
+       free_cpumask_var(new_cpu_mask);
+       return err;
+
+}
+
 /* caller must be under genl_lock() */
-struct drbd_tconn *conn_create(const char *name)
+struct drbd_tconn *conn_create(const char *name, struct res_opts *res_opts)
 {
        struct drbd_tconn *tconn;
 
@@ -2500,6 +2539,9 @@ struct drbd_tconn *conn_create(const char *name)
        if (!zalloc_cpumask_var(&tconn->cpu_mask, GFP_KERNEL))
                goto fail;
 
+       if (set_resource_options(tconn, res_opts))
+               goto fail;
+
        if (!tl_init(tconn))
                goto fail;
 
@@ -2520,8 +2562,6 @@ struct drbd_tconn *conn_create(const char *name)
        drbd_thread_init(tconn, &tconn->worker, drbd_worker, "worker");
        drbd_thread_init(tconn, &tconn->asender, drbd_asender, "asender");
 
-       drbd_set_res_opts_defaults(&tconn->res_opts);
-
        kref_init(&tconn->kref);
        list_add_tail_rcu(&tconn->all_tconn, &drbd_tconns);
 
index e7933e0..930af5d 100644 (file)
@@ -2335,15 +2335,9 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
        return 0;
 }
 
-void drbd_set_res_opts_defaults(struct res_opts *r)
-{
-       return set_res_opts_defaults(r);
-}
-
 int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
 {
        enum drbd_ret_code retcode;
-       cpumask_var_t new_cpu_mask;
        struct drbd_tconn *tconn;
        struct res_opts res_opts;
        int err;
@@ -2355,12 +2349,6 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
                goto fail;
        tconn = adm_ctx.tconn;
 
-       if (!zalloc_cpumask_var(&new_cpu_mask, GFP_KERNEL)) {
-               retcode = ERR_NOMEM;
-               drbd_msg_put_info("unable to allocate cpumask");
-               goto fail;
-       }
-
        res_opts = tconn->res_opts;
        if (should_set_defaults(info))
                set_res_opts_defaults(&res_opts);
@@ -2372,31 +2360,14 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
                goto fail;
        }
 
-       /* silently ignore cpu mask on UP kernel */
-       if (nr_cpu_ids > 1 && res_opts.cpu_mask[0] != 0) {
-               err = __bitmap_parse(res_opts.cpu_mask, 32, 0,
-                               cpumask_bits(new_cpu_mask), nr_cpu_ids);
-               if (err) {
-                       conn_warn(tconn, "__bitmap_parse() failed with %d\n", err);
-                       retcode = ERR_CPU_MASK_PARSE;
-                       goto fail;
-               }
-       }
-
-
-       tconn->res_opts = res_opts;
-
-       if (!cpumask_equal(tconn->cpu_mask, new_cpu_mask)) {
-               cpumask_copy(tconn->cpu_mask, new_cpu_mask);
-               drbd_calc_cpu_mask(tconn);
-               tconn->receiver.reset_cpu_mask = 1;
-               tconn->asender.reset_cpu_mask = 1;
-               tconn->worker.reset_cpu_mask = 1;
+       err = set_resource_options(tconn, &res_opts);
+       if (err) {
+               retcode = ERR_INVALID_REQUEST;
+               if (err == -ENOMEM)
+                       retcode = ERR_NOMEM;
        }
 
 fail:
-       free_cpumask_var(new_cpu_mask);
-
        drbd_adm_finish(info, retcode);
        return 0;
 }
@@ -3012,6 +2983,8 @@ drbd_check_resource_name(const char *name)
 int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info)
 {
        enum drbd_ret_code retcode;
+       struct res_opts res_opts;
+       int err;
 
        retcode = drbd_adm_prepare(skb, info, 0);
        if (!adm_ctx.reply_skb)
@@ -3019,6 +2992,14 @@ int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info)
        if (retcode != NO_ERROR)
                goto out;
 
+       set_res_opts_defaults(&res_opts);
+       err = res_opts_from_attrs(&res_opts, info);
+       if (err && err != -ENOMSG) {
+               retcode = ERR_MANDATORY_TAG;
+               drbd_msg_put_info(from_attrs_err_to_txt(err));
+               goto out;
+       }
+
        retcode = drbd_check_resource_name(adm_ctx.resource_name);
        if (retcode != NO_ERROR)
                goto out;
@@ -3032,7 +3013,7 @@ int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info)
                goto out;
        }
 
-       if (!conn_create(adm_ctx.resource_name))
+       if (!conn_create(adm_ctx.resource_name, &res_opts))
                retcode = ERR_NOMEM;
 out:
        drbd_adm_finish(info, retcode);