COMMAND("osd pool create " \
"name=pool,type=CephPoolname " \
"name=pg_num,type=CephInt,range=0 " \
- "name=pgp_num,type=CephInt,range=0,req=false", \
+ "name=pgp_num,type=CephInt,range=0,req=false" \
+ "name=properties,type=CephString,n=N,req=false,goodchars=[A-Za-z0-9-_.=]", \
"create pool", "osd", "rw", "cli,rest")
COMMAND("osd pool delete " \
"name=pool,type=CephPoolname " \
MonSession *session = m->get_session();
if (!session)
return -EPERM;
+ vector<string> properties;
if (m->auid)
- return prepare_new_pool(m->name, m->auid, m->crush_rule, 0, 0);
+ return prepare_new_pool(m->name, m->auid, m->crush_rule, 0, 0, properties);
else
- return prepare_new_pool(m->name, session->auid, m->crush_rule, 0, 0);
+ return prepare_new_pool(m->name, session->auid, m->crush_rule, 0, 0, properties);
}
/**
* @param crush_rule The crush rule to use. If <0, will use the system default
* @param pg_num The pg_num to use. If set to 0, will use the system default
* @param pgp_num The pgp_num to use. If set to 0, will use the system default
+ * @param properties An opaque list of key[=value] pairs for pool configuration
*
* @return 0 in all cases. That's silly.
*/
int OSDMonitor::prepare_new_pool(string& name, uint64_t auid, int crush_rule,
- unsigned pg_num, unsigned pgp_num)
+ unsigned pg_num, unsigned pgp_num,
+ const vector<string> &properties)
{
for (map<int64_t,string>::iterator p = pending_inc.new_pool_names.begin();
p != pending_inc.new_pool_names.end();
pi->set_pgp_num(pgp_num ? pgp_num : g_conf->osd_pool_default_pgp_num);
pi->last_change = pending_inc.epoch;
pi->auid = auid;
+ for (vector<string>::const_iterator i = properties.begin();
+ i != properties.end();
+ i++) {
+ size_t equal = i->find('=');
+ if (equal != string::npos)
+ pi->properties[*i] = string();
+ else {
+ const string key = i->substr(0, equal);
+ const string value = i->substr(equal);
+ pi->properties[key] = value;
+ }
+ }
pending_inc.new_pool_names[pool] = name;
return 0;
}
goto reply;
}
+ vector<string> properties;
+ cmd_getval(g_ceph_context, cmdmap, "properties", properties);
+
err = prepare_new_pool(poolstr, 0, // auid=0 for admin created pool
-1, // default crush rule
- pg_num, pgp_num);
+ pg_num, pgp_num,
+ properties);
if (err < 0 && err != -EEXIST) {
goto reply;
}
bool prepare_pool_op_create (MPoolOp *m);
bool prepare_pool_op_delete(MPoolOp *m);
int prepare_new_pool(string& name, uint64_t auid, int crush_rule,
- unsigned pg_num, unsigned pgp_num);
+ unsigned pg_num, unsigned pgp_num,
+ const vector<string> &properties);
int prepare_new_pool(MPoolOp *m);
void update_pool_flags(int64_t pool_id, uint64_t flags);
f->dump_int("read_tier", read_tier);
f->dump_int("write_tier", write_tier);
f->dump_string("cache_mode", get_cache_mode_name());
+ f->open_array_section("properties");
+ for (map<string,string>::const_iterator i = properties.begin();
+ i != properties.end();
+ ++i) {
+ string name = i->first;
+ f->dump_string(name.c_str(), i->second);
+ }
+ f->close_section();
}
return;
}
- ENCODE_START(9, 5, bl);
+ ENCODE_START(10, 5, bl);
::encode(type, bl);
::encode(size, bl);
::encode(crush_ruleset, bl);
::encode(c, bl);
::encode(read_tier, bl);
::encode(write_tier, bl);
+ ::encode(properties, bl);
ENCODE_FINISH(bl);
}
::decode(read_tier, bl);
::decode(write_tier, bl);
}
+ if (struct_v >= 10) {
+ ::decode(properties, bl);
+ }
DECODE_FINISH(bl);
calc_pg_masks();
}
a.cache_mode = CACHEMODE_WRITEBACK;
a.read_tier = 1;
a.write_tier = 1;
+ a.properties["p-1"] = "v-1";
+ a.properties["empty"] = string();
o.push_back(new pg_pool_t(a));
}
public:
+ map<string,string> properties; /// interpreted according to the pool type
epoch_t last_change; /// most recent epoch changed, exclusing snapshot changes
snapid_t snap_seq; /// seq for per-pool snapshot
epoch_t snap_epoch; /// osdmap epoch of last snap