Compare commits
15 Commits
Author | SHA1 | Date |
---|---|---|
Vitaliy Filippov | 23a9aa93b5 | |
Vitaliy Filippov | 2412d9e239 | |
Vitaliy Filippov | 9301c857b1 | |
Vitaliy Filippov | 3094358ec2 | |
Vitaliy Filippov | 87f666d2a2 | |
Vitaliy Filippov | bd7fe4ef8f | |
Vitaliy Filippov | 1b3f9a1416 | |
Vitaliy Filippov | a7b7354f38 | |
Vitaliy Filippov | 765befa22f | |
Vitaliy Filippov | 87b3ab94fe | |
Vitaliy Filippov | 2c0801f6e4 | |
Vitaliy Filippov | fd83fef1d9 | |
Vitaliy Filippov | 8d1067971b | |
Vitaliy Filippov | ae5af04fde | |
Vitaliy Filippov | 266d038b11 |
|
@ -64,6 +64,13 @@ jobs:
|
|||
# leak sanitizer sometimes crashes
|
||||
- run: cd /root/vitastor/build && ASAN_OPTIONS=detect_leaks=0 make -j16 test
|
||||
|
||||
npm_lint:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||
steps:
|
||||
- run: cd /root/vitastor/mon && npm run lint
|
||||
|
||||
test_add_osd:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
|
|
@ -2,6 +2,6 @@ cmake_minimum_required(VERSION 2.8.12)
|
|||
|
||||
project(vitastor)
|
||||
|
||||
set(VERSION "1.6.0")
|
||||
set(VERSION "1.6.1")
|
||||
|
||||
add_subdirectory(src)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
VERSION ?= v1.6.0
|
||||
VERSION ?= v1.6.1
|
||||
|
||||
all: build push
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ spec:
|
|||
capabilities:
|
||||
add: ["SYS_ADMIN"]
|
||||
allowPrivilegeEscalation: true
|
||||
image: vitalif/vitastor-csi:v1.6.0
|
||||
image: vitalif/vitastor-csi:v1.6.1
|
||||
args:
|
||||
- "--node=$(NODE_ID)"
|
||||
- "--endpoint=$(CSI_ENDPOINT)"
|
||||
|
|
|
@ -121,7 +121,7 @@ spec:
|
|||
privileged: true
|
||||
capabilities:
|
||||
add: ["SYS_ADMIN"]
|
||||
image: vitalif/vitastor-csi:v1.6.0
|
||||
image: vitalif/vitastor-csi:v1.6.1
|
||||
args:
|
||||
- "--node=$(NODE_ID)"
|
||||
- "--endpoint=$(CSI_ENDPOINT)"
|
||||
|
|
|
@ -5,7 +5,7 @@ package vitastor
|
|||
|
||||
const (
|
||||
vitastorCSIDriverName = "csi.vitastor.io"
|
||||
vitastorCSIDriverVersion = "1.6.0"
|
||||
vitastorCSIDriverVersion = "1.6.1"
|
||||
)
|
||||
|
||||
// Config struct fills the parameters of request or user input
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
vitastor (1.6.0-1) unstable; urgency=medium
|
||||
vitastor (1.6.1-1) unstable; urgency=medium
|
||||
|
||||
* Bugfixes
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ RUN set -e -x; \
|
|||
mkdir -p /root/packages/vitastor-$REL; \
|
||||
rm -rf /root/packages/vitastor-$REL/*; \
|
||||
cd /root/packages/vitastor-$REL; \
|
||||
cp -r /root/vitastor vitastor-1.6.0; \
|
||||
cd vitastor-1.6.0; \
|
||||
cp -r /root/vitastor vitastor-1.6.1; \
|
||||
cd vitastor-1.6.1; \
|
||||
ln -s /root/fio-build/fio-*/ ./fio; \
|
||||
FIO=$(head -n1 fio/debian/changelog | perl -pe 's/^.*\((.*?)\).*$/$1/'); \
|
||||
ls /usr/include/linux/raw.h || cp ./debian/raw.h /usr/include/linux/raw.h; \
|
||||
|
@ -51,8 +51,8 @@ RUN set -e -x; \
|
|||
rm -rf a b; \
|
||||
echo "dep:fio=$FIO" > debian/fio_version; \
|
||||
cd /root/packages/vitastor-$REL; \
|
||||
tar --sort=name --mtime='2020-01-01' --owner=0 --group=0 --exclude=debian -cJf vitastor_1.6.0.orig.tar.xz vitastor-1.6.0; \
|
||||
cd vitastor-1.6.0; \
|
||||
tar --sort=name --mtime='2020-01-01' --owner=0 --group=0 --exclude=debian -cJf vitastor_1.6.1.orig.tar.xz vitastor-1.6.1; \
|
||||
cd vitastor-1.6.1; \
|
||||
V=$(head -n1 debian/changelog | perl -pe 's/^.*\((.*?)\).*$/$1/'); \
|
||||
DEBFULLNAME="Vitaliy Filippov <vitalif@yourcmc.ru>" dch -D $REL -v "$V""$REL" "Rebuild for $REL"; \
|
||||
DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage --jobs=auto -sa; \
|
||||
|
|
|
@ -86,7 +86,11 @@ Parent node reference is required for intermediate tree nodes.
|
|||
Separate OSD settings are set in etc keys `/vitastor/config/osd/<number>`
|
||||
in JSON format `{"<key>":<value>}`.
|
||||
|
||||
As of now, two settings are supported:
|
||||
As of now, the following settings are supported:
|
||||
|
||||
- [reweight](#reweight)
|
||||
- [tags](#tags)
|
||||
- [noout](#noout)
|
||||
|
||||
## reweight
|
||||
|
||||
|
@ -109,6 +113,14 @@ subsets and then use a specific subset for pool instead of all OSDs.
|
|||
For example you can mark SSD OSDs with tag "ssd" and HDD OSDs with "hdd" and
|
||||
such tags will work as device classes.
|
||||
|
||||
## noout
|
||||
|
||||
- Type: boolean
|
||||
- Default: false
|
||||
|
||||
If set to true, [osd_out_time](monitor.en.md#osd_out_time) is ignored for this
|
||||
OSD and it's never removed from data distribution by the monitor.
|
||||
|
||||
# Pool parameters
|
||||
|
||||
## name
|
||||
|
|
|
@ -85,10 +85,11 @@
|
|||
Настройки отдельных OSD задаются в ключах etcd `/vitastor/config/osd/<number>`
|
||||
в JSON-формате `{"<key>":<value>}`.
|
||||
|
||||
На данный момент поддерживаются две настройки:
|
||||
На данный момент поддерживаются следующие настройки:
|
||||
|
||||
- [reweight](#reweight)
|
||||
- [tags](#tags)
|
||||
- [noout](#noout)
|
||||
|
||||
## reweight
|
||||
|
||||
|
@ -112,6 +113,14 @@
|
|||
всех. Можно, например, пометить SSD OSD тегом "ssd", а HDD тегом "hdd", в
|
||||
этом смысле теги работают аналогично классам устройств.
|
||||
|
||||
## noout
|
||||
|
||||
- Тип: булево (да/нет)
|
||||
- Значение по умолчанию: false
|
||||
|
||||
Если установлено в true, то [osd_out_time](monitor.ru.md#osd_out_time) для этого
|
||||
OSD игнорируется и OSD не удаляется из распределения данных монитором.
|
||||
|
||||
# Параметры
|
||||
|
||||
## name
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
module.exports = {
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:node/recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"plugins": [
|
||||
],
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
4
|
||||
],
|
||||
"brace-style": [
|
||||
"error",
|
||||
"allman",
|
||||
{ "allowSingleLine": true }
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"no-useless-escape": [
|
||||
"off"
|
||||
],
|
||||
"no-control-regex": [
|
||||
"off"
|
||||
],
|
||||
"no-empty": [
|
||||
"off"
|
||||
],
|
||||
"no-process-exit": [
|
||||
"off"
|
||||
],
|
||||
"node/shebang": [
|
||||
"off"
|
||||
]
|
||||
}
|
||||
};
|
|
@ -97,7 +97,6 @@ function scale_pg_history(prev_pg_history, prev_pgs, new_pgs)
|
|||
|
||||
function scale_pg_count(prev_pgs, new_pg_count)
|
||||
{
|
||||
const old_pg_count = prev_pgs.length;
|
||||
// Just for the lp_solve optimizer - pick a "previous" PG for each "new" one
|
||||
if (prev_pgs.length < new_pg_count)
|
||||
{
|
||||
|
|
|
@ -152,6 +152,7 @@ function parse_pg_dsl(text)
|
|||
else if (rule[2] === '(')
|
||||
{
|
||||
rule[2] = [];
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true)
|
||||
{
|
||||
if (i > tokens.length-1)
|
||||
|
|
|
@ -77,7 +77,7 @@ async function optimize_initial({ osd_weights, combinator, pg_count, pg_size = 3
|
|||
{
|
||||
if (osd !== NO_OSD)
|
||||
{
|
||||
let osd_pg_count = (osd_weights[osd]||0)/total_weight*pg_effsize*pg_count;
|
||||
let osd_pg_count = osd_weights[osd]/total_weight*pg_effsize*pg_count;
|
||||
lp += pg_per_osd[osd].join(' + ')+' <= '+osd_pg_count+';\n';
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ function calc_intersect_weights(old_pg_size, pg_size, pg_count, prev_weights, al
|
|||
{
|
||||
const intersect_count = ordered
|
||||
? pg.reduce((a, osd, i) => a + (prev_hash[osd] == 1+i ? 1 : 0), 0)
|
||||
: pg.reduce((a, osd, i) => a + (prev_hash[osd] ? 1 : 0), 0);
|
||||
: pg.reduce((a, osd) => a + (prev_hash[osd] ? 1 : 0), 0);
|
||||
if (max_int < intersect_count)
|
||||
{
|
||||
max_int = intersect_count;
|
||||
|
@ -299,7 +299,7 @@ async function optimize_change({ prev_pgs: prev_int_pgs, osd_weights, combinator
|
|||
)).join(' + ');
|
||||
const rm_osd_pg_count = (prev_pg_per_osd[osd]||[])
|
||||
.reduce((a, [ old_pg_name, space ]) => (a + (all_pgs_hash[old_pg_name] ? space : 0)), 0);
|
||||
const osd_pg_count = (osd_weights[osd]||0)*pg_effsize/total_weight*pg_count - rm_osd_pg_count;
|
||||
const osd_pg_count = osd_weights[osd]*pg_effsize/total_weight*pg_count - rm_osd_pg_count;
|
||||
lp += osd_sum + ' <= ' + osd_pg_count + ';\n';
|
||||
}
|
||||
}
|
||||
|
|
104
mon/mon.js
104
mon/mon.js
|
@ -37,7 +37,6 @@ const etcd_allow = new RegExp('^'+[
|
|||
'pg/state/[1-9]\\d*/[1-9]\\d*',
|
||||
'pg/stats/[1-9]\\d*/[1-9]\\d*',
|
||||
'pg/history/[1-9]\\d*/[1-9]\\d*',
|
||||
'pool/stats/[1-9]\\d*',
|
||||
'history/last_clean_pgs',
|
||||
'inode/stats/[1-9]\\d*/\\d+',
|
||||
'pool/stats/[1-9]\\d*',
|
||||
|
@ -215,7 +214,7 @@ const etcd_tree = {
|
|||
}, */
|
||||
pools: {},
|
||||
osd: {
|
||||
/* <id>: { reweight?: 1, tags?: [ 'nvme', ... ] }, ... */
|
||||
/* <id>: { reweight?: 1, tags?: [ 'nvme', ... ], noout?: true }, ... */
|
||||
},
|
||||
/* pgs: {
|
||||
hash: string,
|
||||
|
@ -585,7 +584,7 @@ class Mon
|
|||
now = Date.now();
|
||||
}
|
||||
tried[base] = now;
|
||||
const ok = await new Promise((ok, no) =>
|
||||
const ok = await new Promise(ok =>
|
||||
{
|
||||
const timer_id = setTimeout(() =>
|
||||
{
|
||||
|
@ -747,6 +746,7 @@ class Mon
|
|||
this.save_last_clean_running = true;
|
||||
// last_clean_pgs is used to avoid extra data move when observing a series of changes in the cluster
|
||||
const new_clean_pgs = { items: {} };
|
||||
// eslint-disable-next-line indent
|
||||
next_pool:
|
||||
for (const pool_id in this.state.config.pools)
|
||||
{
|
||||
|
@ -829,6 +829,7 @@ class Mon
|
|||
async become_master()
|
||||
{
|
||||
const state = { ...this.get_mon_state(), id: ''+this.etcd_lease_id };
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (1)
|
||||
{
|
||||
const res = await this.etcd_call('/kv/txn', {
|
||||
|
@ -873,32 +874,19 @@ class Mon
|
|||
levels.osd = levels.osd || 101;
|
||||
const tree = {};
|
||||
let up_osds = {};
|
||||
for (const node_id in this.state.config.node_placement||{})
|
||||
{
|
||||
const node_cfg = this.state.config.node_placement[node_id];
|
||||
if (/^\d+$/.exec(node_id))
|
||||
{
|
||||
node_cfg.level = 'osd';
|
||||
}
|
||||
if (!node_id || !node_cfg.level || !levels[node_cfg.level])
|
||||
{
|
||||
// All nodes must have non-empty IDs and valid levels
|
||||
continue;
|
||||
}
|
||||
tree[node_id] = { id: node_id, level: node_cfg.level, parent: node_cfg.parent, children: [] };
|
||||
}
|
||||
// This requires monitor system time to be in sync with OSD system times (at least to some extent)
|
||||
const down_time = Date.now()/1000 - this.config.osd_out_time;
|
||||
for (const osd_num of this.all_osds().sort((a, b) => a - b))
|
||||
{
|
||||
const stat = this.state.osd.stats[osd_num];
|
||||
if (stat && stat.size && (this.state.osd.state[osd_num] || Number(stat.time) >= down_time))
|
||||
const osd_cfg = this.state.config.osd[osd_num];
|
||||
let reweight = osd_cfg == null ? 1 : Number(osd_cfg.reweight);
|
||||
if (reweight < 0 || isNaN(reweight))
|
||||
reweight = 1;
|
||||
if (stat && stat.size && reweight && (this.state.osd.state[osd_num] || Number(stat.time) >= down_time ||
|
||||
osd_cfg && osd_cfg.noout))
|
||||
{
|
||||
// Numeric IDs are reserved for OSDs
|
||||
const osd_cfg = this.state.config.osd[osd_num];
|
||||
let reweight = osd_cfg == null ? 1 : Number(osd_cfg.reweight);
|
||||
if (reweight < 0 || isNaN(reweight))
|
||||
reweight = 1;
|
||||
if (this.state.osd.state[osd_num] && reweight > 0)
|
||||
{
|
||||
// React to down OSDs immediately
|
||||
|
@ -926,6 +914,29 @@ class Mon
|
|||
}
|
||||
}
|
||||
}
|
||||
for (const node_id in this.state.config.node_placement||{})
|
||||
{
|
||||
const node_cfg = this.state.config.node_placement[node_id];
|
||||
if (/^\d+$/.exec(node_id))
|
||||
{
|
||||
node_cfg.level = 'osd';
|
||||
}
|
||||
if (!node_id || !node_cfg.level || !levels[node_cfg.level] ||
|
||||
node_cfg.level === 'osd' && !tree[node_id])
|
||||
{
|
||||
// All nodes must have non-empty IDs and valid levels
|
||||
// OSDs have to actually exist
|
||||
continue;
|
||||
}
|
||||
tree[node_id] = tree[node_id] || {};
|
||||
tree[node_id].id = node_id;
|
||||
tree[node_id].level = node_cfg.level;
|
||||
tree[node_id].parent = node_cfg.parent;
|
||||
if (node_cfg.level !== 'osd')
|
||||
{
|
||||
tree[node_id].children = [];
|
||||
}
|
||||
}
|
||||
return { up_osds, levels, osd_tree: tree };
|
||||
}
|
||||
|
||||
|
@ -955,6 +966,25 @@ class Mon
|
|||
const parent = parent_level && parent_level < node_level ? node_cfg.parent : '';
|
||||
tree[parent].children.push(tree[node_id]);
|
||||
}
|
||||
// Delete empty nodes
|
||||
let deleted = 0;
|
||||
do
|
||||
{
|
||||
deleted = 0;
|
||||
for (const node_id in tree)
|
||||
{
|
||||
if (tree[node_id].level !== 'osd' && (!tree[node_id].children || !tree[node_id].children.length))
|
||||
{
|
||||
const parent = tree[node_id].parent;
|
||||
if (parent)
|
||||
{
|
||||
tree[parent].children = tree[parent].children.filter(c => c != tree[node_id]);
|
||||
}
|
||||
deleted++;
|
||||
delete tree[node_id];
|
||||
}
|
||||
}
|
||||
} while (deleted > 0);
|
||||
return tree;
|
||||
}
|
||||
|
||||
|
@ -991,7 +1021,7 @@ class Mon
|
|||
const key = b64(this.etcd_prefix+'/osd/state/'+osd_num);
|
||||
checks.push({ key, target: 'MOD', result: 'LESS', mod_revision: ''+this.etcd_watch_revision });
|
||||
}
|
||||
const res = await this.etcd_call('/kv/txn', {
|
||||
await this.etcd_call('/kv/txn', {
|
||||
compare: [
|
||||
{ key: b64(this.etcd_prefix+'/mon/master'), target: 'LEASE', lease: ''+this.etcd_lease_id },
|
||||
{ key: b64(this.etcd_prefix+'/config/pgs'), target: 'MOD', mod_revision: ''+this.etcd_watch_revision, result: 'LESS' },
|
||||
|
@ -1315,7 +1345,7 @@ class Mon
|
|||
for (const k in rules)
|
||||
{
|
||||
if (!levels[k] || typeof rules[k] !== 'string' &&
|
||||
(!rules[k] instanceof Array ||
|
||||
(!(rules[k] instanceof Array) ||
|
||||
rules[k].filter(s => typeof s !== 'string' && typeof s !== 'number').length > 0))
|
||||
{
|
||||
if (warn)
|
||||
|
@ -1429,7 +1459,15 @@ class Mon
|
|||
}
|
||||
console.log(`Pool ${pool_id} (${pool_cfg.name || 'unnamed'}):`);
|
||||
LPOptimizer.print_change_stats(optimize_result);
|
||||
const pg_effsize = Math.min(pool_cfg.pg_size, Object.keys(pool_tree).length);
|
||||
let pg_effsize = pool_cfg.pg_size;
|
||||
for (const pg of optimize_result.int_pgs)
|
||||
{
|
||||
const this_pg_size = pg.filter(osd => osd != LPOptimizer.NO_OSD).length;
|
||||
if (this_pg_size && this_pg_size < pg_effsize)
|
||||
{
|
||||
pg_effsize = this_pg_size;
|
||||
}
|
||||
}
|
||||
return {
|
||||
pool_id,
|
||||
pgs: optimize_result.int_pgs,
|
||||
|
@ -1511,11 +1549,14 @@ class Mon
|
|||
{
|
||||
continue;
|
||||
}
|
||||
const replicated = pool_cfg.scheme === 'replicated';
|
||||
const aff_osds = this.get_affinity_osds(pool_cfg, up_osds, osd_tree);
|
||||
this.reset_rng();
|
||||
for (let pg_num = 1; pg_num <= pool_cfg.pg_count; pg_num++)
|
||||
{
|
||||
if (!this.state.config.pgs.items[pool_id])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const pg_cfg = this.state.config.pgs.items[pool_id][pg_num];
|
||||
if (pg_cfg)
|
||||
{
|
||||
|
@ -1553,10 +1594,6 @@ class Mon
|
|||
|
||||
async apply_pool_pgs(results, up_osds, osd_tree, tree_hash)
|
||||
{
|
||||
if (!results.length)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
for (const pool_id in (this.state.config.pgs||{}).items||{})
|
||||
{
|
||||
// We should stop all PGs when deleting a pool or changing its PG count
|
||||
|
@ -1689,7 +1726,6 @@ class Mon
|
|||
|
||||
derive_osd_stats(st, prev, prev_diff)
|
||||
{
|
||||
const zero_stats = { op: { bps: 0n, iops: 0n, lat: 0n }, subop: { iops: 0n, lat: 0n }, recovery: { bps: 0n, iops: 0n } };
|
||||
const diff = { op_stats: {}, subop_stats: {}, recovery_stats: {}, inode_stats: {} };
|
||||
if (!st || !st.time || !prev || !prev.time || prev.time >= st.time)
|
||||
{
|
||||
|
@ -1729,7 +1765,7 @@ class Mon
|
|||
}
|
||||
for (const pool_id in st.inode_stats||{})
|
||||
{
|
||||
const pool_diff = diff.inode_stats[pool_id] = {};
|
||||
diff.inode_stats[pool_id] = {};
|
||||
for (const inode_num in st.inode_stats[pool_id])
|
||||
{
|
||||
const inode_diff = diff.inode_stats[pool_id][inode_num] = {};
|
||||
|
@ -2147,7 +2183,7 @@ class Mon
|
|||
_die(err, code)
|
||||
{
|
||||
// In fact we can just try to rejoin
|
||||
console.error(new Error(err || 'Cluster connection failed'));
|
||||
console.error(err instanceof Error ? err : new Error(err || 'Cluster connection failed'));
|
||||
process.exit(code || 2);
|
||||
}
|
||||
|
||||
|
@ -2171,7 +2207,7 @@ class Mon
|
|||
|
||||
function POST(url, body, timeout)
|
||||
{
|
||||
return new Promise((ok, no) =>
|
||||
return new Promise(ok =>
|
||||
{
|
||||
const body_text = Buffer.from(JSON.stringify(body));
|
||||
let timer_id = timeout > 0 ? setTimeout(() =>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "vitastor-mon",
|
||||
"version": "1.6.0",
|
||||
"version": "1.6.1",
|
||||
"description": "Vitastor SDS monitor service",
|
||||
"main": "mon-main.js",
|
||||
"scripts": {
|
||||
|
@ -11,5 +11,15 @@
|
|||
"dependencies": {
|
||||
"sprintf-js": "^1.1.2",
|
||||
"ws": "^7.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.0.0",
|
||||
"eslint-plugin-node": "^11.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint *.js"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ async function run()
|
|||
const st = await fs.stat(options.device);
|
||||
options.device_block_size = st.blksize;
|
||||
if (st.isBlockDevice())
|
||||
device_size = Number(await system("/sbin/blockdev --getsize64 "+options.device))
|
||||
device_size = Number(await system("/sbin/blockdev --getsize64 "+options.device));
|
||||
else
|
||||
device_size = st.size;
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ async function run()
|
|||
|
||||
function system(cmd)
|
||||
{
|
||||
return new Promise((ok, no) => child_process.exec(cmd, { maxBuffer: 64*1024*1024 }, (err, stdout, stderr) => (err ? no(err.message) : ok(stdout))));
|
||||
return new Promise((ok, no) => child_process.exec(cmd, { maxBuffer: 64*1024*1024 }, (err, stdout/*, stderr*/) => (err ? no(err.message) : ok(stdout))));
|
||||
}
|
||||
|
||||
run().catch(err => { console.error(err); process.exit(1); });
|
||||
|
|
|
@ -198,7 +198,6 @@ function all_combinations(osd_tree, pg_size, ordered, count)
|
|||
|
||||
function check_combinations(osd_tree, pgs)
|
||||
{
|
||||
const hosts = Object.keys(osd_tree).sort();
|
||||
const host_per_osd = {};
|
||||
for (const host in osd_tree)
|
||||
{
|
||||
|
@ -235,6 +234,7 @@ function compat(params)
|
|||
|
||||
module.exports = {
|
||||
flatten_tree,
|
||||
all_combinations,
|
||||
SimpleCombinator,
|
||||
compat,
|
||||
NO_OSD,
|
||||
|
|
|
@ -20,7 +20,7 @@ const osd_tree = {
|
|||
},
|
||||
500: {
|
||||
4: 3.58498,
|
||||
// 8: 3.58589,
|
||||
/*8: 3.58589,*/
|
||||
9: 3.63869,
|
||||
},
|
||||
600: {
|
||||
|
|
|
@ -50,7 +50,7 @@ from cinder.volume import configuration
|
|||
from cinder.volume import driver
|
||||
from cinder.volume import volume_utils
|
||||
|
||||
VERSION = '1.6.0'
|
||||
VERSION = '1.6.1'
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -24,4 +24,4 @@ rm fio
|
|||
mv fio-copy fio
|
||||
FIO=`rpm -qi fio | perl -e 'while(<>) { /^Epoch[\s:]+(\S+)/ && print "$1:"; /^Version[\s:]+(\S+)/ && print $1; /^Release[\s:]+(\S+)/ && print "-$1"; }'`
|
||||
perl -i -pe 's/(Requires:\s*fio)([^\n]+)?/$1 = '$FIO'/' $VITASTOR/rpm/vitastor-el$EL.spec
|
||||
tar --transform 's#^#vitastor-1.6.0/#' --exclude 'rpm/*.rpm' -czf $VITASTOR/../vitastor-1.6.0$(rpm --eval '%dist').tar.gz *
|
||||
tar --transform 's#^#vitastor-1.6.1/#' --exclude 'rpm/*.rpm' -czf $VITASTOR/../vitastor-1.6.1$(rpm --eval '%dist').tar.gz *
|
||||
|
|
|
@ -36,7 +36,7 @@ ADD . /root/vitastor
|
|||
RUN set -e; \
|
||||
cd /root/vitastor/rpm; \
|
||||
sh build-tarball.sh; \
|
||||
cp /root/vitastor-1.6.0.el7.tar.gz ~/rpmbuild/SOURCES; \
|
||||
cp /root/vitastor-1.6.1.el7.tar.gz ~/rpmbuild/SOURCES; \
|
||||
cp vitastor-el7.spec ~/rpmbuild/SPECS/vitastor.spec; \
|
||||
cd ~/rpmbuild/SPECS/; \
|
||||
rpmbuild -ba vitastor.spec; \
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
Name: vitastor
|
||||
Version: 1.6.0
|
||||
Version: 1.6.1
|
||||
Release: 1%{?dist}
|
||||
Summary: Vitastor, a fast software-defined clustered block storage
|
||||
|
||||
License: Vitastor Network Public License 1.1
|
||||
URL: https://vitastor.io/
|
||||
Source0: vitastor-1.6.0.el7.tar.gz
|
||||
Source0: vitastor-1.6.1.el7.tar.gz
|
||||
|
||||
BuildRequires: liburing-devel >= 0.6
|
||||
BuildRequires: gperftools-devel
|
||||
|
@ -104,7 +104,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||
%make_install
|
||||
. /opt/rh/rh-nodejs12/enable
|
||||
cd mon
|
||||
npm install
|
||||
npm install --production
|
||||
cd ..
|
||||
mkdir -p %buildroot/usr/lib/vitastor
|
||||
cp -r mon %buildroot/usr/lib/vitastor
|
||||
|
|
|
@ -35,7 +35,7 @@ ADD . /root/vitastor
|
|||
RUN set -e; \
|
||||
cd /root/vitastor/rpm; \
|
||||
sh build-tarball.sh; \
|
||||
cp /root/vitastor-1.6.0.el8.tar.gz ~/rpmbuild/SOURCES; \
|
||||
cp /root/vitastor-1.6.1.el8.tar.gz ~/rpmbuild/SOURCES; \
|
||||
cp vitastor-el8.spec ~/rpmbuild/SPECS/vitastor.spec; \
|
||||
cd ~/rpmbuild/SPECS/; \
|
||||
rpmbuild -ba vitastor.spec; \
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
Name: vitastor
|
||||
Version: 1.6.0
|
||||
Version: 1.6.1
|
||||
Release: 1%{?dist}
|
||||
Summary: Vitastor, a fast software-defined clustered block storage
|
||||
|
||||
License: Vitastor Network Public License 1.1
|
||||
URL: https://vitastor.io/
|
||||
Source0: vitastor-1.6.0.el8.tar.gz
|
||||
Source0: vitastor-1.6.1.el8.tar.gz
|
||||
|
||||
BuildRequires: liburing-devel >= 0.6
|
||||
BuildRequires: gperftools-devel
|
||||
|
@ -101,7 +101,7 @@ Vitastor fio drivers for benchmarking.
|
|||
rm -rf $RPM_BUILD_ROOT
|
||||
%make_install
|
||||
cd mon
|
||||
npm install
|
||||
npm install --production
|
||||
cd ..
|
||||
mkdir -p %buildroot/usr/lib/vitastor
|
||||
cp -r mon %buildroot/usr/lib/vitastor
|
||||
|
|
|
@ -18,7 +18,7 @@ ADD . /root/vitastor
|
|||
RUN set -e; \
|
||||
cd /root/vitastor/rpm; \
|
||||
sh build-tarball.sh; \
|
||||
cp /root/vitastor-1.6.0.el9.tar.gz ~/rpmbuild/SOURCES; \
|
||||
cp /root/vitastor-1.6.1.el9.tar.gz ~/rpmbuild/SOURCES; \
|
||||
cp vitastor-el9.spec ~/rpmbuild/SPECS/vitastor.spec; \
|
||||
cd ~/rpmbuild/SPECS/; \
|
||||
rpmbuild -ba vitastor.spec; \
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
Name: vitastor
|
||||
Version: 1.6.0
|
||||
Version: 1.6.1
|
||||
Release: 1%{?dist}
|
||||
Summary: Vitastor, a fast software-defined clustered block storage
|
||||
|
||||
License: Vitastor Network Public License 1.1
|
||||
URL: https://vitastor.io/
|
||||
Source0: vitastor-1.6.0.el9.tar.gz
|
||||
Source0: vitastor-1.6.1.el9.tar.gz
|
||||
|
||||
BuildRequires: liburing-devel >= 0.6
|
||||
BuildRequires: gperftools-devel
|
||||
|
@ -94,7 +94,7 @@ Vitastor fio drivers for benchmarking.
|
|||
rm -rf $RPM_BUILD_ROOT
|
||||
%cmake_install
|
||||
cd mon
|
||||
npm install
|
||||
npm install --production
|
||||
cd ..
|
||||
mkdir -p %buildroot/usr/lib/vitastor
|
||||
cp -r mon %buildroot/usr/lib/vitastor
|
||||
|
|
|
@ -19,7 +19,7 @@ if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/local/?$")
|
|||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
||||
endif()
|
||||
|
||||
add_definitions(-DVERSION="1.6.0")
|
||||
add_definitions(-DVERSION="1.6.1")
|
||||
add_definitions(-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -Wno-sign-compare -Wno-comment -Wno-parentheses -Wno-pointer-arith -fdiagnostics-color=always -fno-omit-frame-pointer -I ${CMAKE_SOURCE_DIR}/src)
|
||||
add_link_options(-fno-omit-frame-pointer)
|
||||
if (${WITH_ASAN})
|
||||
|
|
|
@ -71,7 +71,7 @@ std::string validate_pool_config(json11::Json::object & new_cfg, json11::Json ol
|
|||
auto & key = kv_it->first;
|
||||
auto & value = kv_it->second;
|
||||
if (key == "pg_size" || key == "parity_chunks" || key == "pg_minsize" ||
|
||||
key == "pg_count" || key == "max_osd_combinations" || key == "block_size" ||
|
||||
key == "pg_count" || key == "max_osd_combinations" ||
|
||||
key == "bitmap_granularity" || key == "pg_stripe_size")
|
||||
{
|
||||
if (value.is_number() && value.uint64_value() != value.number_value() ||
|
||||
|
@ -81,6 +81,14 @@ std::string validate_pool_config(json11::Json::object & new_cfg, json11::Json ol
|
|||
}
|
||||
value = value.uint64_value();
|
||||
}
|
||||
else if (key == "block_size")
|
||||
{
|
||||
value = value.is_string() ? parse_size(value.string_value()) : value.uint64_value();
|
||||
if (!value)
|
||||
{
|
||||
return key+" must be an integer with or without size suffix (K/M/G/T)";
|
||||
}
|
||||
}
|
||||
else if (key == "name" || key == "scheme" || key == "immediate_commit" ||
|
||||
key == "failure_domain" || key == "root_node" || key == "scrub_interval" || key == "used_for_fs" ||
|
||||
key == "raw_placement")
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
struct pool_creator_t
|
||||
{
|
||||
cli_tool_t *parent;
|
||||
json11::Json::object cfg;
|
||||
json11::Json cfg;
|
||||
|
||||
bool force = false;
|
||||
bool wait = false;
|
||||
|
@ -55,8 +55,12 @@ struct pool_creator_t
|
|||
goto resume_8;
|
||||
|
||||
// Validate pool parameters
|
||||
result.text = validate_pool_config(cfg, json11::Json(), parent->cli->st_cli.global_block_size,
|
||||
parent->cli->st_cli.global_bitmap_granularity, force);
|
||||
{
|
||||
auto new_cfg = cfg.object_items();
|
||||
result.text = validate_pool_config(new_cfg, json11::Json(), parent->cli->st_cli.global_block_size,
|
||||
parent->cli->st_cli.global_bitmap_granularity, force);
|
||||
cfg = new_cfg;
|
||||
}
|
||||
if (result.text != "")
|
||||
{
|
||||
result.err = EINVAL;
|
||||
|
@ -605,7 +609,7 @@ std::function<bool(cli_result_t &)> cli_tool_t::start_pool_create(json11::Json c
|
|||
{
|
||||
auto pool_creator = new pool_creator_t();
|
||||
pool_creator->parent = this;
|
||||
pool_creator->cfg = cfg.object_items();
|
||||
pool_creator->cfg = cfg;
|
||||
pool_creator->force = cfg["force"].bool_value();
|
||||
pool_creator->wait = cfg["wait"].bool_value();
|
||||
return [pool_creator](cli_result_t & result)
|
||||
|
|
|
@ -205,7 +205,7 @@ resume_1:
|
|||
{ "raw_to_usable", pool_stats[pool_cfg.id]["raw_to_usable"].number_value() },
|
||||
{ "space_efficiency", pool_stats[pool_cfg.id]["space_efficiency"].number_value() },
|
||||
{ "pg_real_size", pool_stats[pool_cfg.id]["pg_real_size"].uint64_value() },
|
||||
{ "osd_count", pg_per_osd.size() },
|
||||
{ "osd_count", (uint64_t)pg_per_osd.size() },
|
||||
};
|
||||
}
|
||||
// Include full pool config
|
||||
|
|
|
@ -452,7 +452,7 @@ void kv_cli_t::handle_cmd(const std::vector<std::string> & cmd, std::function<vo
|
|||
auto name = cmd.size() > 1 ? cmd[1] : "";
|
||||
uint64_t pool_id = 0;
|
||||
inode_t inode_id = 0;
|
||||
int scanned = sscanf(name.c_str(), "%lu %lu", &pool_id, &inode_id);
|
||||
int scanned = sscanf(name.c_str(), "%ju %ju", &pool_id, &inode_id);
|
||||
if (scanned < 2 || !pool_id || !inode_id)
|
||||
{
|
||||
inode_id = 0;
|
||||
|
@ -483,7 +483,7 @@ void kv_cli_t::handle_cmd(const std::vector<std::string> & cmd, std::function<vo
|
|||
else
|
||||
{
|
||||
opened = true;
|
||||
fprintf(interactive ? stdout : stderr, "Index opened. Current size: %lu bytes\n", db->get_size());
|
||||
fprintf(interactive ? stdout : stderr, "Index opened. Current size: %ju bytes\n", db->get_size());
|
||||
}
|
||||
cb(res);
|
||||
});
|
||||
|
|
|
@ -250,14 +250,14 @@ int kv_block_t::parse(uint64_t offset, uint8_t *data, int size)
|
|||
{
|
||||
// empty block
|
||||
if (offset != 0)
|
||||
fprintf(stderr, "K/V: Block %lu is %s\n", offset, blk->magic == 0 ? "empty" : "cleared");
|
||||
fprintf(stderr, "K/V: Block %ju is %s\n", offset, blk->magic == 0 ? "empty" : "cleared");
|
||||
return -ENOTBLK;
|
||||
}
|
||||
if (blk->magic != KV_BLOCK_MAGIC || blk->block_size != size ||
|
||||
!blk->type || blk->type > KV_EMPTY || blk->items > KV_BLOCK_MAX_ITEMS)
|
||||
{
|
||||
// invalid block
|
||||
fprintf(stderr, "K/V: Invalid block %lu magic, size, type or item count\n", offset);
|
||||
fprintf(stderr, "K/V: Invalid block %ju magic, size, type or item count\n", offset);
|
||||
return -EILSEQ;
|
||||
}
|
||||
assert(!this->type);
|
||||
|
@ -266,13 +266,13 @@ int kv_block_t::parse(uint64_t offset, uint8_t *data, int size)
|
|||
this->key_ge = read_string(data, size, &pos);
|
||||
if (pos < 0)
|
||||
{
|
||||
fprintf(stderr, "K/V: Invalid block %lu left bound\n", offset);
|
||||
fprintf(stderr, "K/V: Invalid block %ju left bound\n", offset);
|
||||
return -EILSEQ;
|
||||
}
|
||||
this->key_lt = read_string(data, size, &pos);
|
||||
if (pos < 0)
|
||||
{
|
||||
fprintf(stderr, "K/V: Invalid block %lu right bound\n", offset);
|
||||
fprintf(stderr, "K/V: Invalid block %ju right bound\n", offset);
|
||||
return -EILSEQ;
|
||||
}
|
||||
if (this->type == KV_INT_SPLIT || this->type == KV_LEAF_SPLIT)
|
||||
|
@ -280,12 +280,12 @@ int kv_block_t::parse(uint64_t offset, uint8_t *data, int size)
|
|||
this->right_half = read_string(data, size, &pos);
|
||||
if (pos < 0)
|
||||
{
|
||||
fprintf(stderr, "K/V: Invalid block %lu split bound\n", offset);
|
||||
fprintf(stderr, "K/V: Invalid block %ju split bound\n", offset);
|
||||
return -EILSEQ;
|
||||
}
|
||||
if (pos+8 > size)
|
||||
{
|
||||
fprintf(stderr, "K/V: Invalid block %lu split block ref\n", offset);
|
||||
fprintf(stderr, "K/V: Invalid block %ju split block ref\n", offset);
|
||||
return -EILSEQ;
|
||||
}
|
||||
this->right_half_block = *(uint64_t*)(data+pos);
|
||||
|
@ -296,13 +296,13 @@ int kv_block_t::parse(uint64_t offset, uint8_t *data, int size)
|
|||
auto key = read_string(data, size, &pos);
|
||||
if (pos < 0)
|
||||
{
|
||||
fprintf(stderr, "K/V: Invalid block %lu key %d\n", offset, i);
|
||||
fprintf(stderr, "K/V: Invalid block %ju key %d\n", offset, i);
|
||||
return -EILSEQ;
|
||||
}
|
||||
auto value = read_string(data, size, &pos);
|
||||
if (pos < 0)
|
||||
{
|
||||
fprintf(stderr, "K/V: Invalid block %lu value %d\n", offset, i);
|
||||
fprintf(stderr, "K/V: Invalid block %ju value %d\n", offset, i);
|
||||
return -EILSEQ;
|
||||
}
|
||||
this->data[key] = value;
|
||||
|
@ -470,7 +470,7 @@ static void dump_str(const std::string & str)
|
|||
void kv_block_t::dump(int base_level)
|
||||
{
|
||||
printf(
|
||||
"{\n \"block\": %lu,\n \"level\": %d,\n \"type\": \"%s\",\n \"range\": [",
|
||||
"{\n \"block\": %ju,\n \"level\": %d,\n \"type\": \"%s\",\n \"range\": [",
|
||||
offset, base_level+level,
|
||||
type < sizeof(block_type_names)/sizeof(block_type_names[0]) ? block_type_names[type] : "unknown"
|
||||
);
|
||||
|
@ -482,7 +482,7 @@ void kv_block_t::dump(int base_level)
|
|||
{
|
||||
printf(" \"right_half\": { ");
|
||||
dump_str(right_half);
|
||||
printf(": %lu },\n", right_half_block);
|
||||
printf(": %ju },\n", right_half_block);
|
||||
}
|
||||
printf(" \"data\": {\n");
|
||||
for (auto & kv: data)
|
||||
|
@ -493,7 +493,7 @@ void kv_block_t::dump(int base_level)
|
|||
if (type == KV_LEAF || type == KV_LEAF_SPLIT || kv.second.size() != 8)
|
||||
dump_str(kv.second);
|
||||
else
|
||||
printf("%lu", *(uint64_t*)kv.second.c_str());
|
||||
printf("%ju", *(uint64_t*)kv.second.c_str());
|
||||
printf(",\n");
|
||||
}
|
||||
printf(" }\n}\n");
|
||||
|
@ -1037,7 +1037,7 @@ void kv_op_t::get()
|
|||
{
|
||||
if (cur_block != 0)
|
||||
{
|
||||
fprintf(stderr, "K/V: Hit empty block %lu while searching\n", cur_block);
|
||||
fprintf(stderr, "K/V: Hit empty block %ju while searching\n", cur_block);
|
||||
finish(-EILSEQ);
|
||||
}
|
||||
else
|
||||
|
@ -1095,7 +1095,7 @@ int kv_op_t::handle_block(int res, int refresh, bool stop_on_split)
|
|||
bool fatal = !this->updating_on_path && this->retry > 0;
|
||||
if (fatal || db->log_level > 0)
|
||||
{
|
||||
fprintf(stderr, "K/V: %sgot unrelated block %lu: key=%s range=[%s, %s) from=[%s, %s)\n",
|
||||
fprintf(stderr, "K/V: %sgot unrelated block %ju: key=%s range=[%s, %s) from=[%s, %s)\n",
|
||||
fatal ? "Error: " : "Warning: read/update collision: ",
|
||||
cur_block, key.c_str(), blk->key_ge.c_str(), blk->key_lt.c_str(), prev_key_ge.c_str(), prev_key_lt.c_str());
|
||||
if (fatal)
|
||||
|
@ -1160,7 +1160,7 @@ int kv_op_t::handle_block(int res, int refresh, bool stop_on_split)
|
|||
auto child_it = blk->data.upper_bound(key);
|
||||
if (child_it == blk->data.begin())
|
||||
{
|
||||
fprintf(stderr, "K/V: Internal block %lu misses boundary for %s\n", cur_block, key.c_str());
|
||||
fprintf(stderr, "K/V: Internal block %ju misses boundary for %s\n", cur_block, key.c_str());
|
||||
return -EILSEQ;
|
||||
}
|
||||
auto m = child_it == blk->data.end()
|
||||
|
@ -1169,7 +1169,7 @@ int kv_op_t::handle_block(int res, int refresh, bool stop_on_split)
|
|||
child_it--;
|
||||
if (child_it->second.size() != sizeof(uint64_t))
|
||||
{
|
||||
fprintf(stderr, "K/V: Internal block %lu reference is not 8 byte long\n", cur_block);
|
||||
fprintf(stderr, "K/V: Internal block %ju reference is not 8 byte long\n", cur_block);
|
||||
blk->dump(db->base_block_level);
|
||||
return -EILSEQ;
|
||||
}
|
||||
|
@ -1246,7 +1246,7 @@ static void write_block(kv_db_t *db, kv_block_t *blk, std::function<void(int)> c
|
|||
blk->dump(db->base_block_level);
|
||||
uint64_t old_size = blk->data_size;
|
||||
blk->set_data_size();
|
||||
fprintf(stderr, "K/V: block %lu (ptr=%lx) grew too large: tracked %lu, but real is %u bytes\n",
|
||||
fprintf(stderr, "K/V: block %ju (ptr=%jx) grew too large: tracked %ju, but real is %u bytes\n",
|
||||
blk->offset, (uint64_t)blk, old_size, blk->data_size);
|
||||
abort();
|
||||
return;
|
||||
|
@ -1479,7 +1479,7 @@ void kv_op_t::update_find()
|
|||
else if (cur_block == 0)
|
||||
finish(-ENOENT);
|
||||
else
|
||||
fprintf(stderr, "K/V: Hit empty block %lu while searching\n", cur_block);
|
||||
fprintf(stderr, "K/V: Hit empty block %ju while searching\n", cur_block);
|
||||
}
|
||||
else if (res == -ECHILD)
|
||||
{
|
||||
|
@ -1506,7 +1506,7 @@ void kv_op_t::create_root()
|
|||
// if a referenced non-root block is empty, we just return an error.
|
||||
if (cur_block != 0 || db->next_free != 0)
|
||||
{
|
||||
fprintf(stderr, "K/V: create_root called with non-empty DB (cur_block=%lu)\n", cur_block);
|
||||
fprintf(stderr, "K/V: create_root called with non-empty DB (cur_block=%ju)\n", cur_block);
|
||||
finish(-EILSEQ);
|
||||
return;
|
||||
}
|
||||
|
@ -1551,7 +1551,7 @@ void kv_op_t::resume_split()
|
|||
if (path.size() == 1)
|
||||
{
|
||||
// It shouldn't be the root block because we don't split it via INT_SPLIT/LEAF_SPLIT
|
||||
fprintf(stderr, "K/V: resume_split at root item (cur_block=%lu)\n", cur_block);
|
||||
fprintf(stderr, "K/V: resume_split at root item (cur_block=%ju)\n", cur_block);
|
||||
finish(-EILSEQ);
|
||||
return;
|
||||
}
|
||||
|
@ -1638,7 +1638,7 @@ void kv_op_t::update_block(int path_pos, bool is_delete, const std::string & key
|
|||
{
|
||||
blk->dump(0);
|
||||
// Should not happen - we should have resumed the split
|
||||
fprintf(stderr, "K/V: attempt to write into block %lu instead of resuming the split (got here from %s..%s)\n",
|
||||
fprintf(stderr, "K/V: attempt to write into block %ju instead of resuming the split (got here from %s..%s)\n",
|
||||
blk->offset, prev_key_ge.c_str(), prev_key_lt.c_str());
|
||||
abort();
|
||||
}
|
||||
|
@ -1650,7 +1650,7 @@ void kv_op_t::update_block(int path_pos, bool is_delete, const std::string & key
|
|||
// No need to split the block => just modify and write it
|
||||
if ((blk->type == KV_LEAF_SPLIT || blk->type == KV_INT_SPLIT) && key >= blk->right_half)
|
||||
{
|
||||
fprintf(stderr, "K/V: attempt to modify %s in unrelated split block %lu [%s..%s..%s)\n",
|
||||
fprintf(stderr, "K/V: attempt to modify %s in unrelated split block %ju [%s..%s..%s)\n",
|
||||
key.c_str(), blk->offset, blk->key_ge.c_str(), blk->right_half.c_str(), blk->key_lt.c_str());
|
||||
blk->dump(db->base_block_level);
|
||||
abort();
|
||||
|
@ -1753,11 +1753,11 @@ void kv_op_t::update_block(int path_pos, bool is_delete, const std::string & key
|
|||
clear_block(db, left_blk, 0, [=, left_offset = left_blk->offset](int res)
|
||||
{
|
||||
if (res < 0)
|
||||
fprintf(stderr, "Failed to clear unreferenced block %lu: %s (code %d)\n", left_offset, strerror(-res), res);
|
||||
fprintf(stderr, "Failed to clear unreferenced block %ju: %s (code %d)\n", left_offset, strerror(-res), res);
|
||||
clear_block(db, right_blk, 0, [=, right_offset = right_blk->offset](int res)
|
||||
{
|
||||
if (res < 0)
|
||||
fprintf(stderr, "Failed to clear unreferenced block %lu: %s (code %d)\n", right_offset, strerror(-res), res);
|
||||
fprintf(stderr, "Failed to clear unreferenced block %ju: %s (code %d)\n", right_offset, strerror(-res), res);
|
||||
// CAS failure - zero garbage left_blk and right_blk and retry from the beginning
|
||||
if (write_res == -EINTR)
|
||||
update();
|
||||
|
@ -1784,7 +1784,7 @@ void kv_op_t::update_block(int path_pos, bool is_delete, const std::string & key
|
|||
if (path_pos == 0)
|
||||
{
|
||||
// Block number zero should always be the root block
|
||||
fprintf(stderr, "K/V: root block is not 0, but %lu\n", cur_block);
|
||||
fprintf(stderr, "K/V: root block is not 0, but %ju\n", cur_block);
|
||||
cb(-EILSEQ);
|
||||
return;
|
||||
}
|
||||
|
@ -1809,7 +1809,7 @@ void kv_op_t::update_block(int path_pos, bool is_delete, const std::string & key
|
|||
clear_block(db, right_blk, 0, [=, right_offset = right_blk->offset](int res)
|
||||
{
|
||||
if (res < 0)
|
||||
fprintf(stderr, "Failed to clear unreferenced block %lu: %s (code %d)\n", right_offset, strerror(-res), res);
|
||||
fprintf(stderr, "Failed to clear unreferenced block %ju: %s (code %d)\n", right_offset, strerror(-res), res);
|
||||
// CAS failure - zero garbage right_blk and retry from the beginning
|
||||
if (write_res == -EINTR)
|
||||
update();
|
||||
|
@ -1860,7 +1860,7 @@ void kv_op_t::next_handle_block(int res, int refresh)
|
|||
finish(-ENOENT);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "K/V: Hit empty block %lu while searching\n", cur_block);
|
||||
fprintf(stderr, "K/V: Hit empty block %ju while searching\n", cur_block);
|
||||
finish(-EILSEQ);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -632,7 +632,7 @@ void kv_test_t::print_stats(kv_test_stat_t & prev_stat, timespec & prev_stat_tim
|
|||
char buf[128] = { 0 };
|
||||
for (int i = 0; i < sizeof(lats)/sizeof(lats[0]); i++)
|
||||
{
|
||||
snprintf(buf, sizeof(buf)-1, "%.1f %s/s (%lu us)", (lats[i]->count-prev[i]->count)*1000000.0/usec,
|
||||
snprintf(buf, sizeof(buf)-1, "%.1f %s/s (%ju us)", (lats[i]->count-prev[i]->count)*1000000.0/usec,
|
||||
lats[i]->name, (lats[i]->usec-prev[i]->usec)/(lats[i]->count-prev[i]->count > 0 ? lats[i]->count-prev[i]->count : 1));
|
||||
int k;
|
||||
for (k = strlen(buf); k < strlen(lats[i]->name)+21; k++)
|
||||
|
@ -652,7 +652,7 @@ void kv_test_t::print_stats(kv_test_stat_t & prev_stat, timespec & prev_stat_tim
|
|||
if (lats[i]->count > prev[i]->count)
|
||||
{
|
||||
printf(
|
||||
",\"%s\":{\"avg\":{\"iops\":%.1f,\"usec\":%lu},\"total\":{\"count\":%lu,\"usec\":%lu}}",
|
||||
",\"%s\":{\"avg\":{\"iops\":%.1f,\"usec\":%ju},\"total\":{\"count\":%ju,\"usec\":%ju}}",
|
||||
lats[i]->name, (lats[i]->count-prev[i]->count)*1000000.0/usec,
|
||||
(lats[i]->usec-prev[i]->usec)/(lats[i]->count-prev[i]->count),
|
||||
lats[i]->count, lats[i]->usec
|
||||
|
|
|
@ -497,7 +497,7 @@ static void extend_inode(nfs_client_t *self, uint64_t inode, uint64_t new_size)
|
|||
auto & ext = self->parent->blockfs->extends[inode];
|
||||
if (r.err)
|
||||
{
|
||||
fprintf(stderr, "Error extending inode %lu to %lu bytes: %s\n", inode, new_size, r.text.c_str());
|
||||
fprintf(stderr, "Error extending inode %ju to %ju bytes: %s\n", inode, new_size, r.text.c_str());
|
||||
}
|
||||
if (r.err == EAGAIN || ext.next_extend > ext.cur_extend)
|
||||
{
|
||||
|
|
|
@ -258,7 +258,7 @@ resume_3:
|
|||
auto name = kv_direntry_filename(st->cur_key);
|
||||
if (st->self->parent->trace)
|
||||
{
|
||||
fprintf(stderr, "[%d] READDIR %ju %lu %s\n",
|
||||
fprintf(stderr, "[%d] READDIR %ju %ju %s\n",
|
||||
st->self->nfs_fd, st->dir_ino, st->offset, name.c_str());
|
||||
}
|
||||
auto fh = kv_fh(ino);
|
||||
|
|
|
@ -608,7 +608,7 @@ static void nfs_kv_extend_inode(nfs_kv_write_state *st, int state, int base_stat
|
|||
auto ientry = json11::Json::parse(old_value, err).object_items();
|
||||
if (err != "")
|
||||
{
|
||||
fprintf(stderr, "Invalid JSON in inode %lu = %s: %s\n", st->ino, old_value.c_str(), err.c_str());
|
||||
fprintf(stderr, "Invalid JSON in inode %ju = %s: %s\n", st->ino, old_value.c_str(), err.c_str());
|
||||
st->res2 = -EINVAL;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -534,7 +534,7 @@ void osd_t::renew_lease(bool reload)
|
|||
{ "ID", etcd_lease_id }
|
||||
}, st_cli.etcd_quick_timeout, 0, 0, [this, reload](std::string err, json11::Json data)
|
||||
{
|
||||
if (err == "" && data["result"]["TTL"].string_value() == "")
|
||||
if (err == "" && data["result"]["TTL"].uint64_value() == 0)
|
||||
{
|
||||
// Die
|
||||
fprintf(stderr, "Error refreshing etcd lease\n");
|
||||
|
|
|
@ -6,7 +6,7 @@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
|||
|
||||
Name: Vitastor
|
||||
Description: Vitastor client library
|
||||
Version: 1.6.0
|
||||
Version: 1.6.1
|
||||
Libs: -L${libdir} -lvitastor_client
|
||||
Cflags: -I${includedir}
|
||||
|
||||
|
|
Loading…
Reference in New Issue