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 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * get timestamp from device 29 */ 30 31 #include <meta.h> 32 33 /* 34 * get timestamp 35 */ 36 int 37 getdevstamp( 38 mddrivename_t *dnp, 39 time_t *stamp, /* return timestamp here */ 40 md_error_t *ep 41 ) 42 { 43 int fd; 44 int partno; 45 struct extvtoc vtocbuf; 46 mdname_t *np; 47 48 if ((np = metaslicename(dnp, MD_SLICE0, ep)) == NULL) 49 return (-1); 50 51 /* open given device */ 52 if ((fd = open(np->rname, O_RDONLY | O_NDELAY, 0)) < 0) 53 return (mdsyserror(ep, errno, np->cname)); 54 55 /* re-read vtoc */ 56 if (meta_getvtoc(fd, np->cname, &vtocbuf, &partno, ep) == -1) { 57 (void) close(fd); 58 return (-1); 59 } 60 61 /* close device */ 62 (void) close(fd); /* sd/ssd bug */ 63 64 /* return timestamp, success */ 65 *stamp = vtocbuf.timestamp[partno]; 66 return (0); 67 } 68 69 /* 70 * returns 71 * 0 on success, 72 * ENOTSUP if it's not a device with a vtoc 73 * -1 on failure 74 */ 75 int 76 setdevstamp( 77 mddrivename_t *dnp, 78 time_t *stamp, /* returned timestamp */ 79 md_error_t *ep 80 ) 81 { 82 int fd; 83 int partno; 84 struct extvtoc vtocbuf; 85 time_t now = time(NULL); 86 mdname_t *np; 87 88 if ((np = metaslicename(dnp, MD_SLICE0, ep)) == NULL) 89 return (-1); 90 91 /* open for vtoc */ 92 if ((fd = open(np->rname, O_RDWR | O_NDELAY, 0)) < 0) 93 return (mdsyserror(ep, errno, np->cname)); 94 95 if (meta_getvtoc(fd, np->cname, &vtocbuf, &partno, ep) == -1) { 96 (void) close(fd); 97 if (partno == VT_ENOTSUP) 98 return (ENOTSUP); 99 else 100 return (-1); 101 } 102 103 *stamp = vtocbuf.timestamp[partno] = now; 104 105 if (meta_setvtoc(fd, np->cname, &vtocbuf, ep) == -1) { 106 (void) close(fd); 107 return (-1); 108 } 109 110 /* Clear the timestamp */ 111 vtocbuf.timestamp[partno] = 0; 112 113 if (meta_getvtoc(fd, np->cname, &vtocbuf, &partno, ep) == -1) { 114 (void) close(fd); 115 return (-1); 116 } 117 118 (void) close(fd); /* sd/ssd bug */ 119 120 if (*stamp != vtocbuf.timestamp[partno]) 121 return (mddeverror(ep, MDE_CANTVERIFY_VTOC, NODEV64, 122 np->cname)); 123 124 return (0); 125 } 126