From 55cbf2266a744ee0c82625d6c4956bdfecedafc1 Mon Sep 17 00:00:00 2001 From: cj Date: Sun, 29 Apr 2012 14:14:14 -0700 Subject: [PATCH] Add user level lxc code --- fork/_lxc_fork | Bin 0 -> 13006 bytes fork/_lxc_fork.c | 96 ++++++++++++++++ fork/log.h | 294 +++++++++++++++++++++++++++++++++++++++++++++++ fork/lxc-app2.c | 19 +++ fork/lxc-app3.c | 37 ++++++ fork/lxc-app4 | Bin 0 -> 13256 bytes fork/lxc-app4.c | 170 +++++++++++++++++++++++++++ fork/lxc_fork | Bin 0 -> 12895 bytes fork/lxc_fork.c | 88 ++++++++++++++ fork/lxc_fork.h | 14 +++ fork/make.sh | 3 + fork/mmap.file | Bin 0 -> 40963 bytes fork/pid.txt | 1 + fs/file.c | 7 +- net/socket.c | 18 +++ 15 files changed, 745 insertions(+), 2 deletions(-) create mode 100755 fork/_lxc_fork create mode 100644 fork/_lxc_fork.c create mode 100644 fork/log.h create mode 100644 fork/lxc-app2.c create mode 100644 fork/lxc-app3.c create mode 100755 fork/lxc-app4 create mode 100644 fork/lxc-app4.c create mode 100755 fork/lxc_fork create mode 100644 fork/lxc_fork.c create mode 100644 fork/lxc_fork.h create mode 100755 fork/make.sh create mode 100755 fork/mmap.file create mode 100644 fork/pid.txt diff --git a/fork/_lxc_fork b/fork/_lxc_fork new file mode 100755 index 0000000000000000000000000000000000000000..a1a0c77b259995ce9471d301ae311e645f05f6b7 GIT binary patch literal 13006 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 +#include +#include + +#include +#include +#include + + +#include +#include +#include "lxc_fork.h" + +/* + * _lxc_fork: fork the process set of lxc container "orig" + * orig: forked container name + */ +int main(int argc, char *argv[]) +{ + char *orig; + char buf[64] = { '\0' }; + pid_t init_pid; + int fd, ret, len; + int test = 0; + char c; + int i = 0; + FILE *f; + struct timeval time; + unsigned long start, end; //milliseconds + + lf_debug("This is for debug lxc_start new container: %s.\n", argv[1]); + + //get initial pid of original contianer by get_init_pid + orig = argv[1]; + //init_pid = get_init_pid(orig); + /* + * Since we can't use get_init_pid to read the initial process pid of + * original contianer, read from file first :( + */ + printf("Please input the initial pid of original container %s.\n", orig); + if (test) + f = fopen("./pid.txt", "r+"); + else + f = fopen("/root/pid.txt", "r+"); + if (f == NULL) { + lf_debug("Can't find pid file.\n"); + return -1; + } + /* + while ((c = fgetc(f)) != ' ') { + buf[i++] = c; + } + */ + if (fgets(buf, 64, f) == NULL) { + lf_debug("Can't get initial pid, exit.\n"); + return 1; + } + fclose(f); + + init_pid = atol(buf); + if (argc > 2) { + init_pid = atol(argv[2]); + } + + lf_debug("Get inital pid of original container %s : %d\n", orig, init_pid); + + if (init_pid < 0) { + lf_debug("failed to get the initial pid of original container.\n"); + return -1; + } + //len = sprintf(buf, "echo \"fork %d\" > /proc/cgroups", init_pid); + len = sprintf(buf, "fork %d", init_pid); + lf_debug("echo cmd: %s\n", buf); + //system(buf); + //write "fork orig-container" to /proc/cgroups for call __lxc_fork in kernel + ///* + fd = open("/proc/cgroups", O_WRONLY); + if (fd < 0) { + lf_debug("failed to open cgroup for lxc-fork.\n"); + return -1; + } + //before we call lxc fork in kernel + gettimeofday(&time, NULL); + start = time.tv_sec * 1000 + time.tv_usec / 1000; + + ret = write(fd, buf, len + 1); + + //after lxc fork done + gettimeofday(&time, NULL); + end = time.tv_sec * 1000 + time.tv_usec / 1000; + printf("The time of lxc fork without fs copy: %ld ms\n", end - start); + + close(fd); + //*/ + return 0; +} diff --git a/fork/log.h b/fork/log.h new file mode 100644 index 00000000..b11093d1 --- /dev/null +++ b/fork/log.h @@ -0,0 +1,294 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * Cedric Le Goater + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _log_h +#define _log_h + +#include +#include +#include +#include + +#ifndef O_CLOEXEC +#define O_CLOEXEC 02000000 +#endif + +#ifndef F_DUPFD_CLOEXEC +#define F_DUPFD_CLOEXEC 1030 +#endif + +#define LXC_LOG_PREFIX_SIZE 32 +#define LXC_LOG_BUFFER_SIZE 512 + +/* predefined priorities. */ +enum { + LXC_LOG_PRIORITY_TRACE, + LXC_LOG_PRIORITY_DEBUG, + LXC_LOG_PRIORITY_INFO, + LXC_LOG_PRIORITY_NOTICE, + LXC_LOG_PRIORITY_WARN, + LXC_LOG_PRIORITY_ERROR, + LXC_LOG_PRIORITY_CRIT, + LXC_LOG_PRIORITY_ALERT, + LXC_LOG_PRIORITY_FATAL, + LXC_LOG_PRIORITY_NOTSET, +}; + +/* location information of the logging event */ +struct lxc_log_locinfo { + const char *file; + const char *func; + int line; +}; + +#define LXC_LOG_LOCINFO_INIT \ + { .file = __FILE__, .func = __func__, .line = __LINE__ } + +/* brief logging event object */ +struct lxc_log_event { + const char* category; + int priority; + struct timeval timestamp; + struct lxc_log_locinfo *locinfo; + const char *fmt; + va_list *vap; +}; + +/* log appender object */ +struct lxc_log_appender { + const char* name; + int (*append)(const struct lxc_log_appender *, struct lxc_log_event *); + + /* + * appenders can be stacked + */ + struct lxc_log_appender *next; +}; + +/* log category object */ +struct lxc_log_category { + const char *name; + int priority; + struct lxc_log_appender *appender; + const struct lxc_log_category *parent; +}; + +/* + * Returns true if the chained priority is equal to or higher than + * given priority. + */ +static inline int +lxc_log_priority_is_enabled(const struct lxc_log_category* category, + int priority) +{ + while (category->priority == LXC_LOG_PRIORITY_NOTSET && + category->parent) + category = category->parent; + + return priority >= category->priority; +} + +/* + * converts a priority to a literal string + */ +static inline const char* lxc_log_priority_to_string(int priority) +{ + switch (priority) { + case LXC_LOG_PRIORITY_TRACE: return "TRACE"; + case LXC_LOG_PRIORITY_DEBUG: return "DEBUG"; + case LXC_LOG_PRIORITY_INFO: return "INFO"; + case LXC_LOG_PRIORITY_NOTICE: return "NOTICE"; + case LXC_LOG_PRIORITY_WARN: return "WARN"; + case LXC_LOG_PRIORITY_ERROR: return "ERROR"; + case LXC_LOG_PRIORITY_CRIT: return "CRIT"; + case LXC_LOG_PRIORITY_ALERT: return "ALERT"; + case LXC_LOG_PRIORITY_FATAL: return "FATAL"; + default: + return "NOTSET"; + } +} +/* + * converts a literal priority to an int + */ +static inline int lxc_log_priority_to_int(const char* name) +{ + if (!strcasecmp("TRACE", name)) return LXC_LOG_PRIORITY_TRACE; + if (!strcasecmp("DEBUG", name)) return LXC_LOG_PRIORITY_DEBUG; + if (!strcasecmp("INFO", name)) return LXC_LOG_PRIORITY_INFO; + if (!strcasecmp("NOTICE", name)) return LXC_LOG_PRIORITY_NOTICE; + if (!strcasecmp("WARN", name)) return LXC_LOG_PRIORITY_WARN; + if (!strcasecmp("ERROR", name)) return LXC_LOG_PRIORITY_ERROR; + if (!strcasecmp("CRIT", name)) return LXC_LOG_PRIORITY_CRIT; + if (!strcasecmp("ALERT", name)) return LXC_LOG_PRIORITY_ALERT; + if (!strcasecmp("FATAL", name)) return LXC_LOG_PRIORITY_FATAL; + + return LXC_LOG_PRIORITY_NOTSET; +} + +static inline void +__lxc_log_append(const struct lxc_log_appender *appender, + struct lxc_log_event* event) +{ + va_list va, *va_keep; + va_keep = event->vap; + + while (appender) { + va_copy(va, *va_keep); + event->vap = &va; + appender->append(appender, event); + appender = appender->next; + va_end(va); + } +} + +static inline void +__lxc_log(const struct lxc_log_category* category, + struct lxc_log_event* event) +{ + while (category) { + __lxc_log_append(category->appender, event); + category = category->parent; + } +} + +/* + * Helper macro to define log fonctions. + */ +#define lxc_log_priority_define(acategory, PRIORITY) \ + \ +static inline void LXC_##PRIORITY(struct lxc_log_locinfo *, \ + const char *, ...) __attribute__ ((format (printf, 2, 3))); \ + \ +static inline void LXC_##PRIORITY(struct lxc_log_locinfo* locinfo, \ + const char* format, ...) \ +{ \ + if (lxc_log_priority_is_enabled(acategory, \ + LXC_LOG_PRIORITY_##PRIORITY)) { \ + struct lxc_log_event evt = { \ + .category = (acategory)->name, \ + .priority = LXC_LOG_PRIORITY_##PRIORITY, \ + .fmt = format, \ + .locinfo = locinfo \ + }; \ + va_list va_ref; \ + \ + gettimeofday(&evt.timestamp, NULL); \ + \ + va_start(va_ref, format); \ + evt.vap = &va_ref; \ + __lxc_log(acategory, &evt); \ + va_end(va_ref); \ + } \ +} + +/* + * Helper macro to define and use static categories. + */ +#define lxc_log_category_define(name, parent) \ + extern struct lxc_log_category lxc_log_category_##parent; \ + struct lxc_log_category lxc_log_category_##name = { \ + #name, \ + LXC_LOG_PRIORITY_NOTSET, \ + NULL, \ + &lxc_log_category_##parent \ + }; + +#define lxc_log_define(name, parent) \ + lxc_log_category_define(name, parent) \ + \ + lxc_log_priority_define(&lxc_log_category_##name, TRACE) \ + lxc_log_priority_define(&lxc_log_category_##name, DEBUG) \ + lxc_log_priority_define(&lxc_log_category_##name, INFO) \ + lxc_log_priority_define(&lxc_log_category_##name, NOTICE) \ + lxc_log_priority_define(&lxc_log_category_##name, WARN) \ + lxc_log_priority_define(&lxc_log_category_##name, ERROR) \ + lxc_log_priority_define(&lxc_log_category_##name, CRIT) \ + lxc_log_priority_define(&lxc_log_category_##name, ALERT) \ + lxc_log_priority_define(&lxc_log_category_##name, FATAL) + +#define lxc_log_category_priority(name) \ + (lxc_log_priority_to_string(lxc_log_category_##name.priority)) + +/* + * top categories + */ +extern struct lxc_log_category lxc_log_category_lxc; + +#define TRACE(format, ...) do { \ + struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ + LXC_TRACE(&locinfo, format, ##__VA_ARGS__); \ +} while (0) + +#define DEBUG(format, ...) do { \ + struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ + LXC_DEBUG(&locinfo, format, ##__VA_ARGS__); \ +} while (0) + +#define INFO(format, ...) do { \ + struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ + LXC_INFO(&locinfo, format, ##__VA_ARGS__); \ +} while (0) + +#define NOTICE(format, ...) do { \ + struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ + LXC_NOTICE(&locinfo, format, ##__VA_ARGS__); \ +} while (0) + +#define WARN(format, ...) do { \ + struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ + LXC_WARN(&locinfo, format, ##__VA_ARGS__); \ +} while (0) + +#define ERROR(format, ...) do { \ + struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ + LXC_ERROR(&locinfo, format, ##__VA_ARGS__); \ +} while (0) + +#define CRIT(format, ...) do { \ + struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ + LXC_CRIT(&locinfo, format, ##__VA_ARGS__); \ +} while (0) + +#define ALERT(format, ...) do { \ + struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ + LXC_ALERT(&locinfo, format, ##__VA_ARGS__); \ +} while (0) + +#define FATAL(format, ...) do { \ + struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ + LXC_FATAL(&locinfo, format, ##__VA_ARGS__); \ +} while (0) + + + +#define SYSERROR(format, ...) do { \ + ERROR("%s - " format, strerror(errno), ##__VA_ARGS__); \ +} while (0) + +extern int lxc_log_fd; + +extern int lxc_log_init(const char *file, const char *priority, + const char *prefix, int quiet); + +extern void lxc_log_setprefix(const char *a_prefix); +#endif diff --git a/fork/lxc-app2.c b/fork/lxc-app2.c new file mode 100644 index 00000000..ea66afbb --- /dev/null +++ b/fork/lxc-app2.c @@ -0,0 +1,19 @@ +/* + * Simple application running in the container. + */ + +#include +#include +#include +#include + +int main() { + unsigned int slot = 0; + //say something to prove i am live + while (1) { + printf("I am process %d from process %d, Now it's %d.\n", + getpid(), getppid(), slot); + slot++; + sleep(10); + } +} diff --git a/fork/lxc-app3.c b/fork/lxc-app3.c new file mode 100644 index 00000000..14667fd7 --- /dev/null +++ b/fork/lxc-app3.c @@ -0,0 +1,37 @@ +/* + * lxc test app 3: + * open a file and write some information into it continuously + */ + +#include +#include +#include +#include + +int main() +{ + unsigned int time = 0; + int len = 0; + FILE *f = fopen("./pid.me", "w+"); + + if (!f) { + printf("open pid.me file failed, exit.\n"); + return -1; + } + + while (1) { + len = fprintf(f, "I'm process %d from process %d, i'm %d seconds old\n", + getpid(), getppid(), time * 10); + if (!len) { + printf("Something wrong, write to file 0 bytes.\n"); + return -2; + } else { + printf("I'm process %d from process %d, i'm %d seconds old\n", + getpid(), getppid(), time * 10); + //fclose(f); + fflush(f); + } + time++; + sleep(10); + } +} diff --git a/fork/lxc-app4 b/fork/lxc-app4 new file mode 100755 index 0000000000000000000000000000000000000000..240d525407bddb0b109ab2a16b465cf9805693ac GIT binary patch literal 13256 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 +#include +#include +#include +#include +#include +#include +#include + +#define SLEEPTIME 20 + +/* + * root + * / \ + * child1 child2 + * / \ \ + * grandson1 grandson2 grandson3 + * | + * grand - grand son + */ + +void multiprocesses() { + int i; + pid_t child; + char space[16] = { '\0' }; + unsigned int slot = 0; + + if ((child = fork()) == 0) { //child + space[0] = '-'; + goto loop; + } + + if ((child = fork()) == 0) { //second child + space[0] = '-'; + for (i = 0; i < 3; i++) { + if ((child = fork()) == 0) { + space[1] = '-'; + if (i == 1) + if (fork() == 0) + space[2] = '-'; + goto loop; + } + } + } + + loop: + while (1) { + printf("%sI am process %d from process %d, Now it's %d.\n", + space, getpid(), getppid(), slot); + slot++; + sleep(SLEEPTIME); + } +} + +/* + * lxc fork mmap test function + */ +int lxc_mmap() +{ + int fd = -1; + void *map = NULL; + char *ptr; + size_t length = 8192 * 5; + off_t off = 0; + size_t wsize; + unsigned long slot = 0; + mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; + //S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | S_IWGRP | S_IWOTH; + + fd = open("./mmap.file", O_RDWR | O_CREAT, mode); + if (fd == -1) { + printf("open mmap file failed.\n"); + return -1; + } + + //Make the file big enough + lseek (fd, length + 1, SEEK_SET); + write (fd, "*\n", 2); + lseek (fd, 0, SEEK_SET); + + map = mmap(NULL, length, PROT_WRITE | PROT_READ, MAP_SHARED, fd, off); + + if (!map) { + close(fd); + printf("map file failed.\n"); + return -2; + } + ptr = (char *)map; + while (1) { + wsize = sprintf(ptr, "I am process %d from process %d, Now it's %ld\n", + getpid(), getppid(), slot); + printf("---I am process %d from process %d, Now it's %ld\n", + getpid(), getppid(), slot); + slot++; + sleep(SLEEPTIME); + ptr += wsize; + } + sync(); + munmap(map, length); + return 0; +} + +int lxc_mpmap() +{ + int i; + pid_t child; + char space[16] = { '\0' }; + unsigned int slot = 0; + + if ((child = fork()) == 0) { //child + space[0] = '-'; + goto loop; + } + + if ((child = fork()) == 0) { //second child + space[0] = '-'; + for (i = 0; i < 3; i++) { + if ((child = fork()) == 0) { + space[1] = '-'; + if (i == 1) + if (fork() == 0) { + //space[2] = '-'; + lxc_mmap(); + return 0; + } + goto loop; + } + } + } + + loop: + while (1) { + printf("%sI am process %d from process %d, Now it's %d.\n", + space, getpid(), getppid(), slot); + slot++; + sleep(SLEEPTIME); + } +} + +int main(int argc, char *argv[]) { + int type = 0; + + if (argc > 1) { + type = atol(argv[1]); + } + + switch (type) { + case 0: //print + break; + case 1: //write file + break; + case 2: //multiple process + multiprocesses(); + break; + case 3: //mmap + lxc_mmap(); + break; + case 4: //mp + mmap + lxc_mpmap(); + break; + default: + break; + } + return 0; +} diff --git a/fork/lxc_fork b/fork/lxc_fork new file mode 100755 index 0000000000000000000000000000000000000000..dd664e1ccfc77fc3fc9c24dfe0ee8d48e1e81f44 GIT binary patch literal 12895 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 +#include +#include + +#include "lxc_fork.h" +#include "log.h" + +int main(int argc, char *argv[]) +{ + int opt, ret; + char *orig, *new, *pidbuf; + char clonecmd[256] = { 0 }; + char startcmd[256] = { 0 }; + char cpcmd[256] = { 0 }; + char freezecmd[256] = { 0 }; + char *rcfile = NULL; + struct lxc_conf *conf = NULL; + + //parse the arguments + while ((opt = getopt(argc, argv, "o:n:p:")) != -1) { + switch (opt) { + case 'o': + //FIXME: we need to do string boundary check to avoid buffer overflow ! + orig = optarg; + break; + case 'n': + new = optarg; + break; + case 'p': + pidbuf = optarg; + break; + default: /* ? */ + printf("unrecognized argu: %s.\n", optarg); + break; + } + } + lf_debug("Parse argument, old container name: %s, new name: %s, pid: %s.\n", + orig, new, pidbuf); + + //freeze the original container first, + // maybe we need to flush in-memory dirty data to disk before lxc-clone + sprintf(freezecmd, "lxc-freeze -n %s", orig); + lf_debug("freeze original container: %s.\n", freezecmd); + ret = system(freezecmd); + + //copy lxc container config by lxc-clone + sprintf(clonecmd, "lxc-clone -o %s -n %s", orig, new); + lf_debug("clone command: %s.\n", clonecmd); + + ret = system(clonecmd); + if (ret == -1) { + printf("lxc clone error: %d, exit now.\n", ret); + return ret; + } + + //check if the new lxc files exist, config, fstab, file system + ret = asprintf(&rcfile, LXC_PATH "/%s/config", new); + if (ret == -1) { + lf_debug("failed to allocate memory"); + return ret; + } + + if (access(rcfile, F_OK)) { + free(rcfile); + rcfile = NULL; + lf_debug("failed to find the config file %s", rcfile); + return -1; + } + + sprintf(cpcmd, "cp ./_lxc_fork ./pid.txt /var/lib/lxc/%s/rootfs/root/", new); + //copy binary to root directory at new container + system(cpcmd); + + //initial new lxc contianer + sprintf(startcmd, "lxc-start -n %s /root/_lxc_fork %s %s", new, orig, pidbuf); + ret = system(startcmd); + + //unfreeze original contianer + sprintf(freezecmd, "lxc-unfreeze -n %s", orig); + ret = system(freezecmd); + return 0; +} diff --git a/fork/lxc_fork.h b/fork/lxc_fork.h new file mode 100644 index 00000000..4c4e2516 --- /dev/null +++ b/fork/lxc_fork.h @@ -0,0 +1,14 @@ +#ifndef __LXC_FORK_H__ +#define __LXC_FORK_H__ + +#define LF_DEBUG + +#ifdef LF_DEBUG +#define lf_debug(fmt, args...) printf("%s%s:%d "fmt, "[D]", __FILE__, __LINE__, ##args) +#else +#define lf_debug(fmt, args...) +#endif + +#define LXC_PATH "/var/lib/lxc" + +#endif /* __LXC_FORK_H__ */ diff --git a/fork/make.sh b/fork/make.sh new file mode 100755 index 00000000..ceb39e5e --- /dev/null +++ b/fork/make.sh @@ -0,0 +1,3 @@ +gcc -o lxc-app4 lxc-app4.c +gcc -o lxc_fork lxc_fork.c +gcc -o _lxc_fork _lxc_fork.c diff --git a/fork/mmap.file b/fork/mmap.file new file mode 100755 index 0000000000000000000000000000000000000000..c2e3fdf983d81821bd064fa387c4e03df8ffcad1 GIT binary patch literal 40963 zcmeI%F$%&k7=Y2vIYl<1IM`ZkdW0_CK}5kpDy`u4U2O*?b6>{r5&pc4>ErnkpW|@3 zPE)MAwu!fKnC;ZtcpBdE{@P4&7y7Ke%Ixb<%+60$x0okY?bkf}#rgmGCbK_e_Q%Y= z&FoWV--W^=K!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB=DY2$a5v*YVJ9Nq_(W z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly oK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pkKLyJ00dIJcnE(I) literal 0 HcmV?d00001 diff --git a/fork/pid.txt b/fork/pid.txt new file mode 100644 index 00000000..0ece43ab --- /dev/null +++ b/fork/pid.txt @@ -0,0 +1 @@ +2756 diff --git a/fs/file.c b/fs/file.c index 88db5a4c..43d1b759 100644 --- a/fs/file.c +++ b/fs/file.c @@ -357,6 +357,7 @@ struct file *lxc_find_new_file(struct file *old_file, struct task_struct *tsk, */ #include extern int aa_get_name(struct path *path, int flags, char **buffer, const char **name); +extern void show_sock_info(void *); struct files_struct *deep_dup_fd(struct files_struct *oldf, struct files_struct *parentf, int *errorp, struct task_struct *tsk, struct task_struct *otsk, @@ -554,9 +555,11 @@ struct files_struct *deep_dup_fd(struct files_struct *oldf, struct files_struct } break; } - case S_IFSOCK: //socket - printk("[%d] socket file.\n", open_files - i); + case S_IFSOCK: {//socket + printk("[%d]socket: ", open_files - i); + show_sock_info(of->private_data); break; + } default: //unknown type printk("[%d] unknown file i_mode: 0%o[0x%x].\n", open_files - i, i_mode, i_mode); diff --git a/net/socket.c b/net/socket.c index 1ad42d36..9310750f 100644 --- a/net/socket.c +++ b/net/socket.c @@ -3382,3 +3382,21 @@ int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how) return sock->ops->shutdown(sock, how); } EXPORT_SYMBOL(kernel_sock_shutdown); + +/* + * cj-hack @ April-29-2012 + * print socket related information, family, type, protocol, address.... + */ +#include +void show_sock_info(void *sockp) +{ + struct socket *sock = (struct socket *)sockp; + struct sock *sk = sock->sk; + printk("family:%d, type:%d, protocol:%d.\n", + sk->sk_family, sk->sk_type, sk->sk_protocol); + if (sk->sk_family == AF_INET) { + struct inet_sock *inet = (struct inet_sock *)sk; + printk("\t\tport=%x\n", inet->inet_sport); + } +} +EXPORT_SYMBOL(show_sock_info);