21
22 /*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2013, Joyent, Inc. All rights reserved.
25 * Copyright 2016 RackTop Systems.
26 * Copyright (c) 2016 by Delphix. All rights reserved.
27 * Copyright 2017 OmniOS Community Edition (OmniOSce) Association.
28 */
29
30 /*
31 * This is the main implementation file for the low-level repository
32 * interface.
33 */
34
35 #include "lowlevel_impl.h"
36
37 #include "repcache_protocol.h"
38 #include "scf_type.h"
39
40 #include <assert.h>
41 #include <alloca.h>
42 #include <door.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <fnmatch.h>
46 #include <libuutil.h>
47 #include <poll.h>
48 #include <pthread.h>
49 #include <synch.h>
50 #include <stddef.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <sys/mman.h>
55 #include <sys/sysmacros.h>
56 #include <libzonecfg.h>
57 #include <unistd.h>
58 #include <dlfcn.h>
59
60 #define ENV_SCF_DEBUG "LIBSCF_DEBUG"
61 #define ENV_SCF_DOORPATH "LIBSCF_DOORPATH"
4065 (void) pthread_mutex_lock(&h->rh_lock);
4066 if (tran->tran_state != TRAN_STATE_SETUP ||
4067 tran->tran_invalid) {
4068 (void) pthread_mutex_unlock(&h->rh_lock);
4069 return (scf_set_error(SCF_ERROR_INVALID_ARGUMENT));
4070 }
4071
4072 total = 0;
4073 for (cur = uu_list_first(tran->tran_props); cur != NULL;
4074 cur = uu_list_next(tran->tran_props, cur)) {
4075 size = commit_process(cur, NULL);
4076 if (size == BAD_SIZE) {
4077 (void) pthread_mutex_unlock(&h->rh_lock);
4078 return (scf_set_error(SCF_ERROR_INTERNAL));
4079 }
4080 assert(TX_SIZE(size) == size);
4081 total += size;
4082 }
4083
4084 request_size = REP_PROTOCOL_TRANSACTION_COMMIT_SIZE(total);
4085 request = alloca(request_size);
4086 (void) memset(request, '\0', request_size);
4087 request->rpr_request = REP_PROTOCOL_PROPERTYGRP_TX_COMMIT;
4088 request->rpr_entityid = tran->tran_pg.rd_d.rd_entity;
4089 request->rpr_size = request_size;
4090 cmd = (uintptr_t)request->rpr_cmd;
4091
4092 datael_finish_reset(&tran->tran_pg.rd_d);
4093
4094 new_total = 0;
4095 for (cur = uu_list_first(tran->tran_props); cur != NULL;
4096 cur = uu_list_next(tran->tran_props, cur)) {
4097 size = commit_process(cur, (void *)cmd);
4098 if (size == BAD_SIZE) {
4099 (void) pthread_mutex_unlock(&h->rh_lock);
4100 return (scf_set_error(SCF_ERROR_INTERNAL));
4101 }
4102 cmd += size;
4103 new_total += size;
4104 }
4105 assert(new_total == total);
4106
4107 r = make_door_call(h, request, request_size,
4108 &response, sizeof (response));
4109
4110 if (r < 0) {
4111 (void) pthread_mutex_unlock(&h->rh_lock);
4112 DOOR_ERRORS_BLOCK(r);
4113 }
4114
4115 if (response.rpr_response != REP_PROTOCOL_SUCCESS &&
4116 response.rpr_response != REP_PROTOCOL_FAIL_NOT_LATEST) {
4117 (void) pthread_mutex_unlock(&h->rh_lock);
4118 return (scf_set_error(proto_error(response.rpr_response)));
4119 }
4120
4121 tran->tran_state = TRAN_STATE_COMMITTED;
4122 (void) pthread_mutex_unlock(&h->rh_lock);
4123 return (response.rpr_response == REP_PROTOCOL_SUCCESS);
4124 }
4125
4126 static void
4127 transaction_reset(scf_transaction_t *tran)
4128 {
4129 assert(MUTEX_HELD(&tran->tran_pg.rd_d.rd_handle->rh_lock));
4130
4131 tran->tran_state = TRAN_STATE_NEW;
4132 datael_reset_locked(&tran->tran_pg.rd_d);
4133 }
4134
4135 static void
4136 scf_transaction_reset_impl(scf_transaction_t *tran, int and_destroy,
4137 int and_reset_value)
4138 {
4139 scf_transaction_entry_t *cur;
4140 void *cookie;
4141
4142 (void) pthread_mutex_lock(&tran->tran_pg.rd_d.rd_handle->rh_lock);
4143 cookie = NULL;
|
21
22 /*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2013, Joyent, Inc. All rights reserved.
25 * Copyright 2016 RackTop Systems.
26 * Copyright (c) 2016 by Delphix. All rights reserved.
27 * Copyright 2017 OmniOS Community Edition (OmniOSce) Association.
28 */
29
30 /*
31 * This is the main implementation file for the low-level repository
32 * interface.
33 */
34
35 #include "lowlevel_impl.h"
36
37 #include "repcache_protocol.h"
38 #include "scf_type.h"
39
40 #include <assert.h>
41 #include <door.h>
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <fnmatch.h>
45 #include <libuutil.h>
46 #include <poll.h>
47 #include <pthread.h>
48 #include <synch.h>
49 #include <stddef.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <sys/mman.h>
54 #include <sys/sysmacros.h>
55 #include <libzonecfg.h>
56 #include <unistd.h>
57 #include <dlfcn.h>
58
59 #define ENV_SCF_DEBUG "LIBSCF_DEBUG"
60 #define ENV_SCF_DOORPATH "LIBSCF_DOORPATH"
4064 (void) pthread_mutex_lock(&h->rh_lock);
4065 if (tran->tran_state != TRAN_STATE_SETUP ||
4066 tran->tran_invalid) {
4067 (void) pthread_mutex_unlock(&h->rh_lock);
4068 return (scf_set_error(SCF_ERROR_INVALID_ARGUMENT));
4069 }
4070
4071 total = 0;
4072 for (cur = uu_list_first(tran->tran_props); cur != NULL;
4073 cur = uu_list_next(tran->tran_props, cur)) {
4074 size = commit_process(cur, NULL);
4075 if (size == BAD_SIZE) {
4076 (void) pthread_mutex_unlock(&h->rh_lock);
4077 return (scf_set_error(SCF_ERROR_INTERNAL));
4078 }
4079 assert(TX_SIZE(size) == size);
4080 total += size;
4081 }
4082
4083 request_size = REP_PROTOCOL_TRANSACTION_COMMIT_SIZE(total);
4084 request = calloc(1, request_size);
4085 if (request == NULL) {
4086 (void) pthread_mutex_unlock(&h->rh_lock);
4087 return (scf_set_error(SCF_ERROR_NO_MEMORY));
4088 }
4089
4090 request->rpr_request = REP_PROTOCOL_PROPERTYGRP_TX_COMMIT;
4091 request->rpr_entityid = tran->tran_pg.rd_d.rd_entity;
4092 request->rpr_size = request_size;
4093 cmd = (uintptr_t)request->rpr_cmd;
4094
4095 datael_finish_reset(&tran->tran_pg.rd_d);
4096
4097 new_total = 0;
4098 for (cur = uu_list_first(tran->tran_props); cur != NULL;
4099 cur = uu_list_next(tran->tran_props, cur)) {
4100 size = commit_process(cur, (void *)cmd);
4101 if (size == BAD_SIZE) {
4102 (void) pthread_mutex_unlock(&h->rh_lock);
4103 r = (scf_set_error(SCF_ERROR_INTERNAL));
4104 goto out;
4105 }
4106 cmd += size;
4107 new_total += size;
4108 }
4109 assert(new_total == total);
4110
4111 r = make_door_call(h, request, request_size,
4112 &response, sizeof (response));
4113
4114 if (r < 0) {
4115 (void) pthread_mutex_unlock(&h->rh_lock);
4116 DOOR_ERRORS_BLOCK(r);
4117 }
4118
4119 if (response.rpr_response != REP_PROTOCOL_SUCCESS &&
4120 response.rpr_response != REP_PROTOCOL_FAIL_NOT_LATEST) {
4121 (void) pthread_mutex_unlock(&h->rh_lock);
4122 r = (scf_set_error(proto_error(response.rpr_response)));
4123 goto out;
4124 }
4125
4126 tran->tran_state = TRAN_STATE_COMMITTED;
4127 (void) pthread_mutex_unlock(&h->rh_lock);
4128 r = (response.rpr_response == REP_PROTOCOL_SUCCESS);
4129
4130 out:
4131 free(request);
4132 return (r);
4133 }
4134
4135 static void
4136 transaction_reset(scf_transaction_t *tran)
4137 {
4138 assert(MUTEX_HELD(&tran->tran_pg.rd_d.rd_handle->rh_lock));
4139
4140 tran->tran_state = TRAN_STATE_NEW;
4141 datael_reset_locked(&tran->tran_pg.rd_d);
4142 }
4143
4144 static void
4145 scf_transaction_reset_impl(scf_transaction_t *tran, int and_destroy,
4146 int and_reset_value)
4147 {
4148 scf_transaction_entry_t *cur;
4149 void *cookie;
4150
4151 (void) pthread_mutex_lock(&tran->tran_pg.rd_d.rd_handle->rh_lock);
4152 cookie = NULL;
|