xenstore.c (41716b8d5151d2bec72b6796ed58b6206cdb4779) | xenstore.c (5f8f664619ecc3afcbc3573a64a814646b3584ba) |
---|---|
1/****************************************************************************** 2 * xenstore.c 3 * 4 * Low-level kernel interface to the XenStore. 5 * 6 * Copyright (C) 2005 Rusty Russell, IBM Corporation 7 * Copyright (C) 2009,2010 Spectra Logic Corporation 8 * --- 188 unchanged lines hidden (view full) --- 197 * List of pending watch callback events. 198 */ 199 struct xs_stored_msg_list watch_events; 200 201 /** Lock protecting the watch calback list. */ 202 struct mtx watch_events_lock; 203 204 /** | 1/****************************************************************************** 2 * xenstore.c 3 * 4 * Low-level kernel interface to the XenStore. 5 * 6 * Copyright (C) 2005 Rusty Russell, IBM Corporation 7 * Copyright (C) 2009,2010 Spectra Logic Corporation 8 * --- 188 unchanged lines hidden (view full) --- 197 * List of pending watch callback events. 198 */ 199 struct xs_stored_msg_list watch_events; 200 201 /** Lock protecting the watch calback list. */ 202 struct mtx watch_events_lock; 203 204 /** |
205 * Sleepable lock used to prevent VM suspension while a 206 * xenstore transaction is outstanding. 207 * 208 * Each active transaction holds a shared lock on the 209 * suspend mutex. Our suspend method blocks waiting 210 * to acquire an exclusive lock. This guarantees that 211 * suspend processing will only proceed once all active 212 * transactions have been retired. 213 */ 214 struct sx suspend_mutex; 215 216 /** | |
217 * The processid of the xenwatch thread. 218 */ 219 pid_t xenwatch_pid; 220 221 /** 222 * Sleepable mutex used to gate the execution of XenStore 223 * watch event callbacks. 224 * --- 480 unchanged lines hidden (view full) --- 705 error = xs_process_msg(&type); 706 if (error) 707 printf("XENSTORE error %d while reading message\n", 708 error); 709 } 710} 711 712/*---------------- XenStore Message Request/Reply Processing -----------------*/ | 205 * The processid of the xenwatch thread. 206 */ 207 pid_t xenwatch_pid; 208 209 /** 210 * Sleepable mutex used to gate the execution of XenStore 211 * watch event callbacks. 212 * --- 480 unchanged lines hidden (view full) --- 693 error = xs_process_msg(&type); 694 if (error) 695 printf("XENSTORE error %d while reading message\n", 696 error); 697 } 698} 699 700/*---------------- XenStore Message Request/Reply Processing -----------------*/ |
713/** 714 * Filter invoked before transmitting any message to the XenStore service. 715 * 716 * The role of the filter may expand, but currently serves to manage 717 * the interactions of messages with transaction state. 718 * 719 * \param request_msg_type The message type for the request. 720 */ 721static inline void 722xs_request_filter(uint32_t request_msg_type) 723{ 724 if (request_msg_type == XS_TRANSACTION_START) 725 sx_slock(&xs.suspend_mutex); 726} 727 728/** 729 * Filter invoked after transmitting any message to the XenStore service. 730 * 731 * The role of the filter may expand, but currently serves to manage 732 * the interactions of messages with transaction state. 733 * 734 * \param request_msg_type The message type for the original request. 735 * \param reply_msg_type The message type for any received reply. 736 * \param request_reply_error The error status from the attempt to send 737 * the request or retrieve the reply. 738 */ 739static inline void 740xs_reply_filter(uint32_t request_msg_type, 741 uint32_t reply_msg_type, int request_reply_error) 742{ 743 /* 744 * The count of transactions drops if we attempted 745 * to end a transaction (even if that attempt fails 746 * in error), we receive a transaction end acknowledgement, 747 * or if our attempt to begin a transaction fails. 748 */ 749 if (request_msg_type == XS_TRANSACTION_END 750 || (request_reply_error == 0 && reply_msg_type == XS_TRANSACTION_END) 751 || (request_msg_type == XS_TRANSACTION_START 752 && (request_reply_error != 0 || reply_msg_type == XS_ERROR))) 753 sx_sunlock(&xs.suspend_mutex); 754 755} 756 | |
757#define xsd_error_count (sizeof(xsd_errors) / sizeof(xsd_errors[0])) 758 759/** 760 * Convert a XenStore error string into an errno number. 761 * 762 * \param errorstring The error string to convert. 763 * 764 * \return The errno best matching the input string. --- 73 unchanged lines hidden (view full) --- 838 */ 839int 840xs_dev_request_and_reply(struct xsd_sockmsg *msg, void **result) 841{ 842 uint32_t request_type; 843 int error; 844 845 request_type = msg->type; | 701#define xsd_error_count (sizeof(xsd_errors) / sizeof(xsd_errors[0])) 702 703/** 704 * Convert a XenStore error string into an errno number. 705 * 706 * \param errorstring The error string to convert. 707 * 708 * \return The errno best matching the input string. --- 73 unchanged lines hidden (view full) --- 782 */ 783int 784xs_dev_request_and_reply(struct xsd_sockmsg *msg, void **result) 785{ 786 uint32_t request_type; 787 int error; 788 789 request_type = msg->type; |
846 xs_request_filter(request_type); | |
847 848 sx_xlock(&xs.request_mutex); 849 if ((error = xs_write_store(msg, sizeof(*msg) + msg->len)) == 0) 850 error = xs_read_reply(&msg->type, &msg->len, result); 851 sx_xunlock(&xs.request_mutex); 852 | 790 791 sx_xlock(&xs.request_mutex); 792 if ((error = xs_write_store(msg, sizeof(*msg) + msg->len)) == 0) 793 error = xs_read_reply(&msg->type, &msg->len, result); 794 sx_xunlock(&xs.request_mutex); 795 |
853 xs_reply_filter(request_type, msg->type, error); 854 | |
855 return (error); 856} 857 858/** 859 * Send a message with an optionally muti-part body to the XenStore service. 860 * 861 * \param t The transaction to use for this request. 862 * \param request_type The type of message to send. --- 19 unchanged lines hidden (view full) --- 882 883 msg.tx_id = t.id; 884 msg.req_id = 0; 885 msg.type = request_type; 886 msg.len = 0; 887 for (i = 0; i < num_vecs; i++) 888 msg.len += iovec[i].iov_len; 889 | 796 return (error); 797} 798 799/** 800 * Send a message with an optionally muti-part body to the XenStore service. 801 * 802 * \param t The transaction to use for this request. 803 * \param request_type The type of message to send. --- 19 unchanged lines hidden (view full) --- 823 824 msg.tx_id = t.id; 825 msg.req_id = 0; 826 msg.type = request_type; 827 msg.len = 0; 828 for (i = 0; i < num_vecs; i++) 829 msg.len += iovec[i].iov_len; 830 |
890 xs_request_filter(request_type); 891 | |
892 sx_xlock(&xs.request_mutex); 893 error = xs_write_store(&msg, sizeof(msg)); 894 if (error) { 895 printf("xs_talkv failed %d\n", error); 896 goto error_lock_held; 897 } 898 899 for (i = 0; i < num_vecs; i++) { 900 error = xs_write_store(iovec[i].iov_base, iovec[i].iov_len); 901 if (error) { 902 printf("xs_talkv failed %d\n", error); 903 goto error_lock_held; 904 } 905 } 906 907 error = xs_read_reply(&msg.type, len, &ret); 908 909error_lock_held: 910 sx_xunlock(&xs.request_mutex); | 831 sx_xlock(&xs.request_mutex); 832 error = xs_write_store(&msg, sizeof(msg)); 833 if (error) { 834 printf("xs_talkv failed %d\n", error); 835 goto error_lock_held; 836 } 837 838 for (i = 0; i < num_vecs; i++) { 839 error = xs_write_store(iovec[i].iov_base, iovec[i].iov_len); 840 if (error) { 841 printf("xs_talkv failed %d\n", error); 842 goto error_lock_held; 843 } 844 } 845 846 error = xs_read_reply(&msg.type, len, &ret); 847 848error_lock_held: 849 sx_xunlock(&xs.request_mutex); |
911 xs_reply_filter(request_type, msg.type, error); | |
912 if (error) 913 return (error); 914 915 if (msg.type == XS_ERROR) { 916 error = xs_get_error(ret); 917 free(ret, M_XENSTORE); 918 return (error); 919 } --- 281 unchanged lines hidden (view full) --- 1201 1202 TAILQ_INIT(&xs.reply_list); 1203 TAILQ_INIT(&xs.watch_events); 1204 1205 mtx_init(&xs.ring_lock, "ring lock", NULL, MTX_DEF); 1206 mtx_init(&xs.reply_lock, "reply lock", NULL, MTX_DEF); 1207 sx_init(&xs.xenwatch_mutex, "xenwatch"); 1208 sx_init(&xs.request_mutex, "xenstore request"); | 850 if (error) 851 return (error); 852 853 if (msg.type == XS_ERROR) { 854 error = xs_get_error(ret); 855 free(ret, M_XENSTORE); 856 return (error); 857 } --- 281 unchanged lines hidden (view full) --- 1139 1140 TAILQ_INIT(&xs.reply_list); 1141 TAILQ_INIT(&xs.watch_events); 1142 1143 mtx_init(&xs.ring_lock, "ring lock", NULL, MTX_DEF); 1144 mtx_init(&xs.reply_lock, "reply lock", NULL, MTX_DEF); 1145 sx_init(&xs.xenwatch_mutex, "xenwatch"); 1146 sx_init(&xs.request_mutex, "xenstore request"); |
1209 sx_init(&xs.suspend_mutex, "xenstore suspend"); | |
1210 mtx_init(&xs.registered_watches_lock, "watches", NULL, MTX_DEF); 1211 mtx_init(&xs.watch_events_lock, "watch events", NULL, MTX_DEF); 1212 1213 /* Initialize the shared memory rings to talk to xenstored */ 1214 error = xs_init_comms(); 1215 if (error) 1216 return (error); 1217 --- 26 unchanged lines hidden (view full) --- 1244{ 1245 int error; 1246 1247 /* Suspend child Xen devices. */ 1248 error = bus_generic_suspend(dev); 1249 if (error != 0) 1250 return (error); 1251 | 1147 mtx_init(&xs.registered_watches_lock, "watches", NULL, MTX_DEF); 1148 mtx_init(&xs.watch_events_lock, "watch events", NULL, MTX_DEF); 1149 1150 /* Initialize the shared memory rings to talk to xenstored */ 1151 error = xs_init_comms(); 1152 if (error) 1153 return (error); 1154 --- 26 unchanged lines hidden (view full) --- 1181{ 1182 int error; 1183 1184 /* Suspend child Xen devices. */ 1185 error = bus_generic_suspend(dev); 1186 if (error != 0) 1187 return (error); 1188 |
1252 sx_xlock(&xs.suspend_mutex); | |
1253 sx_xlock(&xs.request_mutex); 1254 1255 return (0); 1256} 1257 1258/** 1259 * Resume XenStore operations after this VM is resumed. 1260 */ 1261static int 1262xs_resume(device_t dev __unused) 1263{ 1264 struct xs_watch *watch; 1265 char token[sizeof(watch) * 2 + 1]; 1266 1267 xs_init_comms(); 1268 1269 sx_xunlock(&xs.request_mutex); 1270 1271 /* | 1189 sx_xlock(&xs.request_mutex); 1190 1191 return (0); 1192} 1193 1194/** 1195 * Resume XenStore operations after this VM is resumed. 1196 */ 1197static int 1198xs_resume(device_t dev __unused) 1199{ 1200 struct xs_watch *watch; 1201 char token[sizeof(watch) * 2 + 1]; 1202 1203 xs_init_comms(); 1204 1205 sx_xunlock(&xs.request_mutex); 1206 1207 /* |
1272 * No need for registered_watches_lock: the suspend_mutex 1273 * is sufficient. | 1208 * NB: since xenstore childs have not been resumed yet, there's 1209 * no need to hold any watch mutex. Having clients try to add or 1210 * remove watches at this point (before xenstore is resumed) is 1211 * clearly a violantion of the resume order. |
1274 */ 1275 LIST_FOREACH(watch, &xs.registered_watches, list) { 1276 sprintf(token, "%lX", (long)watch); 1277 xs_watch(watch->node, token); 1278 } 1279 | 1212 */ 1213 LIST_FOREACH(watch, &xs.registered_watches, list) { 1214 sprintf(token, "%lX", (long)watch); 1215 xs_watch(watch->node, token); 1216 } 1217 |
1280 sx_xunlock(&xs.suspend_mutex); 1281 | |
1282 /* Resume child Xen devices. */ 1283 bus_generic_resume(dev); 1284 1285 return (0); 1286} 1287 1288/*-------------------- Private Device Attachment Data -----------------------*/ 1289static device_method_t xenstore_methods[] = { --- 336 unchanged lines hidden (view full) --- 1626xs_register_watch(struct xs_watch *watch) 1627{ 1628 /* Pointer in ascii is the token. */ 1629 char token[sizeof(watch) * 2 + 1]; 1630 int error; 1631 1632 sprintf(token, "%lX", (long)watch); 1633 | 1218 /* Resume child Xen devices. */ 1219 bus_generic_resume(dev); 1220 1221 return (0); 1222} 1223 1224/*-------------------- Private Device Attachment Data -----------------------*/ 1225static device_method_t xenstore_methods[] = { --- 336 unchanged lines hidden (view full) --- 1562xs_register_watch(struct xs_watch *watch) 1563{ 1564 /* Pointer in ascii is the token. */ 1565 char token[sizeof(watch) * 2 + 1]; 1566 int error; 1567 1568 sprintf(token, "%lX", (long)watch); 1569 |
1634 sx_slock(&xs.suspend_mutex); 1635 | |
1636 mtx_lock(&xs.registered_watches_lock); 1637 KASSERT(find_watch(token) == NULL, ("watch already registered")); 1638 LIST_INSERT_HEAD(&xs.registered_watches, watch, list); 1639 mtx_unlock(&xs.registered_watches_lock); 1640 1641 error = xs_watch(watch->node, token); 1642 1643 /* Ignore errors due to multiple registration. */ 1644 if (error == EEXIST) 1645 error = 0; 1646 1647 if (error != 0) { 1648 mtx_lock(&xs.registered_watches_lock); 1649 LIST_REMOVE(watch, list); 1650 mtx_unlock(&xs.registered_watches_lock); 1651 } 1652 | 1570 mtx_lock(&xs.registered_watches_lock); 1571 KASSERT(find_watch(token) == NULL, ("watch already registered")); 1572 LIST_INSERT_HEAD(&xs.registered_watches, watch, list); 1573 mtx_unlock(&xs.registered_watches_lock); 1574 1575 error = xs_watch(watch->node, token); 1576 1577 /* Ignore errors due to multiple registration. */ 1578 if (error == EEXIST) 1579 error = 0; 1580 1581 if (error != 0) { 1582 mtx_lock(&xs.registered_watches_lock); 1583 LIST_REMOVE(watch, list); 1584 mtx_unlock(&xs.registered_watches_lock); 1585 } 1586 |
1653 sx_sunlock(&xs.suspend_mutex); 1654 | |
1655 return (error); 1656} 1657 1658void 1659xs_unregister_watch(struct xs_watch *watch) 1660{ 1661 struct xs_stored_msg *msg, *tmp; 1662 char token[sizeof(watch) * 2 + 1]; 1663 int error; 1664 1665 sprintf(token, "%lX", (long)watch); 1666 | 1587 return (error); 1588} 1589 1590void 1591xs_unregister_watch(struct xs_watch *watch) 1592{ 1593 struct xs_stored_msg *msg, *tmp; 1594 char token[sizeof(watch) * 2 + 1]; 1595 int error; 1596 1597 sprintf(token, "%lX", (long)watch); 1598 |
1667 sx_slock(&xs.suspend_mutex); 1668 | |
1669 mtx_lock(&xs.registered_watches_lock); 1670 if (find_watch(token) == NULL) { 1671 mtx_unlock(&xs.registered_watches_lock); | 1599 mtx_lock(&xs.registered_watches_lock); 1600 if (find_watch(token) == NULL) { 1601 mtx_unlock(&xs.registered_watches_lock); |
1672 sx_sunlock(&xs.suspend_mutex); | |
1673 return; 1674 } 1675 LIST_REMOVE(watch, list); 1676 mtx_unlock(&xs.registered_watches_lock); 1677 1678 error = xs_unwatch(watch->node, token); 1679 if (error) 1680 log(LOG_WARNING, "XENSTORE Failed to release watch %s: %i\n", 1681 watch->node, error); 1682 | 1602 return; 1603 } 1604 LIST_REMOVE(watch, list); 1605 mtx_unlock(&xs.registered_watches_lock); 1606 1607 error = xs_unwatch(watch->node, token); 1608 if (error) 1609 log(LOG_WARNING, "XENSTORE Failed to release watch %s: %i\n", 1610 watch->node, error); 1611 |
1683 sx_sunlock(&xs.suspend_mutex); 1684 | |
1685 /* Cancel pending watch events. */ 1686 mtx_lock(&xs.watch_events_lock); 1687 TAILQ_FOREACH_SAFE(msg, &xs.watch_events, list, tmp) { 1688 if (msg->u.watch.handle != watch) 1689 continue; 1690 TAILQ_REMOVE(&xs.watch_events, msg, list); 1691 free(msg->u.watch.vec, M_XENSTORE); 1692 free(msg, M_XENSTORE); --- 26 unchanged lines hidden --- | 1612 /* Cancel pending watch events. */ 1613 mtx_lock(&xs.watch_events_lock); 1614 TAILQ_FOREACH_SAFE(msg, &xs.watch_events, list, tmp) { 1615 if (msg->u.watch.handle != watch) 1616 continue; 1617 TAILQ_REMOVE(&xs.watch_events, msg, list); 1618 free(msg->u.watch.vec, M_XENSTORE); 1619 free(msg, M_XENSTORE); --- 26 unchanged lines hidden --- |