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