* Jimi Xenidis <[EMAIL PROTECTED]> [2007-01-15 14:53]:
> 
> On Jan 15, 2007, at 1:51 PM, Ryan Harper wrote:
> 
> >* Jimi Xenidis <[EMAIL PROTECTED]> [2007-01-11 16:53]:
> >>
> >>Ok there are a few things here.
> >
> BTW: some of these issues existed in the original python, but they
> are yours now :)

Of course =)

> 
> >Respun with fixes:
> >
> >- preserve and return errno where approriate
> >- using open/close and read/write instead of f*
> >- dropped vcpu argument, only fill out one cpu in devtree
> >- dropped regexp requirment, use a null-terminated list of filters
> >- made sure to call closedir()
> >- fixed double-free of bph on error path
> >- fixed static function names
> >- renamed find_first_cpu to find_cpu, we don't care which cpu we find
> 
> I believe you _must_ use the the entry that has a reg property of 0.

Is that because the properties we are interested aren't guaranteed to be
present in all cpu nodes?

> >+static int readfile(const char *fullpath, void *data, int len)
> >+{
> >+    struct stat st;
> >+    int saved_errno;
> >+    int rc = -1;
> >+    int fd;
> >+
> >+    if ((fd = open(fullpath, O_RDONLY)) == -1) {
> >+        PERROR("%s: failed to open file %s", __func__, fullpath);
> >+        return -1;
> >+    }
> >+
> >+    if ((rc = fstat(fd, &st)) == -1) {
> >+        PERROR("%s: failed to stat fd %d", __func__, fd);
> >+        goto error;
> >+    }
> >+
> >+    if (S_ISREG(st.st_mode))
> >+        rc = read(fd, data, MIN(len, st.st_size));
> My brain fart, the MIN() is not necessary. you want to read no-more
> than your buffer allows, so just use len and forget about
> st.st_size.  This assumes that you are not interested in the case
> where len yields a partial read, are you?

OK.  I thought about putting a warning that the payload is larger than
the length of the buffer and truncating.

> >+ *
> >+ * compare @property string to each string in @filter
> >+ *
> >+ * return 1 if @property matches any filter, otherwise 0
> >+ *
> >+ */
> >+static int match(const char *property, const char **filter)
> >+{
> >+    int i;
> >+
> >+    if ((property == NULL) || (filter == NULL) || (*filter == NULL))
> >+        return -1;
> This will get interpreted as a "match" bye its users, I would not
> even bother checking.

It shouldn't since match == 1.  But I see what you mean as I used 

if ( !match())

> SEGVs are good! :)

WFM. =)

> >+
> >+    for (i=0; filter[i] != NULL; i++) {
> >+        /* compare the filter to property, ignoring NULL
> >terminator */
> >+        if (strncmp(property, filter[i], sizeof(filter[i])-1) == 0)
> 
> This function has no clue what the contents of "filter" is so you
> cannot use sizeof().
> Assuming sizeof() worked, it is your intention to match the substring?

Ack! I was thinking strlen() since we are comparing the property to the
full-lenght of the filter string.  The -1 is probably my screw up for
using sizeof() instead of strlen().

> >+static int copynode(struct ft_cxt *cxt, const char *dirpath, const
> >char **propfilter)
> >+{
> 
> This is totally informational, but I think the blob/fnmatch routines
> may make this code way simpler.

sure and I liked my regexp, but the concern was what sort of libc
functions would be available in Xen when we implement copynode down
there for dom0 devtree construction.

> 
> >+    struct dirent *tree;
> >+    struct stat st;
> >+    DIR *dir;
> >+    char fullpath[MAX_PATH];
> >+    char *bname = NULL;
> >+    char *basec = NULL;
> >+    int saved_errno;
> >+
> >+    if ((dir = opendir(dirpath)) == NULL) {
> >+        PERROR("%s: failed to open dir %s", __func__, dirpath);
> >+        return -1;
> >+    }
> >+
> >+    while (1) {
> >+        if ((tree = readdir(dir)) == NULL)
> >+            break;  /* reached end of directory entries */
> >+
> >+        /* ignore . and .. */
> >+        if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree-
> >>d_name,"..") == 0)
> >+            continue;
> >+
> >+        /* build full path name of the file, for stat() */
> >+        if (snprintf(fullpath, sizeof(fullpath), "%s/%s", dirpath,
> >tree->d_name) <= 0) {
> snprintf will almost never return -1, what you are really interested
> in is if the result does not fit in the buffer, so the test would be:
>   >= sizeof(fullpath).
> To "be complete" you should also check against "!=-1" which means
> that the strlen() of the result would be to bit for an int (hard to
> do that, but possible) :)

OK

> >+int make_devtree(
> >+    struct ft_cxt *root,
> >+    uint32_t domid, uint32_t mem_mb,
> >+    unsigned long shadow_mb,
> >+    const char *bootargs)
> >+{
> >+    struct boot_param_header *bph = NULL;
> >+    uint64_t val[2];
> >+    uint32_t val32[2];
> >+    uint64_t totalmem;
> >+    uint64_t rma_bytes;
> >+    uint64_t remaining;
> >+    uint64_t pft_size;
> >+    int64_t shadow_mb_log;
> >+    char cpupath[MAX_PATH];
> >+    const char *propfilter[] = { "ibm", "linux,", NULL };
> >+    char *cpupath_copy = NULL;
> >+    char *cpuname = NULL;
> >+    int saved_errno;
> >+    int dtb_fd = -1;
> >+    int rma_log;
> >+
> >+    /* initialize bph to prevent double free on error path */
> >+    root->bph = NULL;
> >+
> >+    /* carve out space for bph */
> >+    if ((bph = (struct boot_param_header *)malloc(BPH_SIZE)) ==
> >NULL) {
> >+        PERROR("%s: Failed to malloc bph buffer size", __func__);
> >+        goto error;
> >+    }
> >+
> >+    /* NB: struct ft_cxt root defined at top of file */
> >+    /* root = Tree() */
> >+    ft_begin(root, bph, BPH_SIZE);
> >+
> >+    /* you MUST set reservations BEFORE _starting_the_tree_ */
> >+
> Any ideas what this reservation is for? is it for the flat-devtree
> itself?

Nope.

> >+    /* root.reserve(0x1000000, 0x1000) */
> >+    val[0] = cpu_to_be64((u64) 0x1000000);
> >+    val[1] = cpu_to_be64((u64) 0x1000);
> >+    ft_add_rsvmap(root, val[0], val[1]);
> >+
> 
> this value is keyed off of rma_bytes

No idea, just duping reservations that the python code made.  Is there
some place I should be getting these values from?

> >+    /* chosen.addprop('cpu', cpu0.get_phandle()) */
> >+    ft_prop_int(root, "cpu", PHANDLE_CPU0);
> 
> Instead of defining a static set of phandles, can you have a function
> that hands out a counted value, sorta like:
>   cpu0_phandle = new_handle();
> 
> that way we don;t have to associate a numerical value to each,
> especially new ones.

OK.

> >+    /* xen = root.addnode('xen') */
> >+    ft_begin_node(root, "xen");
> 
> the 0x3ffc00 value is offset from rma_bytes
> >+
> >+    /* xen.addprop('start-info', long(0x3ffc000), long(0x1000)) */
> >+    val[0] = cpu_to_be64((u64) 0x3ffc000);
> >+    val[1] = cpu_to_be64((u64) 0x1000);
> >+    ft_prop(root, "start-info", val, sizeof(val));

What am I missing here?
   
> >+
> >+    /* [EMAIL PROTECTED] is all the rest */
> >+    if (remaining > 0)
> >+    {
> 
> this really should be "memory@<rma_bytes>"
> 
> >+        /* mem = root.addnode('[EMAIL PROTECTED]') */
> >+        ft_begin_node(root, "[EMAIL PROTECTED]");
> >+

OK.

-- 
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
(512) 838-9253   T/L: 678-9253
[EMAIL PROTECTED]

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel

Reply via email to