1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "med_local.h" 30 #include "med_hash.h" 31 #include <sys/lvm/mdio.h> 32 #include <sys/lvm/md_mdiox.h> 33 #include <sys/lvm/md_crc.h> 34 35 static int med_db_is_inited = 0; 36 static Cache *med_db_cache = (Cache *) NULL; 37 static med_rec_t *med_db_medrp = NULL; 38 static int med_db_nma = 0; 39 static int med_db_nmu = 0; 40 static int rec_size = roundup(sizeof (med_rec_t), DEV_BSIZE); 41 static char *rec_buf = NULL; 42 static int dbfd = -1; 43 44 #define OP_FLAGS (O_RDWR | O_SYNC) 45 #define CR_FLAGS (OP_FLAGS | O_CREAT) 46 47 #define HASHSIZE 151 48 #define BSZ 4 49 50 #ifdef DEBUG 51 void 52 med_pr(void *keyp, int keyl, void *datap, int datal) 53 { 54 med_med_t *medp = (med_med_t *)keyp; 55 int medridx = *(int *)datap; 56 med_rec_t *medrp = &med_db_medrp[medridx]; 57 58 med_eprintf( 59 "key (%d)[keyp=0x%08x]: setno=%ld, setname=<%s>, caller=<%s>\n", 60 keyl, (unsigned)keyp, medp->med_setno, medp->med_setname, 61 medp->med_caller); 62 med_eprintf("data(%d)[datap=0x%x08][medrp=0x%x08]: medridx=%d\n", 63 datal, (unsigned)datap, (unsigned)medrp, medridx); 64 } 65 #endif /* DEBUG */ 66 67 static int 68 med_hash(void *datap, int datalen, int hsz) 69 { 70 med_med_t *medp = (med_med_t *)datap; 71 int i = datalen; 72 char *cp; 73 74 i = 0; 75 cp = medp->med_setname; 76 while (*cp != '\0') 77 i += *cp++; 78 79 cp = medp->med_caller; 80 while (*cp != '\0') 81 i += *cp++; 82 83 i *= medp->med_setno; 84 85 return (i % hsz); 86 } 87 88 /*ARGSUSED*/ 89 static int 90 med_comp(void *datap1, void *datap2, int datalen) 91 { 92 med_med_t *medp1 = (med_med_t *)datap1; 93 med_med_t *medp2 = (med_med_t *)datap2; 94 int ret; 95 96 97 ret = medp1->med_setno - medp2->med_setno; 98 99 if (ret != 0) 100 return (ret); 101 102 ret = strcmp(medp1->med_caller, medp2->med_caller); 103 104 if (ret != 0) 105 return (ret); 106 107 return (strcmp(medp1->med_setname, medp2->med_setname)); 108 } 109 110 static void 111 med_kfree(void *keyp) 112 { 113 med_med_t *medp = (med_med_t *)keyp; 114 115 (void) Free(medp->med_caller); 116 (void) Free(medp->med_setname); 117 (void) Free(keyp); 118 } 119 120 static int 121 add_key(med_med_t *medp, int medridx) 122 { 123 Item *itemp; 124 int len; 125 med_med_t *tmedp; 126 127 if (med_db_cache == (Cache *) NULL) { 128 len = init_cache(&med_db_cache, HASHSIZE, BSZ, med_hash, 129 med_comp, med_kfree, (void (*)())NULL); 130 if (len == -1) { 131 med_eprintf("add_key(): init_cache() failed.\n"); 132 return (-1); 133 } 134 } 135 136 len = sizeof (med_med_t); 137 138 if ((itemp = lookup_cache(med_db_cache, medp, len)) == Null_Item) { 139 if ((itemp = (Item *) Malloc(sizeof (*itemp))) == NULL) { 140 med_eprintf("add_key(): itemp = Malloc(%d)\n", 141 sizeof (*itemp)); 142 return (-1); 143 } 144 if ((tmedp = itemp->key = Malloc(len)) == NULL) { 145 med_eprintf("add_key(): itemp->key = Malloc(%d)\n", 146 len); 147 return (-1); 148 } 149 150 *tmedp = *medp; /* structure assignment */ 151 152 tmedp->med_caller = Malloc(strlen(medp->med_caller) + 1); 153 if (tmedp->med_caller == NULL) { 154 med_eprintf( 155 "add_key(): tmedp->med_caller = Malloc(%d)\n", 156 strlen(medp->med_caller) + 1); 157 return (-1); 158 } 159 (void) strcpy(tmedp->med_caller, medp->med_caller); 160 161 tmedp->med_setname = Malloc(strlen(medp->med_setname) + 1); 162 if (tmedp->med_setname == NULL) { 163 med_eprintf( 164 "add_key(): tmedp->med_setname = Malloc(%d)\n", 165 strlen(medp->med_setname) + 1); 166 return (-1); 167 } 168 (void) strcpy(tmedp->med_setname, medp->med_setname); 169 170 itemp->keyl = len; 171 172 if ((itemp->data = Malloc(sizeof (int))) == NULL) { 173 med_eprintf("add_key(): itemp->data = Malloc(%d)\n", 174 sizeof (med_rec_t *)); 175 return (-1); 176 } 177 178 *(int *)itemp->data = medridx; 179 180 itemp->datal = sizeof (int); 181 182 if (add_cache(med_db_cache, itemp) == -1) { 183 med_eprintf("add_key(): add_cache() failed.\n"); 184 return (-1); 185 } 186 return (0); 187 } 188 return (1); 189 } 190 191 static int 192 del_key(med_med_t *medp) 193 { 194 Item *itemp; 195 int len; 196 197 if (med_db_cache == (Cache *) NULL) 198 return (0); 199 200 len = sizeof (med_med_t); 201 202 if ((itemp = lookup_cache(med_db_cache, medp, len)) == Null_Item) 203 return (0); 204 205 (void) del_cache(med_db_cache, itemp); 206 207 return (0); 208 } 209 210 static int 211 find_key(med_med_t *medp) 212 { 213 Item *itemp; 214 int len; 215 216 if (med_db_cache == (Cache *) NULL) 217 return (-1); 218 219 len = sizeof (med_med_t); 220 221 if ((itemp = lookup_cache(med_db_cache, medp, len)) == Null_Item) 222 return (-1); 223 224 return (*(int *)itemp->data); 225 } 226 227 static int 228 add_db_keys(int medridx, med_err_t *medep) 229 { 230 med_med_t med; 231 med_rec_t *medrp; 232 int i; 233 234 for (i = 0; i < MD_MAXSIDES; i++) { 235 medrp = &med_db_medrp[medridx]; 236 if (medrp->med_rec_nodes[i][0] == '\0') 237 continue; 238 med.med_setno = medrp->med_rec_sn; 239 med.med_setname = medrp->med_rec_snm; 240 med.med_caller = medrp->med_rec_nodes[i]; 241 if (add_key(&med, medridx) == -1) 242 return (med_error(medep, MDE_MED_DBKEYADDFAIL, 243 medrp->med_rec_nodes[i])); 244 } 245 return (0); 246 } 247 248 static int 249 del_db_keys(int medridx, med_err_t *medep) 250 { 251 med_med_t med; 252 med_rec_t *medrp; 253 int i; 254 255 for (i = 0; i < MD_MAXSIDES; i++) { 256 medrp = &med_db_medrp[medridx]; 257 if (medrp->med_rec_nodes[i][0] == '\0') 258 continue; 259 med.med_setno = medrp->med_rec_sn; 260 med.med_setname = medrp->med_rec_snm; 261 med.med_caller = medrp->med_rec_nodes[i]; 262 if (del_key(&med) == -1) 263 return (med_error(medep, MDE_MED_DBKEYDELFAIL, 264 medrp->med_rec_nodes[i])); 265 } 266 return (0); 267 } 268 269 static int 270 alloc_rec_buf(med_err_t *medep) 271 { 272 if (rec_buf == NULL) { 273 if ((rec_buf = Malloc(rec_size)) == NULL) 274 return (med_error(medep, errno, 275 "alloc_rec_buf: Malloc()")); 276 } 277 278 (void) memset(rec_buf, '\0', rec_size); 279 return (0); 280 } 281 282 static void 283 free_rec_buf(void) 284 { 285 if (rec_buf == NULL) 286 return; 287 288 Free(rec_buf); 289 rec_buf = NULL; 290 } 291 292 static int 293 write_hdr( 294 int dbfd, 295 med_err_t *medep 296 ) 297 { 298 med_db_hdr_t dbh; 299 300 if (alloc_rec_buf(medep)) 301 return (-1); 302 303 (void) memset(&dbh, '\0', sizeof (med_db_hdr_t)); 304 305 /* Setup the new hdr record */ 306 dbh.med_dbh_mag = MED_DB_MAGIC; 307 dbh.med_dbh_rev = MED_DB_REV; 308 dbh.med_dbh_nm = med_db_nmu; 309 310 /* Checksum new header */ 311 crcgen(&dbh, &dbh.med_dbh_cks, sizeof (med_db_hdr_t), NULL); 312 313 /* Position to the beginning of the file */ 314 if (lseek(dbfd, 0, SEEK_SET) == -1) 315 return (med_error(medep, errno, "write_hdr: lseek()")); 316 317 /* Copy the header into the output buffer */ 318 (void) memmove(rec_buf, &dbh, sizeof (med_db_hdr_t)); 319 320 /* Write out the header */ 321 if (write(dbfd, rec_buf, rec_size) == -1) 322 return (med_error(medep, errno, "write_hdr: write()")); 323 324 return (0); 325 } 326 327 static int 328 write_rec( 329 int dbfd, 330 med_rec_t *medrp, 331 med_err_t *medep 332 ) 333 { 334 uint_t save_flags = 0; 335 uint_t save_cks = 0; 336 337 if (alloc_rec_buf(medep)) 338 return (-1); 339 340 if (medrp->med_rec_data.med_dat_fl) { 341 save_flags = medrp->med_rec_data.med_dat_fl; 342 save_cks = medrp->med_rec_data.med_dat_cks; 343 medrp->med_rec_data.med_dat_fl = 0; 344 /* Checksum the new data */ 345 crcgen(&medrp->med_rec_data, &medrp->med_rec_data.med_dat_cks, 346 sizeof (med_data_t), NULL); 347 } 348 349 /* Checksum record */ 350 crcgen(medrp, &medrp->med_rec_cks, sizeof (med_rec_t), NULL); 351 352 /* Load the record into the output buffer */ 353 (void) memmove(rec_buf, medrp, sizeof (med_rec_t)); 354 355 if (save_flags) { 356 medrp->med_rec_data.med_dat_fl = save_flags; 357 medrp->med_rec_data.med_dat_cks = save_cks; 358 /* Re-checksum the updated record */ 359 crcgen(medrp, &medrp->med_rec_cks, sizeof (med_rec_t), NULL); 360 } 361 362 /* Write out the record */ 363 if (write(dbfd, rec_buf, rec_size) == -1) 364 return (med_error(medep, errno, "write_rec: write()")); 365 366 return (0); 367 } 368 369 static int 370 open_dbfile(med_err_t *medep) 371 { 372 if (dbfd != -1) 373 return (0); 374 375 /* Open the database file */ 376 if ((dbfd = open(MED_DB_FILE, OP_FLAGS, 0644)) == -1) { 377 if (errno != ENOENT) 378 return (med_error(medep, errno, "open_dbfile: open()")); 379 380 if ((dbfd = open(MED_DB_FILE, CR_FLAGS, 0644)) == -1) 381 return (med_error(medep, errno, 382 "open_dbfile: open(create)")); 383 } 384 385 /* Try to take an advisory lock on the file */ 386 if (lockf(dbfd, F_TLOCK, (off_t)0) == -1) { 387 (void) med_error(medep, errno, "open_dbfile: lockf(F_TLOCK)"); 388 medde_perror(medep, ""); 389 med_exit(1); 390 } 391 392 return (0); 393 } 394 395 static int 396 close_dbfile(med_err_t *medep) 397 { 398 if (dbfd == -1) 399 return (0); 400 401 /* Make sure we are at the beginning of the file */ 402 if (lseek(dbfd, 0, SEEK_SET) == -1) 403 return (med_error(medep, errno, "close_dbfile: lseek()")); 404 405 /* Release the advisory lock on the file */ 406 if (lockf(dbfd, F_ULOCK, 0LL) == -1) { 407 (void) med_error(medep, errno, "close_dbfile: lockf(F_ULOCK)"); 408 medde_perror(medep, ""); 409 med_exit(1); 410 } 411 412 if (close(dbfd) == -1) 413 return (med_error(medep, errno, "close_dbfile: close()")); 414 415 dbfd = -1; 416 417 return (0); 418 } 419 420 static int 421 med_db_del_rec(med_med_t *medp, med_err_t *medep) 422 { 423 med_rec_t *medrp = NULL; 424 int i; 425 int medridx = -1; 426 427 428 if (! med_db_is_inited) 429 return (med_error(medep, MDE_MED_DBNOTINIT, "med_db_del_rec")); 430 431 if ((medridx = find_key(medp)) == -1) 432 return (0); 433 434 /* Delete the old keys */ 435 if (del_db_keys(medridx, medep)) 436 return (-1); 437 438 medrp = &med_db_medrp[medridx]; 439 440 /* Mark the record in core as deleted */ 441 medrp->med_rec_fl |= MED_RFL_DEL; 442 443 /* Decrement the used slot count */ 444 med_db_nmu--; 445 446 /* Get ready to re-write the file */ 447 if (ftruncate(dbfd, 0) == -1) 448 return (med_error(medep, errno, "med_db_del_rec: ftruncate()")); 449 450 if (write_hdr(dbfd, medep)) 451 return (-1); 452 453 for (i = 0; i < med_db_nma; i++) { 454 medrp = &med_db_medrp[i]; 455 456 if (medrp->med_rec_fl & MED_RFL_DEL) 457 continue; 458 459 /* Determine our location in the file */ 460 if ((medrp->med_rec_foff = lseek(dbfd, 0, SEEK_CUR)) == -1) 461 return (med_error(medep, errno, 462 "med_db_del_rec: lseek()")); 463 464 if (write_rec(dbfd, medrp, medep)) 465 return (-1); 466 } 467 return (0); 468 } 469 470 static int 471 cmp_medrec(med_rec_t *omedrp, med_rec_t *nmedrp) 472 { 473 int ret; 474 int i; 475 476 if (omedrp->med_rec_mag != nmedrp->med_rec_mag) 477 return (0); 478 479 if (omedrp->med_rec_rev != nmedrp->med_rec_rev) 480 return (0); 481 482 /* Can't compare checksums, since the new record has no data yet */ 483 484 /* Can't compare flags, since the in-core may have golden */ 485 486 if (omedrp->med_rec_sn != nmedrp->med_rec_sn) 487 return (0); 488 489 if (strcmp(omedrp->med_rec_snm, nmedrp->med_rec_snm) != 0) 490 return (0); 491 492 for (i = 0; i < MD_MAXSIDES; i++) { 493 if (omedrp->med_rec_nodes[i][0] == '\0' && 494 nmedrp->med_rec_nodes[i][0] == '\0') 495 continue; 496 497 ret = strcmp(omedrp->med_rec_nodes[i], 498 nmedrp->med_rec_nodes[i]); 499 if (ret != 0) 500 return (0); 501 } 502 503 ret = memcmp(&omedrp->med_rec_meds, &nmedrp->med_rec_meds, 504 sizeof (md_h_arr_t)); 505 if (ret != 0) 506 return (0); 507 508 return (1); 509 } 510 511 /* 512 * Exported routines 513 */ 514 515 int 516 med_db_init(med_err_t *medep) 517 { 518 int i; 519 int err = 0; 520 int ret; 521 struct stat statb; 522 med_db_hdr_t *dbhp; 523 med_rec_t *medrp; 524 int nm; 525 off_t cur_off; 526 527 if (med_db_is_inited) 528 return (0); 529 530 if (open_dbfile(medep)) 531 return (-1); 532 533 if (fstat(dbfd, &statb) == -1) 534 return (med_error(medep, errno, "med_db_init: fstat()")); 535 536 /* Empty file */ 537 if (statb.st_size == 0) 538 goto out; 539 540 /* File should be a multiple of the record size */ 541 if (((int)(statb.st_size % (off_t)rec_size)) != 0) 542 return (med_error(medep, MDE_MED_DBSZBAD, "med_db_init")); 543 544 if (alloc_rec_buf(medep)) 545 return (-1); 546 547 /* Read in the file header */ 548 if ((ret = read(dbfd, rec_buf, rec_size)) == -1) 549 return (med_error(medep, errno, "med_db_init: read(hdr)")); 550 551 if (ret != rec_size) 552 return (med_error(medep, MDE_MED_DBHDRSZBAD, "med_db_init")); 553 554 /*LINTED*/ 555 dbhp = (med_db_hdr_t *)rec_buf; 556 557 /* Header magic is not OK */ 558 if (dbhp->med_dbh_mag != MED_DB_MAGIC) 559 return (med_error(medep, MDE_MED_DBHDRMAGBAD, "med_db_init")); 560 561 /* Header revision is not OK */ 562 if (dbhp->med_dbh_rev != MED_DB_REV) 563 return (med_error(medep, MDE_MED_DBHDRREVBAD, "med_db_init")); 564 565 /* Header checksum is not OK */ 566 if (crcchk(dbhp, &dbhp->med_dbh_cks, sizeof (med_db_hdr_t), NULL)) 567 return (med_error(medep, MDE_MED_DBHDRCKSBAD, "med_db_init")); 568 569 /* File size does not add up */ 570 if (((off_t)((dbhp->med_dbh_nm * rec_size) + rec_size)) 571 != statb.st_size) 572 return (med_error(medep, MDE_MED_DBSZBAD, "med_db_init")); 573 574 if ((nm = dbhp->med_dbh_nm) > 0) { 575 /* Allocate space to hold the records to be read next */ 576 med_db_medrp = (med_rec_t *)Calloc(nm, sizeof (med_rec_t)); 577 if (med_db_medrp == NULL) 578 return (med_error(medep, errno, 579 "med_db_init: Calloc(med_db_medrp)")); 580 } 581 582 /* Read in all the records */ 583 for (i = 0; i < nm; i++) { 584 if ((cur_off = lseek(dbfd, 0, SEEK_CUR)) == -1) { 585 err = med_error(medep, errno, 586 "med_db_init: lseek()"); 587 goto out; 588 } 589 590 (void) memset(rec_buf, '\0', rec_size); 591 592 if ((ret = read(dbfd, rec_buf, rec_size)) == -1) { 593 err = med_error(medep, errno, 594 "med_db_init: read() rec"); 595 goto out; 596 } 597 598 if (ret != rec_size) { 599 err = med_error(medep, MDE_MED_DBRECSZBAD, 600 "med_db_init"); 601 goto out; 602 } 603 604 /*LINTED*/ 605 medrp = (med_rec_t *)rec_buf; 606 607 /* Record magic is not OK */ 608 if (medrp->med_rec_mag != MED_REC_MAGIC) { 609 err = med_error(medep, MDE_MED_DBRECMAGBAD, 610 "med_db_init"); 611 goto out; 612 } 613 614 /* Record revision is not OK */ 615 if (medrp->med_rec_rev != MED_REC_REV) { 616 err = med_error(medep, MDE_MED_DBRECREVBAD, 617 "med_db_init"); 618 goto out; 619 } 620 621 /* Record checksum is not OK */ 622 ret = crcchk(medrp, &medrp->med_rec_cks, sizeof (med_rec_t), 623 NULL); 624 if (ret) { 625 err = med_error(medep, MDE_MED_DBRECCKSBAD, 626 "med_db_init"); 627 goto out; 628 } 629 630 /* Record is not where it is supposed to be */ 631 if (medrp->med_rec_foff != cur_off) { 632 err = med_error(medep, MDE_MED_DBRECOFFBAD, 633 "med_db_init"); 634 goto out; 635 } 636 637 med_db_medrp[i] = *medrp; /* structure assignment */ 638 } 639 640 /* Add the keys to access this record */ 641 for (i = 0; i < nm; i++) 642 if ((err = add_db_keys(i, medep)) == -1) 643 goto out; 644 645 med_db_nma = nm; 646 med_db_nmu = nm; 647 648 out: 649 if (err && med_db_medrp != NULL) 650 Free(med_db_medrp); 651 652 if (!err) 653 med_db_is_inited = 1; 654 655 return (err); 656 } 657 658 med_rec_t * 659 med_db_get_rec(med_med_t *medp, med_err_t *medep) 660 { 661 int medridx = -1; 662 663 if ((medridx = find_key(medp)) == -1) { 664 (void) med_error(medep, MDE_MED_DBRECNOENT, "med_db_get_rec"); 665 return (NULL); 666 } 667 668 return (&med_db_medrp[medridx]); 669 } 670 671 med_data_t * 672 med_db_get_data(med_med_t *medp, med_err_t *medep) 673 { 674 int medridx = -1; 675 676 if ((medridx = find_key(medp)) == -1) { 677 (void) med_error(medep, MDE_MED_DBRECNOENT, "med_db_get_data"); 678 return (NULL); 679 } 680 681 return (&med_db_medrp[medridx].med_rec_data); 682 } 683 684 int 685 med_db_put_rec(med_med_t *medp, med_rec_t *nmedrp, med_err_t *medep) 686 { 687 med_rec_t *medrp = NULL; 688 med_rec_t *tmedrp = NULL; 689 int i; 690 int found = 0; 691 int medridx = -1; 692 693 694 if (! med_db_is_inited) 695 return (med_error(medep, MDE_MED_DBNOTINIT, "med_db_put_rec")); 696 697 if (medp->med_setno != nmedrp->med_rec_sn) 698 return (med_error(medep, MDE_MED_DBARGSMISMATCH, 699 "med_db_put_rec")); 700 701 /* See if we are still considered a mediator - is this a delete? */ 702 for (i = 0; i < MED_MAX_HOSTS; i++) { 703 if (nmedrp->med_rec_meds.n_lst[i].a_cnt == 0) 704 continue; 705 706 if (strcmp(nmedrp->med_rec_meds.n_lst[i].a_nm[0], 707 mynode()) == 0) { 708 found = 1; 709 break; 710 } 711 } 712 713 /* If it is a delete, make it happen */ 714 if (! found) 715 return (med_db_del_rec(medp, medep)); 716 717 /* See if there is an existing record */ 718 if ((medridx = find_key(medp)) != -1) { 719 720 medrp = &med_db_medrp[medridx]; 721 722 /* Delete the old keys */ 723 if (del_db_keys(medridx, medep)) 724 return (-1); 725 726 /* Decrement the used slot count */ 727 med_db_nmu--; 728 } else { 729 for (i = 0; i < MED_MAX_HOSTS; i++) { 730 med_med_t tmed; 731 732 if (nmedrp->med_rec_meds.n_lst[i].a_cnt == 0) 733 continue; 734 735 if (strcmp(nmedrp->med_rec_meds.n_lst[i].a_nm[0], 736 medp->med_caller) == 0) 737 continue; 738 739 tmed = *medp; /* structure assignment */ 740 741 tmed.med_caller = 742 Strdup(nmedrp->med_rec_meds.n_lst[i].a_nm[0]); 743 744 medridx = find_key(&tmed); 745 746 Free(tmed.med_caller); 747 748 if (medridx != -1) { 749 medrp = &med_db_medrp[medridx]; 750 751 if (cmp_medrec(medrp, nmedrp)) 752 return (0); 753 } 754 } 755 } 756 757 /* Allocate more space if needed */ 758 if ((med_db_nmu + 1) > med_db_nma) { 759 760 /* Allocate more space to hold the new record */ 761 tmedrp = (med_rec_t *)Calloc((med_db_nmu + 1), 762 sizeof (med_rec_t)); 763 if (tmedrp == NULL) 764 return (med_error(medep, errno, 765 "med_db_put_rec: Re-Calloc(tmedrp)")); 766 767 /* Copy the existing information into the new area */ 768 for (i = 0; i < med_db_nma; i++) 769 tmedrp[i] = med_db_medrp[i]; /* structure assignment */ 770 771 med_db_nmu++; 772 med_db_nma = med_db_nmu; 773 774 if (med_db_medrp) 775 Free(med_db_medrp); 776 777 med_db_medrp = tmedrp; 778 779 medridx = med_db_nma - 1; 780 781 /* Initialize */ 782 medrp = &med_db_medrp[medridx]; 783 medrp->med_rec_mag = MED_REC_MAGIC; 784 medrp->med_rec_rev = MED_REC_REV; 785 medrp->med_rec_sn = nmedrp->med_rec_sn; 786 (void) strcpy(medrp->med_rec_snm, nmedrp->med_rec_snm); 787 788 /* Calculate the record offset */ 789 medrp->med_rec_foff = (off_t)(((med_db_nma - 1) * rec_size) + 790 rec_size); 791 } else { 792 /* 793 * We did not find the record, but have space allocated. 794 * Find an empty slot. 795 */ 796 if (medrp == NULL) { 797 for (i = 0; i < med_db_nma; i++) { 798 medrp = &med_db_medrp[i]; 799 800 if (! (medrp->med_rec_fl & MED_RFL_DEL)) 801 continue; 802 803 medridx = i; 804 805 /* Mark as no longer deleted */ 806 medrp->med_rec_fl &= ~MED_RFL_DEL; 807 808 /* Initialize */ 809 medrp->med_rec_mag = MED_REC_MAGIC; 810 medrp->med_rec_rev = MED_REC_REV; 811 medrp->med_rec_sn = nmedrp->med_rec_sn; 812 (void) strcpy(medrp->med_rec_snm, 813 nmedrp->med_rec_snm); 814 815 /* Calculate the new offset of the record */ 816 medrp->med_rec_foff = (off_t) 817 ((med_db_nmu * rec_size) + rec_size); 818 819 /* Clear the old data */ 820 (void) memset(&medrp->med_rec_data, '\0', 821 sizeof (med_data_t)); 822 823 break; 824 } 825 } 826 med_db_nmu++; 827 } 828 829 assert(medridx != -1); 830 831 /* Update the record with the new information */ 832 medrp->med_rec_meds = nmedrp->med_rec_meds; /* structure assignment */ 833 834 for (i = 0; i < MD_MAXSIDES; i++) 835 (void) strcpy(medrp->med_rec_nodes[i], 836 nmedrp->med_rec_nodes[i]); 837 838 if (write_hdr(dbfd, medep)) 839 return (-1); 840 841 /* Position to record location */ 842 if (lseek(dbfd, medrp->med_rec_foff, SEEK_SET) == -1) 843 return (med_error(medep, errno, "med_db_put_rec: lseek(rec)")); 844 845 if (write_rec(dbfd, medrp, medep)) 846 return (-1); 847 848 /* Add the keys for this record */ 849 if (add_db_keys(medridx, medep)) 850 return (-1); 851 852 return (0); 853 } 854 855 int 856 med_db_put_data(med_med_t *medp, med_data_t *meddp, med_err_t *medep) 857 { 858 med_rec_t *medrp = NULL; 859 int medridx = -1; 860 861 862 if (! med_db_is_inited) 863 return (med_error(medep, MDE_MED_DBNOTINIT, "med_db_pud_data")); 864 865 if (medp->med_setno != meddp->med_dat_sn) 866 return (med_error(medep, MDE_MED_DBARGSMISMATCH, 867 "med_db_put_data")); 868 869 if ((medridx = find_key(medp)) == -1) 870 return (med_error(medep, MDE_MED_DBRECNOENT, 871 "med_db_put_data")); 872 873 medrp = &med_db_medrp[medridx]; 874 875 medrp->med_rec_data = *meddp; /* structure assignment */ 876 877 /* Go to location of the record */ 878 if (lseek(dbfd, medrp->med_rec_foff, SEEK_SET) == -1) 879 return (med_error(medep, errno, "med_db_put_data: lseek()")); 880 881 if (write_rec(dbfd, medrp, medep)) 882 return (-1); 883 884 return (0); 885 } 886 887 int 888 med_db_finit(med_err_t *medep) 889 { 890 des_cache(&med_db_cache); 891 Free(med_db_medrp); 892 free_rec_buf(); 893 if (close_dbfile(medep)) 894 return (-1); 895 return (0); 896 } 897