2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Krzysztof Dynowski <k.dynowski@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
22 * @author Krzysztof Dynowski (k.dynowski@samsung.com)
23 * @brief Vasum old API compatibility functions
26 #include "wrapper-compatibility.h"
38 #include <inttypes.h> //PRIx64
39 #include <sys/mount.h>
40 #include <sys/xattr.h>
42 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <asm/unistd.h>
48 #include "logger/logger.hpp"
49 #include "logger/logger-scope.hpp"
51 #define UNUSED(x) ((void)(x))
55 // find_container_by_pid
56 API char *find_container_by_pid(pid_t /*pid*/) {
61 API pid_t get_domain_pid(const char * /*name*/, const char * /*target*/) {
67 API int sock_close_socket(int fd) {
69 struct sockaddr_un addr;
70 socklen_t addrlen = sizeof(addr);
72 if (!getsockname(fd, (struct sockaddr *)&addr, &addrlen) && addr.sun_path[0]) {
73 unlink(addr.sun_path);
81 API int sock_connect(const char *path) {
85 struct sockaddr_un addr;
87 fd = socket(PF_UNIX, SOCK_STREAM, 0);
92 memset(&addr, 0, sizeof(addr));
94 addr.sun_family = AF_UNIX;
96 /* Is it abstract address */
97 if (path[0] == '\0') {
100 LOGD("socket path=" << &path[idx]);
101 len = strlen(&path[idx]) + idx;
102 if (len >= sizeof(addr.sun_path)) {
104 errno = ENAMETOOLONG;
108 strncpy(&addr.sun_path[idx], &path[idx], strlen(&path[idx]));
110 (fd, (struct sockaddr *)&addr,
111 offsetof(struct sockaddr_un, sun_path) + len)) {
119 // sock_create_socket
120 API int sock_create_socket(const char *path, int type, int flags) {
124 struct sockaddr_un addr;
132 fd = socket(PF_UNIX, type, 0);
137 memset(&addr, 0, sizeof(addr));
139 addr.sun_family = AF_UNIX;
141 /* Is it abstract address */
142 if (path[0] == '\0') {
145 LOGD("socket path=" << &path[idx]);
146 len = strlen(&path[idx]) + idx;
147 if (len >= sizeof(addr.sun_path)) {
149 errno = ENAMETOOLONG;
153 strncpy(&addr.sun_path[idx], &path[idx], strlen(&path[idx]));
155 if (bind (fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + len)) {
160 if (type == SOCK_STREAM && listen(fd, 100)) {
168 // "Fowler–Noll–Vo hash function" implementation (taken from old API source)
169 #define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL)
170 static uint64_t hash_fnv_64a(void *buf, size_t len, uint64_t hval)
174 for (bp = (unsigned char *)buf; bp < (unsigned char *)buf + len; bp++) {
175 hval ^= (uint64_t) * bp;
176 hval += (hval << 1) + (hval << 4) + (hval << 5) +
177 (hval << 7) + (hval << 8) + (hval << 40);
183 // sock_monitor_address
184 API int sock_monitor_address(char *buffer, int len, const char *lxcpath) {
191 memset(buffer, 0, len);
192 sockname = &buffer[1];
194 ret = snprintf(path, sizeof(path), "lxc/%s/monitor-sock", lxcpath);
196 errno = ENAMETOOLONG;
200 hash = hash_fnv_64a(path, ret, FNV1A_64_INIT);
201 ret = snprintf(sockname, len, "lxc/%016" PRIx64 "/%s", hash, lxcpath);
203 errno = ENAMETOOLONG;
209 // sock_recv_fd (intern)
210 API int sock_recv_fd(int fd, int *recvfd, void *data, size_t size) {
217 char control[CMSG_SPACE(sizeof(int))];
219 struct cmsghdr *cmsg;
222 memset(&msg, 0, sizeof(msg));
226 msg.msg_control = control_un.control;
227 msg.msg_controllen = sizeof(control_un.control);
229 iov.iov_base = data ? data : &dummy;
230 iov.iov_len = data ? size : sizeof(dummy);
234 ret = recvmsg(fd, &msg, 0);
238 cmsg = CMSG_FIRSTHDR(&msg);
239 if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
240 cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
241 *recvfd = *((int *)CMSG_DATA(cmsg));
249 API int sock_send_fd(int fd, int sendfd, void *data, size_t size) {
255 char control[CMSG_SPACE(sizeof(int))];
257 struct cmsghdr *cmsg;
260 memset(&msg, 0, sizeof(msg));
261 msg.msg_control = control_un.control;
262 msg.msg_controllen = sizeof(control_un.control);
264 cmsg = CMSG_FIRSTHDR(&msg);
265 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
266 cmsg->cmsg_level = SOL_SOCKET;
267 cmsg->cmsg_type = SCM_RIGHTS;
268 *((int *)CMSG_DATA(cmsg)) = sendfd;
273 iov.iov_base = data ? data : &dummy;
274 iov.iov_len = data ? size : sizeof(dummy);
278 return sendmsg(fd, &msg, MSG_NOSIGNAL);
281 API void vasum_log(int type, const char *tag, const char *fmt, ...) {
284 LOGS("type=" << type << " tag=" << tag);
285 va_start(arg_ptr, fmt);
286 vsnprintf(buf, sizeof(buf), fmt, arg_ptr);
288 buf[sizeof(buf)-1]=0;
292 #define MAX_ERROR_MSG 0x1000
293 #define BUF_SIZE 4096
295 #define SMACK_LABEL_LEN 8
296 #define ERROR(...) do{}while(0)
297 #define WARN(...) do{}while(0)
298 #define DEBUG(...) do{}while(0)
299 #define INFO(...) do{}while(0)
302 const char *const fso_type_strtab[] = {
310 API const char *fso_type_to_string(vsm_fso_type_t fso)
313 if (fso < 0 || fso > VSM_FSO_MAX_TYPE) {
317 return fso_type_strtab[fso];
320 API int wait_for_pid_status(pid_t pid)
326 ret = waitpid(pid, &status, 0);
328 if (errno == EINTR) {
331 ERROR("waitpid pid : %d error : %s", pid, strerror(errno));
340 API vsm_fso_type_t fso_string_to_type(char *str)
345 for (i = 0; i <= VSM_FSO_MAX_TYPE; i++) {
346 len = strlen(fso_type_strtab[i]);
347 if (strncmp(str, fso_type_strtab[i], len) == 0)
348 return static_cast<vsm_fso_type_t>(i);
351 return static_cast<vsm_fso_type_t>(-1);
354 API int mkdir_p(const char *dir, mode_t mode)
357 const char *tmp = dir;
358 const char *orig = dir;
362 dir = tmp + strspn(tmp, "/");
363 tmp = dir + strcspn(dir, "/");
364 makeme = strndup(orig, dir - orig);
366 if (mkdir(makeme, mode) && errno != EEXIST) {
372 } while (tmp != dir);
377 API int lock_fd(int fd, int wait)
385 f.l_whence = SEEK_SET;
390 ret = fcntl(fd, F_SETLKW, &f);
392 ret = fcntl(fd, F_SETLK, &f);
401 API int unlock_fd(int fd)
406 f.l_whence = SEEK_SET;
409 return fcntl(fd, F_SETLKW, &f);
412 API int copy_smacklabel(const char * /*source*/, const char * /*dest*/)
418 API int remove_file(char *path)
421 struct stat path_stat;
426 if (lstat(path, &path_stat) < 0) {
427 if (errno != ENOENT) {
428 ERROR("Unable to stat : %s");
433 if (S_ISDIR(path_stat.st_mode)) {
434 if ((dp = opendir(path)) == NULL) {
435 ERROR("Unable to opendir %s", path);
439 while ((d = readdir(dp)) != NULL) {
440 char new_path[PATH_MAX];
441 if (strcmp(d->d_name, ".") == 0 ||
442 strcmp(d->d_name, "..") == 0)
445 snprintf(new_path, PATH_MAX, "%s/%s", path, d->d_name);
446 if (remove_file(new_path) < 0)
450 if (closedir(dp) < 0) {
451 ERROR("Unable to close dp : %s", path);
455 if (rmdir(path) < 0) {
456 ERROR("Failed to remove dir : %s, cause: %s", path,
462 if (unlink(path) < 0) {
463 ERROR("Unable to remove %s", path);
471 API int copy_file(const char *source, const char *dest, int /*flags*/)
476 size_t nread, nwritten, size = BUF_SIZE;
477 char buffer[BUF_SIZE];
479 if ((sfp = fopen(source, "r")) == NULL) {
480 ERROR("Unable to open source : %s", source);
484 if ((dfp = fopen(dest, "w+")) == NULL) {
485 ERROR("Unable to open destination : %s", dest);
491 nread = fread(buffer, 1, size, sfp);
493 if (nread != size && ferror(sfp)) {
494 ERROR("Read failed");
496 } else if (nread == 0) {
500 nwritten = fwrite(buffer, 1, nread, dfp);
502 if (nwritten != nread) {
506 ERROR("Unable to write all data");
514 ret = copy_smacklabel(source, dest);
516 ERROR("Unable to setting smack lable");
522 API int regex_compile(regex_t * r, const char *regex_text)
525 int status = regcomp(r, regex_text, REG_EXTENDED | REG_NEWLINE);
528 char error_message[MAX_ERROR_MSG];
530 regerror(status, r, error_message, MAX_ERROR_MSG);
531 DEBUG("Regex error compiling '%s': %s\n",
532 regex_text, error_message);
539 API int regex_match(regex_t * r, const char *to_match)
542 const char *p = to_match;
543 const int n_matches = 10;
544 regmatch_t m[n_matches];
548 int nomatch = regexec(r, p, n_matches, m, 0);
551 DEBUG("No more matches.\n");
555 for (i = 0; i < n_matches; i++) {
561 if (m[i].rm_so == -1) {
565 start = m[i].rm_so + (p - to_match);
566 finish = m[i].rm_eo + (p - to_match);
573 INFO("'%.*s' (bytes %d:%d)\n", (finish - start),
574 to_match + start, start, finish);
583 API int get_peer_pid(int fd)
587 socklen_t cr_len = sizeof(cred);
588 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &cr_len) < 0) {
594 API pid_t gettid(void)
597 return syscall(__NR_gettid);
600 API int set_smacklabel_fd(int fd, const char *xattr_name, const char *label)
609 len = strnlen(label, SMACK_LABEL_LEN + 1);
610 if (len > SMACK_LABEL_LEN)
613 ret = fsetxattr(fd, xattr_name, label, len + 1, 0);
615 ERROR("Set Smack lable error : %s", strerror(errno));
620 API int set_smacklabel(const char *path, const char *xattr_name, const char *label)
629 len = strnlen(label, SMACK_LABEL_LEN + 1);
630 if (len > SMACK_LABEL_LEN)
633 ret = lsetxattr(path, xattr_name, label, len + 1, 0);
635 ERROR("Set Smack lable error : %s", strerror(errno));
639 API char *get_self_smacklabel(void)
644 const char *attr_path = "/proc/self/attr/current";
645 char buffer[SMACK_LABEL_LEN + 1];
647 bzero(buffer, SMACK_LABEL_LEN + 1);
649 fd = open(attr_path, O_RDONLY);
654 ret = read(fd, buffer, SMACK_LABEL_LEN + 1);
660 if (ret > SMACK_LABEL_LEN) {
663 buffer[SMACK_LABEL_LEN] = 0;
665 return strdup(buffer);
668 API int get_self_cpuset(char *name, int buf_sz)
673 char cpuset_path[] = "/proc/self/cpuset";
674 char current_name[NAME_MAX];
676 fd = open(cpuset_path, O_RDONLY);
681 ret = read(fd, current_name, NAME_MAX - 1);
687 current_name[ret - 1] = '\0';
690 lxc_len = sizeof("/lxc");
697 p = current_name + lxc_len;
706 snprintf(name, buf_sz, "%s", current_name + lxc_len);
709 return ret - lxc_len;
713 API char * get_pid_cpuset(int pid)
718 char cpuset_path[PATH_MAX];
719 char current_name[NAME_MAX];
721 snprintf(cpuset_path, PATH_MAX, "/proc/%d/cpuset", pid);
723 ret = access(cpuset_path, F_OK | R_OK);
727 fd = open(cpuset_path, O_RDONLY);
732 ret = read(fd, current_name, NAME_MAX - 1);
738 current_name[ret - 1] = 0;
741 INFO("cpuset path : %s, value : %s", cpuset_path, current_name);
743 return strdup(current_name);
746 API char * read_namespace_link(const char *ns, int pid)
749 char ns_path[PATH_MAX];
753 snprintf(ns_path, PATH_MAX, "/proc/%d/ns/%s", pid, ns);
755 ret = access(ns_path, F_OK);
759 ret = readlink(ns_path, buf, NAME_MAX);
761 ERROR("Failed to readlink ns file - [%s]", ns_path);
767 INFO("Read ns link data -pid : %d data : %s", pid, buf);
773 #define DEV_ITERATE_CONTINUE 0
774 API int dev_enumerate_nodes(const char *cname, dev_enumerator enumerator,
780 char path[PATH_MAX], entry[64];
782 ret = snprintf(path, sizeof(path),
783 "/sys/fs/cgroup/devices/lxc/%s/devices.list", cname);
786 ERROR("Failed to make pathname");
790 fp = fopen(path, "r");
792 ERROR("File open failed: %s(%s)", path, strerror(errno));
796 while (fgets(entry, sizeof(entry), fp) != NULL) {
798 char *next, *ptr = &entry[2];
800 major = strtol(ptr, &next, 10);
801 minor = strtol(++next, (char **)NULL, 10);
803 ret = enumerator(entry[0], major, minor, data);
804 if (ret != DEV_ITERATE_CONTINUE)
813 API int dev_terminal_enumerator(int type, int major, int minor, void *data)
816 int *dev = (int*)data;
822 INFO("Matched device: %c, %d, %d\n", type, major, minor);
828 API pid_t get_init_pid(const char *name)
831 char filename[PATH_MAX];
835 snprintf(filename, sizeof(filename),
836 "/sys/fs/cgroup/devices/lxc/%s/cgroup.procs", name);
838 fp = fopen(filename, "r");
841 if (fscanf(fp, "%d", &ret) < 0) {
842 ERROR("Failed to read %s\n", filename);
847 INFO("Unable to access %s\n", filename);
855 API pid_t get_zone_pid(const char *name, const char *target)
867 snprintf(path, PATH_MAX,
868 "/sys/fs/cgroup/cpuset/lxc/%s/cgroup.procs", name);
870 res = access(path, F_OK | R_OK);
872 ERROR("Failed to acess zone cgroup file: %s", path);
876 if (target == NULL) {
877 ERROR("Failed to lookup cmdline in zone proc");
880 len = strlen(target);
883 fp = fopen(path, "r");
885 ERROR("Failed to open zone cgroup");
889 while (getline(&line, &line_len, fp) != -1) {
893 char cmdpath[PATH_MAX];
895 res = sscanf(line, "%d", &pid);
897 ERROR("Failed to read %s\n", path);
905 snprintf(cmdpath, PATH_MAX, "/proc/%d/cmdline", pid);
907 if (access(cmdpath, F_OK | R_OK) != 0)
910 cmdfp = fopen(cmdpath, "r");
912 ERROR("Unable to access %s\n", cmdpath);
916 if (fscanf(cmdfp, "%s", cmd) < 0) {
917 ERROR("Failed to read cmdline - pid : %d\n", pid);
923 if (strncmp(cmd, target, len) == 0) {
933 API int open_ns(pid_t pid, const char *name)
939 ret = snprintf(path, PATH_MAX, "/proc/%d/ns/%s", pid, name);
940 if (ret < 0 || ret >= PATH_MAX) {
941 ERROR("Failed to namespace - pid %d, ns: %s ", pid, name);
945 fd = open(path, O_RDONLY);
947 ERROR("failed to open %s\n", path);
955 #include <linux/kd.h>
956 #include <linux/vt.h>
957 static int is_console(int fd)
962 return (isatty(fd) &&
963 (ioctl(fd, KDGKBTYPE, &arg) == 0) &&
964 ((arg == KB_101) || (arg == KB_84)));
967 static int open_console(const char *path)
971 fd = open(path, O_RDWR);
973 fd = open(path, O_WRONLY);
976 fd = open(path, O_RDONLY);
985 API int get_console_fd(const char *path)
991 fd = open_console(path);
999 fd = open_console("/dev/tty0");
1004 fd = open_console("/dev/console");
1009 for (fd = 0; fd < 3; fd++) {
1010 if (is_console(fd)) {
1018 API int vt_switch_terminal(int id)
1023 fd = get_console_fd(NULL);
1028 if (ioctl(fd, VT_ACTIVATE, id) < 0) {
1032 if (ioctl(fd, VT_WAITACTIVE, id) < 0) {
1042 API int vt_find_unused_terminal(void)
1047 fd = get_console_fd(NULL);
1049 perror("Terminal open failed");
1053 if (ioctl(fd, VT_OPENQRY, &nr) < 0) {
1054 perror("VT_OPENQRY failed");
1064 API int vt_query_active_terminal(void)
1068 struct vt_stat vtstat;
1070 fd = get_console_fd(NULL);
1075 if (ioctl(fd, VT_GETSTATE, &vtstat) < 0) {
1079 ret = vtstat.v_active;
1086 struct unit_keyword_callback {
1088 int (*func) (int nargs, char **args);
1091 struct unit_parser {
1092 struct unit_keyword_callback *kw;
1095 API int parse_stream(const char *name, struct unit_parser *parser);
1097 #define PARSER_MAXARGS 32
1100 #define T_STATEMENT 2
1101 #define T_ARGUMENT 3
1103 #define T_NEWBLOCK 8
1105 struct parser_context {
1106 struct unit_keyword_callback *kw;
1109 struct parser_state {
1117 static void parser_init_state(struct parser_state *state, char *line)
1121 state->nexttoken = 0;
1123 state->context = NULL;
1126 static struct unit_keyword_callback *keyword_lookup(struct parser_context *ctx,
1131 for (i = 0; ctx->kw[i].name != NULL; i++) {
1132 if (!strcmp(ctx->kw[i].name, kw)) {
1140 static int tokenize(struct parser_state *state)
1142 char *x = state->ptr;
1145 if (state->nexttoken) {
1146 int t = state->nexttoken;
1147 state->nexttoken = 0;
1152 state->stmt = s = x;
1158 state->nexttoken = T_EOF;
1178 /* \ <cr> <lf> -> line continuation */
1184 /* \ <lf> -> line continuation */
1187 /* eat any extra whitespace */
1188 while ((*x == ' ') || (*x == '\t'))
1192 /* unknown escape -- just copy */
1219 state->nexttoken = T_NEWLINE;
1227 /* unterminated quoted thing */
1246 while (*x && (*x != '\n'))
1267 static int parse_statement(struct parser_context *ctx, int argc, char **argv,
1268 int (*func) (int argc, char **argv))
1270 struct parser_state state;
1271 char *args[PARSER_MAXARGS];
1272 int i, nargs, done, rc;
1276 for (i = 0; i < argc; i++) {
1278 parser_init_state(&state, argv[i]);
1281 int token = tokenize(&state);
1284 if (nargs && func) {
1285 rc = func(nargs, args);
1287 WARN("Key word callback error");
1294 if (nargs < PARSER_MAXARGS) {
1295 args[nargs++] = state.stmt;
1305 API int parse_stream_core(struct parser_context *ctx, char *s)
1308 struct unit_keyword_callback *kw;
1309 struct parser_state state;
1310 char *args[PARSER_MAXARGS];
1314 parser_init_state(&state, s);
1317 int token = tokenize(&state);
1323 if ((kw = keyword_lookup(ctx, args[0])) != NULL) {
1324 rc = parse_statement(ctx, nargs - 1,
1336 if (nargs < PARSER_MAXARGS) {
1337 args[nargs++] = state.stmt;
1346 /* reads a file, making sure it is terminated with \n \0 */
1347 static char *open_stream(const char *name, unsigned int *_sz)
1352 fd = open(name, O_RDONLY);
1356 sz = lseek(fd, 0, SEEK_END);
1360 if (lseek(fd, 0, SEEK_SET) != 0)
1363 data = (char *)malloc(sz + 2);
1367 if (read(fd, data, sz) != sz)
1387 API int parse_stream(const char *name, struct unit_parser *parser)
1391 struct parser_context *ctx;
1393 ctx = (struct parser_context *)malloc(sizeof(struct parser_context));
1398 ctx->kw = parser->kw;
1400 /* File open & return file context */
1401 stream = open_stream(name, NULL);
1402 if (stream == NULL) {
1407 parse_stream_core(ctx, stream);
1414 API struct vsm_netdev *alloc_netdev(struct vsm_zone * /*zone*/, vsm_netdev_type_t /*type*/, const char * /*netdev_name*/) {
1418 API void enter_to_ns(pid_t /*pid*/, char * /*name*/) {
1423 static int dummy_create_zone(vsm_context_h /*ctx*/, const char * /*zone_name*/,
1424 const char * /*template*/, int /*flags*/)
1426 return -VSM_ERROR_NOT_SUPPORTED;
1429 static int dummy_destroy_zone(vsm_context_h /*ctx*/, const char * /*zone_name*/, int /*force*/)
1431 return -VSM_ERROR_NOT_SUPPORTED;
1434 static int dummy_start_zone(vsm_context_h /*ctx*/, const char * /*zone_name*/)
1436 return -VSM_ERROR_NOT_SUPPORTED;
1439 static int dummy_shutdown_zone(vsm_context_h /*ctx*/, const char * /*zone_name*/, int /*force*/)
1441 return -VSM_ERROR_NOT_SUPPORTED;
1444 static int dummy_lock_zone(vsm_context_h /*ctx*/, const char * /*zone_name*/, int /*shutdown*/)
1446 return -VSM_ERROR_NOT_SUPPORTED;
1449 static int dummy_unlock_zone(vsm_context_h /*ctx*/, const char * /*zone_name*/)
1451 return -VSM_ERROR_NOT_SUPPORTED;
1454 static int dummy_set_foreground(vsm_zone_h zone)
1457 return -VSM_ERROR_INVALID;
1459 if (zone->parent == zone) {
1460 return VSM_ERROR_NONE;
1462 return -VSM_ERROR_NO_OBJECT;
1465 static vsm_zone_h dummy_get_foreground(vsm_context_h ctx)
1472 return ctx->root_zone;
1475 static int dummy_iterate_zone(vsm_context_h ctx, vsm_zone_iter_cb callback, void *user_data)
1478 callback(ctx->root_zone, user_data);
1480 return VSM_ERROR_NONE;
1483 static vsm_zone_h dummy_lookup_zone_by_name(vsm_context_h ctx, const char *name)
1485 if (strcmp(name, "") != 0) {
1490 return ctx->root_zone;
1493 static vsm_zone_h dummy_lookup_zone_by_pid(vsm_context_h ctx, pid_t /*pid*/)
1498 return ctx->root_zone;
1501 static int dummy_attach_zone(vsm_context_h ctx, const char *zone_name,
1502 vsm_attach_command_s * command,
1503 vsm_attach_options_s * opts,
1504 pid_t * attached_process)
1507 struct vsm_attach_options_s options;
1509 if (command == NULL || command->exec == NULL || zone_name == NULL) {
1510 ERROR("Invalid arguments");
1511 ctx->error = VSM_ERROR_INVALID;
1512 return -VSM_ERROR_INVALID;
1515 if (strcmp("", zone_name) != 0) {
1516 ctx->error = VSM_ERROR_INVALID;
1517 return -VSM_ERROR_INVALID;
1522 opts->uid = getuid();
1523 opts->gid = getgid();
1525 opts->extra_env = NULL;
1530 if (opts->extra_env != NULL) {
1531 while (*opts->extra_env)
1532 putenv(*opts->extra_env++);
1535 if (getuid() == 0 && opts->uid != 0) {
1536 if (setuid(opts->uid) != 0) {
1537 ERROR("Failed to set uid : %d", opts->uid);
1540 WARN("setuid() is not permitted");
1543 if (getgid() == 0 && opts->gid != 0) {
1544 if (setgid(opts->gid) != 0) {
1545 ERROR("Failed to set gid : %d", opts->gid);
1548 WARN("setgid() is not permitted");
1551 if (execvp(command->exec, command->argv) < 0) {
1552 ERROR("exevp failed : %s, %s", command->exec,
1557 *attached_process = pid;
1560 return VSM_ERROR_NONE;
1563 static int dummy_attach_zone_wait(vsm_context_h ctx, const char *zone_name,
1564 vsm_attach_command_s * command,
1565 vsm_attach_options_s * opts)
1570 ret = dummy_attach_zone(ctx, zone_name, command, opts, &pid);
1571 if (ret != VSM_ERROR_NONE) {
1572 ERROR("API Failed.");
1576 status = wait_for_pid_status(pid);
1578 ctx->error = VSM_ERROR_GENERIC;
1579 return -VSM_ERROR_GENERIC;
1582 INFO("attached process extied : pid - %d, exit code : %d", pid,
1583 WEXITSTATUS(status));
1588 static vsm_zone_h dummy_join_zone(vsm_zone_h zone)
1594 if (zone != zone->parent) {
1602 static int dummy_is_equivalent_zone(vsm_context_h /*ctx*/, pid_t /*pid*/)
1607 static int dummy_get_host_pid(vsm_zone_h zone, pid_t pid)
1609 if (zone == zone->parent)
1612 return -VSM_ERROR_NO_OBJECT;
1615 static int dummy_grant_device(vsm_zone_h /*zone*/, const char * /*path*/, uint32_t /*flags*/)
1617 return -VSM_ERROR_NOT_SUPPORTED;
1620 static int dummy_revoke_device(vsm_zone_h /*zone*/, const char * /*path*/)
1622 return -VSM_ERROR_NOT_SUPPORTED;
1625 static int dummy_declare_file(vsm_context_h /*ctx*/, vsm_fso_type_t /*ftype*/,
1626 const char * /*path*/, int /*flags*/, vsm_mode_t /*mode*/)
1628 return VSM_ERROR_NONE;
1631 static int dummy_declare_link(vsm_context_h /*ctx*/, const char *source,
1632 const char * /*target*/)
1636 ret = access(source, F_OK);
1638 return -VSM_ERROR_NO_OBJECT;
1640 return VSM_ERROR_NONE;
1643 struct vasum_ops dummy_ops;
1644 static int dummy_ops_init() {
1645 dummy_ops.create_zone = dummy_create_zone;
1646 dummy_ops.destroy_zone = dummy_destroy_zone;
1647 dummy_ops.start_zone = dummy_start_zone;
1648 dummy_ops.shutdown_zone = dummy_shutdown_zone;
1649 dummy_ops.lock_zone = dummy_lock_zone;
1650 dummy_ops.unlock_zone = dummy_unlock_zone;
1651 dummy_ops.set_foreground = dummy_set_foreground;
1652 dummy_ops.get_foreground = dummy_get_foreground;
1653 dummy_ops.iterate_zone = dummy_iterate_zone;
1654 dummy_ops.lookup_zone_by_name = dummy_lookup_zone_by_name;
1655 dummy_ops.lookup_zone_by_pid = dummy_lookup_zone_by_pid;
1656 dummy_ops.attach_zone = dummy_attach_zone;
1657 dummy_ops.attach_zone_wait = dummy_attach_zone_wait;
1658 dummy_ops.join_zone = dummy_join_zone;
1659 dummy_ops.is_equivalent_zone = dummy_is_equivalent_zone;
1660 dummy_ops.get_host_pid = dummy_get_host_pid;
1661 dummy_ops.grant_device = dummy_grant_device;
1662 dummy_ops.revoke_device = dummy_revoke_device;
1663 dummy_ops.declare_file = dummy_declare_file;
1664 dummy_ops.declare_link = dummy_declare_link;
1667 int dummy_ops_init_i = dummy_ops_init();