Changeset b0f1366 in mainline
- Timestamp:
- 2024-09-06T11:37:54Z (8 months ago)
- Children:
- 9c1cf34c
- Parents:
- ee83e9c
- Location:
- uspace
- Files:
-
- 2 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/hrctl/hrctl.c
ree83e9c rb0f1366 53 53 "\n" 54 54 "Options:\n" 55 " -h, --help display this help and exit\n" 56 " -C, --config-file=path create an array from file,\n" 57 " sample file at: " HRCTL_SAMPLE_CONFIG_PATH "\n" 58 " -s, --status display status of active arrays\n" 59 " -a, --assemble=NAME assemble an existing array\n" 60 " -c, --create=NAME create new array\n" 61 " -n non-zero number of devices\n" 62 " -l, --level=LEVEL set the RAID level,\n" 63 " valid values: 0, 1, 5, linear\n" 64 " -0 striping\n" 65 " -1 mirroring\n" 66 " -5 distributed parity\n" 67 " -L linear concatenation\n" 55 " -h, --help display this help and exit\n" 56 " -C, --create-file=path create an array from file,\n" 57 " sample file at: " HRCTL_SAMPLE_CONFIG_PATH "\n" 58 " -A, --assemble-file=path create an array from file\n" 59 " -s, --status display status of active arrays\n" 60 " -c, --create=NAME create new array\n" 61 " -a, --assemble=NAME assemble an existing array\n" 62 " -n non-zero number of devices\n" 63 " -l, --level=LEVEL set the RAID level,\n" 64 " valid values: 0, 1, 5, linear\n" 65 " -0 striping\n" 66 " -1 mirroring\n" 67 " -5 distributed parity\n" 68 " -L linear concatenation\n" 68 69 "\n" 69 70 "Example usage:\n" … … 83 84 { "create", required_argument, 0, 'c' }, 84 85 { "level", required_argument, 0, 'l' }, 85 { "config-file", required_argument, 0, 'C' }, 86 { "create-file", required_argument, 0, 'C' }, 87 { "assemble-file", required_argument, 0, 'A' }, 86 88 { 0, 0, 0, 0 } 87 89 }; … … 154 156 155 157 level_str = sif_node_get_attr(narray, "level"); 156 if (level_str == NULL) { 157 rc = EIO; 158 goto error; 159 } 160 cfg->level = strtol(level_str, NULL, 10); 158 if (level_str == NULL) 159 cfg->level = hr_l_empty; 160 else if (str_cmp(level_str, "linear") == 0) 161 cfg->level = hr_l_linear; 162 else 163 cfg->level = strtol(level_str, NULL, 10); 161 164 162 165 dev_no_str = sif_node_get_attr(narray, "n"); … … 228 231 229 232 while (c != -1) { 230 c = getopt_long(argc, argv, "hsC:c: a:l:015Ln:",233 c = getopt_long(argc, argv, "hsC:c:A:a:l:015Ln:", 231 234 long_options, NULL); 232 235 switch (c) { … … 239 242 return 1; 240 243 return 0; 241 case 'a':242 if (str_size(optarg) > sizeof(cfg->devname) - 1) {243 printf("hrctl: device name too long\n");244 return 1;245 }246 str_cpy(cfg->devname, sizeof(cfg->devname), optarg);247 assemble = true;248 break;249 244 case 'C': 250 245 /* only support 1 array inside config for now XXX */ … … 264 259 create = true; 265 260 break; 261 case 'A': 262 rc = load_config(optarg, cfg); 263 if (rc != EOK) { 264 printf("hrctl: failed to load config\n"); 265 return 1; 266 } 267 assemble = true; 268 goto skip; 269 case 'a': 270 if (str_size(optarg) > sizeof(cfg->devname) - 1) { 271 printf("hrctl: device name too long\n"); 272 return 1; 273 } 274 str_cpy(cfg->devname, sizeof(cfg->devname), optarg); 275 assemble = true; 276 break; 266 277 case 'l': 267 278 if (cfg->level != hr_l_empty) … … 296 307 if ((int) cfg->dev_no + optind != argc) 297 308 goto bad; 298 if (cfg->dev_no > HR_MAXDEVS) {299 printf("hrctl: too many devices\n");300 return 1;301 }302 309 rc = fill_config_devs(argc, argv, optind, cfg); 303 310 if (rc != EOK) … … 308 315 309 316 skip: 310 if ((create && assemble) || 311 (!create && !assemble) || 312 (create && cfg->level == hr_l_empty) || 313 (assemble && cfg->level != hr_l_empty) || 314 (cfg->dev_no == 0)) { 317 if ((create && assemble) || (!create && !assemble)) 315 318 goto bad; 319 320 if (create && cfg->level == hr_l_empty) { 321 printf("hrctl: invalid level, exiting\n"); 322 return 1; 323 } 324 325 if (cfg->dev_no > HR_MAXDEVS) { 326 printf("hrctl: too many devices, exiting\n"); 327 return 1; 328 } 329 330 if (cfg->dev_no == 0) { 331 printf("hrctl: invalid number of devices, exiting\n"); 332 return 1; 316 333 } 317 334 … … 327 344 printf("hrctl: hr_create() rc: %s\n", str_error(rc)); 328 345 } else if (assemble) { 329 printf("hrctl: assemble not implemented yet\n"); 346 rc = hr_assemble(hr, cfg); 347 printf("hrctl: hr_assemble() rc: %s\n", str_error(rc)); 330 348 } 331 349 -
uspace/lib/device/include/hr.h
ree83e9c rb0f1366 76 76 77 77 extern errno_t hr_create(hr_t *, hr_config_t *); 78 extern errno_t hr_assemble(hr_t *, hr_config_t *); 78 79 extern errno_t hr_print_status(void); 79 80 -
uspace/lib/device/include/ipc/hr.h
ree83e9c rb0f1366 40 40 typedef enum { 41 41 HR_CREATE = IPC_FIRST_USER_METHOD, 42 HR_ASSEMBLE, 42 43 HR_STATUS 43 44 } hr_request_t; -
uspace/lib/device/src/hr.c
ree83e9c rb0f1366 114 114 } 115 115 116 errno_t hr_assemble(hr_t *hr, hr_config_t *hr_config) 117 { 118 errno_t rc, retval; 119 async_exch_t *exch; 120 aid_t req; 121 122 exch = async_exchange_begin(hr->sess); 123 if (exch == NULL) 124 return EINVAL; 125 126 req = async_send_0(exch, HR_ASSEMBLE, NULL); 127 128 rc = async_data_write_start(exch, hr_config, sizeof(hr_config_t)); 129 if (rc != EOK) { 130 async_exchange_end(exch); 131 async_forget(req); 132 return rc; 133 } 134 135 async_exchange_end(exch); 136 async_wait_for(req, &retval); 137 if (retval != EOK) 138 return retval; 139 140 return EOK; 141 } 142 116 143 static errno_t print_vol_info(size_t index, hr_vol_info_t *vol_info) 117 144 { -
uspace/srv/bd/hr/hr.c
ree83e9c rb0f1366 49 49 #include <str_error.h> 50 50 51 #include "superblock.h" 52 #include "util.h" 51 53 #include "var.h" 52 54 … … 58 60 59 61 static service_id_t ctl_sid; 62 60 63 61 64 static void hr_create_srv(ipc_call_t *icall) … … 92 95 async_answer_0(&call, rc); 93 96 async_answer_0(icall, rc); 97 return; 94 98 } 95 99 96 100 new_volume = calloc(1, sizeof(hr_volume_t)); 97 101 if (new_volume == NULL) { 98 rc = ENOMEM; 99 goto end; 102 free(cfg); 103 async_answer_0(icall, ENOMEM); 104 return; 100 105 } 101 106 … … 104 109 new_volume->level = cfg->level; 105 110 new_volume->dev_no = cfg->dev_no; 111 112 rc = hr_init_devs(new_volume); 113 if (rc != EOK) { 114 free(cfg); 115 async_answer_0(icall, rc); 116 return; 117 } 118 119 rc = hr_check_devs(new_volume); 120 if (rc != EOK) 121 goto error; 122 123 rc = hr_write_meta_to_vol(new_volume); 124 if (rc != EOK) 125 goto error; 106 126 107 127 switch (new_volume->level) { … … 113 133 break; 114 134 default: 115 log_msg(LOG_DEFAULT, LVL_ NOTE,116 "level %d not implemented yet \n", new_volume->level);135 log_msg(LOG_DEFAULT, LVL_ERROR, 136 "level %d not implemented yet", new_volume->level); 117 137 rc = EINVAL; 118 goto e nd;138 goto error; 119 139 } 120 140 121 141 rc = new_volume->hr_ops.create(new_volume); 122 if (rc != EOK) { 123 goto end; 124 } 142 if (rc != EOK) 143 goto error; 125 144 126 145 fibril_mutex_lock(&hr_volumes_lock); … … 128 147 fibril_mutex_unlock(&hr_volumes_lock); 129 148 130 log_msg(LOG_DEFAULT, LVL_NOTE, "created volume \"%s\" (%" PRIun ") \n",149 log_msg(LOG_DEFAULT, LVL_NOTE, "created volume \"%s\" (%" PRIun ")", 131 150 new_volume->devname, new_volume->svc_id); 132 151 133 end:134 152 free(cfg); 153 async_answer_0(icall, rc); 154 return; 155 error: 156 free(cfg); 157 hr_fini_devs(new_volume); 158 async_answer_0(icall, rc); 159 } 160 161 static void hr_assemble_srv(ipc_call_t *icall) 162 { 163 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_assemble_srv()"); 164 165 errno_t rc; 166 size_t size; 167 hr_config_t *cfg; 168 hr_volume_t *new_volume; 169 ipc_call_t call; 170 171 if (!async_data_write_receive(&call, &size)) { 172 async_answer_0(&call, EREFUSED); 173 async_answer_0(icall, EREFUSED); 174 return; 175 } 176 177 if (size != sizeof(hr_config_t)) { 178 async_answer_0(&call, EINVAL); 179 async_answer_0(icall, EINVAL); 180 return; 181 } 182 183 cfg = calloc(1, sizeof(hr_config_t)); 184 if (cfg == NULL) { 185 async_answer_0(&call, ENOMEM); 186 async_answer_0(icall, ENOMEM); 187 return; 188 } 189 190 rc = async_data_write_finalize(&call, cfg, size); 191 if (rc != EOK) { 192 async_answer_0(&call, rc); 193 async_answer_0(icall, rc); 194 return; 195 } 196 197 new_volume = calloc(1, sizeof(hr_volume_t)); 198 if (new_volume == NULL) { 199 free(cfg); 200 async_answer_0(icall, ENOMEM); 201 return; 202 } 203 204 str_cpy(new_volume->devname, 32, cfg->devname); 205 memcpy(new_volume->devs, cfg->devs, sizeof(service_id_t) * HR_MAXDEVS); 206 new_volume->dev_no = cfg->dev_no; 207 208 if (cfg->level != hr_l_empty) 209 log_msg(LOG_DEFAULT, LVL_WARN, 210 "level manually set when assembling, ingoring"); 211 212 new_volume->level = hr_l_empty; 213 214 rc = hr_init_devs(new_volume); 215 if (rc != EOK) { 216 free(cfg); 217 async_answer_0(icall, rc); 218 return; 219 } 220 221 rc = hr_check_devs(new_volume); 222 if (rc != EOK) 223 goto error; 224 225 rc = hr_get_vol_from_meta(cfg, new_volume); 226 if (rc != EOK) 227 goto error; 228 229 switch (new_volume->level) { 230 case hr_l_1: 231 new_volume->hr_ops.create = hr_raid1_create; 232 break; 233 case hr_l_0: 234 new_volume->hr_ops.create = hr_raid0_create; 235 break; 236 default: 237 log_msg(LOG_DEFAULT, LVL_ERROR, 238 "level %d not implemented yet", new_volume->level); 239 rc = EINVAL; 240 goto error; 241 } 242 243 rc = new_volume->hr_ops.create(new_volume); 244 if (rc != EOK) 245 goto error; 246 247 fibril_mutex_lock(&hr_volumes_lock); 248 list_append(&new_volume->lvolumes, &hr_volumes); 249 fibril_mutex_unlock(&hr_volumes_lock); 250 251 log_msg(LOG_DEFAULT, LVL_NOTE, "assembled volume \"%s\" (%" PRIun ")", 252 new_volume->devname, new_volume->svc_id); 253 254 free(cfg); 255 async_answer_0(icall, rc); 256 return; 257 error: 258 free(cfg); 259 hr_fini_devs(new_volume); 135 260 async_answer_0(icall, rc); 136 261 } … … 170 295 info.extent_no = volume->dev_no; 171 296 info.level = volume->level; 172 info.nblocks = volume->nblocks; 297 /* print usable number of blocks */ 298 info.nblocks = volume->data_blkno; 173 299 info.bsize = volume->bsize; 174 300 … … 219 345 case HR_STATUS: 220 346 hr_print_status_srv(&call); 347 break; 348 case HR_ASSEMBLE: 349 hr_assemble_srv(&call); 221 350 break; 222 351 default: -
uspace/srv/bd/hr/meson.build
ree83e9c rb0f1366 28 28 29 29 deps = [ 'block', 'device' ] 30 src = files('hr.c', 'raid0.c', 'raid1.c', ' util.c')30 src = files('hr.c', 'raid0.c', 'raid1.c', 'superblock.c', 'util.c') -
uspace/srv/bd/hr/raid0.c
ree83e9c rb0f1366 48 48 #include <str_error.h> 49 49 50 #include "util.h" 50 51 #include "var.h" 51 #include "util.h"52 52 53 53 extern fibril_mutex_t big_lock; … … 64 64 static errno_t hr_raid0_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 65 65 66 #define strip_size DATA_XFER_LIMIT67 68 66 static bd_ops_t hr_raid0_bd_ops = { 69 67 .open = hr_raid0_bd_open, … … 80 78 { 81 79 uint64_t N = vol->dev_no; /* extents */ 82 uint64_t L = strip_size/ vol->bsize; /* size of strip in blocks */80 uint64_t L = HR_STRIP_SIZE / vol->bsize; /* size of strip in blocks */ 83 81 84 82 uint64_t i = (x / L) % N; /* extent */ … … 114 112 while (left != 0) { 115 113 raid0_geometry(ba++, vol, &extent, &phys_block); 114 rc = hr_calc_ba(vol, cnt, &ba); 115 if (rc != EOK) 116 break; 116 117 rc = block_sync_cache(vol->devs[extent], phys_block, 1); 117 118 if (rc != EOK) … … 140 141 while (left != 0) { 141 142 raid0_geometry(ba++, vol, &extent, &phys_block); 143 rc = hr_calc_ba(vol, cnt, &ba); 144 if (rc != EOK) 145 break; 142 146 rc = block_read_direct(vol->devs[extent], phys_block, 1, buf); 143 147 buf = buf + vol->bsize; … … 167 171 while (left != 0) { 168 172 raid0_geometry(ba++, vol, &extent, &phys_block); 173 rc = hr_calc_ba(vol, cnt, &phys_block); 174 if (rc != EOK) 175 break; 169 176 rc = block_write_direct(vol->devs[extent], phys_block, 1, data); 170 177 data = data + vol->bsize; … … 190 197 hr_volume_t *vol = bd->srvs->sarg; 191 198 192 *rnb = vol-> nblocks;199 *rnb = vol->data_blkno; 193 200 return EOK; 194 201 } … … 196 203 errno_t hr_raid0_create(hr_volume_t *new_volume) 197 204 { 205 errno_t rc; 206 198 207 assert(new_volume->level == hr_l_0); 199 208 … … 204 213 } 205 214 206 errno_t rc;207 size_t i, bsize, last_bsize;208 uint64_t nblocks, last_nblocks;209 uint64_t total_blocks = 0;210 211 rc = hr_init_devs(new_volume);212 if (rc != EOK)213 return rc;214 215 for (i = 0; i < new_volume->dev_no; i++) {216 rc = block_get_nblocks(new_volume->devs[i], &nblocks);217 if (rc != EOK)218 goto error;219 if (i != 0 && nblocks != last_nblocks) {220 log_msg(LOG_DEFAULT, LVL_ERROR,221 "number of blocks differs");222 rc = EINVAL;223 goto error;224 }225 total_blocks += nblocks;226 last_nblocks = nblocks;227 }228 229 for (i = 0; i < new_volume->dev_no; i++) {230 rc = block_get_bsize(new_volume->devs[i], &bsize);231 if (rc != EOK)232 goto error;233 if (i != 0 && bsize != last_bsize) {234 log_msg(LOG_DEFAULT, LVL_ERROR, "block sizes differ");235 rc = EINVAL;236 goto error;237 }238 last_bsize = bsize;239 }240 241 215 bd_srvs_init(&new_volume->hr_bds); 242 216 new_volume->hr_bds.ops = &hr_raid0_bd_ops; 243 217 new_volume->hr_bds.sarg = new_volume; 244 new_volume->nblocks = total_blocks;245 new_volume->bsize = bsize;246 218 247 219 rc = hr_register_volume(new_volume); 248 220 if (rc != EOK) 249 goto error; 250 251 return EOK; 252 error: 253 hr_fini_devs(new_volume); 254 return rc; 221 return rc; 222 223 return EOK; 255 224 } 256 225 -
uspace/srv/bd/hr/raid1.c
ree83e9c rb0f1366 47 47 #include <str_error.h> 48 48 49 #include "util.h" 49 50 #include "var.h" 50 #include "util.h"51 51 52 52 extern fibril_mutex_t big_lock; … … 85 85 } 86 86 87 static errno_t hr_raid1_bd_sync_cache(bd_srv_t *bd, aoff64_t ba, size_t size)87 static errno_t hr_raid1_bd_sync_cache(bd_srv_t *bd, aoff64_t ba, size_t cnt) 88 88 { 89 89 fibril_mutex_lock(&big_lock); … … 93 93 size_t i; 94 94 95 rc = hr_calc_ba(vol, cnt, &ba); 96 if (rc != EOK) { 97 fibril_mutex_unlock(&big_lock); 98 return rc; 99 } 100 95 101 for (i = 0; i < vol->dev_no; i++) { 96 rc = block_sync_cache(vol->devs[i], ba, size);102 rc = block_sync_cache(vol->devs[i], ba, cnt); 97 103 if (rc != EOK) 98 104 break; … … 111 117 errno_t rc; 112 118 size_t i; 119 120 rc = hr_calc_ba(vol, cnt, &ba); 121 if (rc != EOK) { 122 fibril_mutex_unlock(&big_lock); 123 return rc; 124 } 113 125 114 126 for (i = 0; i < vol->dev_no; i++) { … … 131 143 size_t i; 132 144 145 rc = hr_calc_ba(vol, cnt, &ba); 146 if (rc != EOK) { 147 fibril_mutex_unlock(&big_lock); 148 return rc; 149 } 150 133 151 for (i = 0; i < vol->dev_no; i++) { 134 152 rc = block_write_direct(vol->devs[i], ba, cnt, data); … … 153 171 hr_volume_t *vol = bd->srvs->sarg; 154 172 155 *rnb = vol-> nblocks;173 *rnb = vol->data_blkno; 156 174 return EOK; 157 175 } … … 159 177 errno_t hr_raid1_create(hr_volume_t *new_volume) 160 178 { 179 errno_t rc; 180 161 181 assert(new_volume->level == hr_l_1); 162 182 … … 167 187 } 168 188 169 errno_t rc;170 size_t i, bsize, last_bsize;171 uint64_t nblocks, last_nblocks;172 uint64_t total_blocks = 0;173 174 rc = hr_init_devs(new_volume);175 if (rc != EOK)176 return rc;177 178 for (i = 0; i < new_volume->dev_no; i++) {179 rc = block_get_nblocks(new_volume->devs[i], &nblocks);180 if (rc != EOK)181 goto error;182 if (i != 0 && nblocks != last_nblocks) {183 log_msg(LOG_DEFAULT, LVL_ERROR,184 "number of blocks differs");185 rc = EINVAL;186 goto error;187 }188 total_blocks += nblocks;189 last_nblocks = nblocks;190 }191 192 for (i = 0; i < new_volume->dev_no; i++) {193 rc = block_get_bsize(new_volume->devs[i], &bsize);194 if (rc != EOK)195 goto error;196 if (i != 0 && bsize != last_bsize) {197 log_msg(LOG_DEFAULT, LVL_ERROR, "block sizes differ");198 rc = EINVAL;199 goto error;200 }201 last_bsize = bsize;202 }203 204 189 bd_srvs_init(&new_volume->hr_bds); 205 190 new_volume->hr_bds.ops = &hr_raid1_bd_ops; 206 191 new_volume->hr_bds.sarg = new_volume; 207 new_volume->nblocks = total_blocks / new_volume->dev_no;208 new_volume->bsize = bsize;209 192 210 193 rc = hr_register_volume(new_volume); 211 194 if (rc != EOK) 212 goto error; 213 214 return EOK; 215 error: 216 hr_fini_devs(new_volume); 217 return rc; 195 return rc; 196 197 return EOK; 218 198 } 219 199 -
uspace/srv/bd/hr/util.c
ree83e9c rb0f1366 43 43 #include <str_error.h> 44 44 45 #include "util.h" 45 46 #include "var.h" 46 #include "util.h"47 47 48 48 extern loc_srv_t *hr_srv; … … 82 82 errno_t hr_register_volume(hr_volume_t *new_volume) 83 83 { 84 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_register_volume()"); 85 84 86 errno_t rc; 85 87 service_id_t new_id; … … 120 122 } 121 123 124 errno_t hr_check_devs(hr_volume_t *vol) 125 { 126 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_check_devs()"); 127 128 errno_t rc; 129 size_t i, bsize, last_bsize; 130 uint64_t nblocks, last_nblocks; 131 uint64_t total_blocks = 0; 132 133 for (i = 0; i < vol->dev_no; i++) { 134 rc = block_get_nblocks(vol->devs[i], &nblocks); 135 if (rc != EOK) 136 goto error; 137 if (i != 0 && nblocks != last_nblocks) { 138 log_msg(LOG_DEFAULT, LVL_ERROR, 139 "number of blocks differs"); 140 rc = EINVAL; 141 goto error; 142 } 143 total_blocks += nblocks; 144 last_nblocks = nblocks; 145 } 146 147 for (i = 0; i < vol->dev_no; i++) { 148 rc = block_get_bsize(vol->devs[i], &bsize); 149 if (rc != EOK) 150 goto error; 151 if (i != 0 && bsize != last_bsize) { 152 log_msg(LOG_DEFAULT, LVL_ERROR, "block sizes differ"); 153 rc = EINVAL; 154 goto error; 155 } 156 last_bsize = bsize; 157 } 158 159 if (vol->level == hr_l_1) { 160 vol->nblocks = total_blocks / vol->dev_no; 161 } else if (vol->level == hr_l_0) { 162 vol->nblocks = total_blocks; 163 } else { 164 log_msg(LOG_DEFAULT, LVL_DEBUG, "unkown level, ok when assembling"); 165 vol->nblocks = 0; 166 } 167 168 vol->bsize = bsize; 169 170 error: 171 return rc; 172 } 173 174 errno_t hr_calc_ba(hr_volume_t *vol, size_t cnt, uint64_t *ba) 175 { 176 if (*ba + cnt > vol->data_blkno) 177 return ERANGE; 178 179 *ba = *ba + vol->data_offset; 180 return EOK; 181 } 182 122 183 /** @} 123 184 */ -
uspace/srv/bd/hr/util.h
ree83e9c rb0f1366 44 44 extern void hr_fini_devs(hr_volume_t *); 45 45 extern errno_t hr_register_volume(hr_volume_t *); 46 extern errno_t hr_check_devs(hr_volume_t *vol); 47 errno_t hr_calc_ba(hr_volume_t *vol, size_t cnt, uint64_t *ba); 46 48 47 49 #endif -
uspace/srv/bd/hr/var.h
ree83e9c rb0f1366 43 43 #define NAME "hr" 44 44 45 #define HR_STRIP_SIZE DATA_XFER_LIMIT 46 45 47 typedef struct hr_volume hr_volume_t; 46 48 … … 56 58 service_id_t devs[HR_MAXDEVS]; 57 59 uint64_t nblocks; 60 uint64_t data_blkno; 61 uint32_t data_offset; 62 service_id_t svc_id; 58 63 size_t bsize; 59 service_id_t svc_id;60 64 size_t dev_no; 61 65 hr_level_t level;
Note:
See TracChangeset
for help on using the changeset viewer.